When developing Malloy models, it is fairly common to have a table which has more fields than you need, or fields which are useful for intermediary computation but should not be part of the external interface of the modeled source. To enable better curation of sources, we've added a new experiment for specifying access modifiers on fields, as well as modifiying access when extending a source.
Enable the access modifiers experiment with:
##! experimental.access_modifiers
Access Levels
This experiment adds three access levels to Malloy:
public
- A field which may be used in queries against the sourceinternal
- A field which may not be used in queries, but can be used in definitions in extensions of the sourceprivate
- A field which may not be used in queries or definitions in extensions of the source
Specifying Access Level
Any definition inside a source may be prefixed with an access modifier label (public
, internal
, or private
):
source: flights is duckdb.table('../data/flights.parquet') extend { private dimension: only_in_flights is ... // Can reference private dimensions in the original source public dimension: exposed is only_in_flights } source: flights_ext is flights extend { // Error: `only_in_flights` is private, so it cannot be used in an extension public dimension: exposed_2 is only_in_flights } // Error: `only_in_flights` is private, so it cannot be used in a query run: flights -> { group_by: only_in_flights }
Changing Access When Extending Sources
When extending a source, you can change the access of fields by using the include
operator before the extend
, with the following rules:
public
fields may be narrowed tointernal
orprivate
internal
fields may be narrowed toprivate
or expanded topublic
private
fields may not be expanded to eitherinternal
orpublic
The include
operator allows you to specify a series of fields, optionally with new labels. The wildcard *
may be used to reference all fields not specified in another rule.
Any field not listed in the include (unless *
is used) will not be included in the resulting source. Fields can be explicitly called out to be excluded by using except: field_1, field_2, ...
.
Note that in an extend
immediately following an include
, fields made private in the include block are available for use in that extend block (but not subsequent ones).
source: flights is duckdb.table('../data/flights.parquet') include { private: * public: distance, origin, destination } extend { // This is allowed dimension: carrier_copy is carrier }
Examples
Include Rules | Meaning |
---|---|
include { *; private: a } |
Include all fields, making a private |
include { a, b, c } |
Only include a , b , and c |
include { except: a, b } |
Include all fields except a and b |
include { private: *; public: a, b } |
Include all fields, making them private, except a and b (which remain public) |
Changing Access Without Extending
You can also limit access to a source (thus defining a new source) without extend
ing:
source: flights is duckdb.table('../data/flights.parquet') include { * private: distance }
Interaction with Composite Sources
private
fields are not included in composite sources. If all input sources have a field which isprivate
, that field will not be part of the composite source's interface. If the field is only private in some input sources, then use of that field in the composite source will disqualify those input sources from being chosen during composite source resolution.If any instance of a field in any input source is
internal
, that field will beinternal
in the composite source.