Friendly syntax
FeatureQL extends standard SQL with features that make queries more readable and maintainable:
Automatic Dependency Resolution
The query engine automatically resolves dependencies, so you can reference columns before they're defined.
Alternative Assignment Syntax
For better readability, you can reverse expr AS identifier using := or IS.
expr AS identifier can then be written:
- identifier
:=expr - identifier
ISexpr
Function Chaining
Function chaining allows you to write nested functions in a more readable, left-to-right format. Instead of writing nested functions like FUNC1(FUNC2(X)), you can express them as X.FUNC2().FUNC1().
When using function chaining:
- The expression before the dot (
.) becomes the first argument of the function - For functions with multiple arguments, provide the remaining arguments within the parentheses
- Use parentheses
()to control precedence, especially with type casting operations
Key insights from the chaining examples:
- Simple chaining:
(1+2).MULTIPLY(3)is equivalent toMULTIPLY((1+2), 3) - Multiple operations:
(1).ADD(2).MULTIPLY(3)chains left-to-right: first add 2 to 1, then multiply by 3 - Type casting precedence:
(1).ADD(2).MULTIPLY(3)::(DOUBLE).SQRT()::BIGINTshows how parentheses control casting scope - String operations:
.TRIM().LOWER()chains naturally for text processing
This chainable syntax enhances code readability by making the sequence of operations more intuitive and easier to follow.
Advanced chaining with namespaces
When working with namespaced features and functions, chaining syntax requires careful attention to disambiguation:
Important distinctions:
- Quoted names:
"FM.MYFEATURES.FEATURE1".ADD(1)treats the entire quoted string as a feature name - Namespaced features:
FM.MYFEATURES.FEATURE1.ADD(1)chains theADDfunction on the namespaced feature - Parentheses for clarity:
(FEATURE1).ADD(2)explicitly marks the feature boundary - Function quoting:
(FEATURE1)."ADD"(3)calls the ADD function explicitly
Use parentheses and quotes strategically to ensure FeatureQL interprets your chaining intentions correctly.
Flexible Formatting
Trailing commas are supported and whitespace and formatting are flexible.
This makes it easier to:
- Reorder columns without breaking syntax
- Write more maintainable queries
Functions aliases
SQL dialects have different names for the same operation. FeatureQL accepts function aliases to provide flexibility and accommodate users coming from different SQL dialects.
Common alias patterns include:
- Complex structure types: ARRAY/LIST, ROW/STRUCT
- Construction syntax:
ARRAY[...]andARRAY(...),ROW(...)andROW[...] - Type-specific naming:
SLICE(),LIST_SLICE(), andARRAY_SLICE() - Mathematical functions with full and abbreviated forms:
POWER()andPOW()
You can use any alias when writing your feature definition, but FeatureQL converts them to a single canonical function name when saved. This lets you use function names that match your backend's native syntax while ensuring consistency in stored feature definitions.
Intermediate features using WITH
When writing complex queries, you often need intermediate features that you don't want to expose in your final output.
You can use the WITH clause to keep these calculations private while only exposing the final results you want to show.
In this example, NUMBER2 is used in calculations but not exposed in the final output, while NUMBER1 and NUMBER3 are visible in the results.
Benefits of this approach:
- Maintains named intermediate features for clarity
- Helps separate logic from presentation
- Keeps your query output clean and focused
Note: Features corresponding to "internal" functions cannot be returned and therefore must then be defined in the WITH clause.
| Function type | Why it can't be returned | What to return instead |
|---|---|---|
INPUT() | Returns input placeholder | Return the BIND_XXX() binding values to the input |
ENTITY() | Returns entity | Return the BIND_XXX() binding values to the INPUT() that references the entity |
SOURCE_XXX() | Returns source | Return the EXTERNAL_XXX() using the source as parameters |
UDF() and MACRO() | Returns function | Return the UDF() or MACRO() applied to some parameters |