Statement tools

These tools wrap or replace a query: you prefix EXPLAIN / FORMAT, or you run DESCRIBE / SHOW … as the statement. Tools you write inside RETURN are on Tools in the query .

EXPLAIN

Prefix any query with EXPLAIN to see a JSON plan — stage, output schema, features, layers — without executing it:

FeatureQL
EXPLAIN (FIELDS (STAGE, OUTPUT_SCHEMA, FEATURES)) RETURN feature1 := 1, feature2 := feature1 + 1;
Result
JMESPATH VARCHAREXPECTED_VALUE VARCHAR
stage"base"
output_schema[*].{name: name, type: type}[{"name": "FEATURE1", "type": "BIGINT"}, {"name": "FEATURE2", "type": "BIGINT"}]
features[?name == 'FEATURE1'].function["VALUE"]
features[?name == 'FEATURE2'].function["ADD"]

Use EXPLAIN (FIELDS (…)) to keep only the keys you need. The result stays one OUTPUT VARCHAR cell containing JSON.

More on EXPLAIN — field lists, reading the plan, and request-prefix forms over a temporary overlay. Syntax: EXPLAIN .

FORMAT

FORMAT rewrites a query into canonical layout and syntax without executing it. Options include ESCAPED (newline markers for tests), FIX (migrate STRUCT/LIST and other legacy forms), and WIDTH:

FeatureQL
FORMAT (ESCAPED) RETURN F1 := 1 + 2 * 3;
Result
OUTPUT VARCHAR
RETURN\n f1 := 1 + 2 * 3\n;

More on FORMAT — FIX caveats, comment attachment, and worked examples. Syntax: FORMAT .

DESCRIBE

The DESCRIBE statement shows compiler metadata about a named feature as a JSON cell:

FeatureQL
CREATE TEMPORARY FEATURES AS PERSIST feature1 := 1, feature2 := feature1 + 1;
DESCRIBE (FIELDS (NAME, FUNCTION)) FEATURE2;
Result
JMESPATH VARCHAREXPECTED_VALUE VARCHAR
[0].name"FEATURE2"
[0].function"ADD"
length(@)`1`

Use DESCRIBE (FIELDS (NAME, FUNCTION, …)) to project each feature object before serialization. It works with both temporary and persisted features.

For columns you can project with [field] access, use DESCRIBE() inside RETURN — Tools in the query . Syntax: DESCRIBE .

SHOW CREATE

SHOW CREATE FEATURES returns the FeatureQL code needed to recreate one or more features. Useful for inspecting stored definitions and for exporting them.

For temporary features:

FeatureQL
START TRANSACTION;
CREATE TEMPORARY FEATURES AS PERSIST feature1 := 1, feature2 := feature1 + 1;
SHOW CREATE FEATURES FEATURE1, FEATURE2;
COMMIT;
Result
OUTPUT VARCHAR
CREATE FEATURES AS PERSIST FEATURE1 := 1, FEATURE2 := FEATURE1 + 1 ;

FeatureQL reorders features by dependency layer and writes the canonical spelling. A literal stays := 1. Semantics stay the same.

For persisted features, the output includes full namespace paths:

FeatureQL
CREATE OR REPLACE FEATURES AS
PERSIST
    fm.tutorials.querytools.feature1 := 1,
    fm.tutorials.querytools.feature2 := fm.tutorials.querytools.feature1 + 1
;
Result
feature_name VARCHARstatus VARCHARmessage VARCHAR
FM.TUTORIALS.QUERYTOOLS.FEATURE1CREATEDFeature created as not exists
FM.TUTORIALS.QUERYTOOLS.FEATURE2CREATEDFeature created as not exists

FeatureQL
SHOW CREATE FEATURES FM.TUTORIALS.QUERYTOOLS.FEATURE2;
Result
OUTPUT VARCHAR
CREATE FEATURES AS PERSIST FM.TUTORIALS.QUERYTOOLS.FEATURE1 := 1, FM.TUTORIALS.QUERYTOOLS.FEATURE2 := FM.TUTORIALS.QUERYTOOLS.FEATURE1 + 1 ;

Features are topologically ordered, so the output is self-contained — you can run it to recreate the features.

Without LANGUAGE, the text is FeatureQL. With (LANGUAGE DUCKDB) (or TRINO, DATAFUSION), you get the SQL that dialect would run to return those features. Serving uses DATAFUSION.

FeatureQL
SHOW CREATE FEATURES (LANGUAGE DUCKDB)
    FM.TUTORIALS.QUERYTOOLS.FEATURE1,
    FM.TUTORIALS.QUERYTOOLS.FEATURE2
;
Result
OUTPUT VARCHAR
AS "FM.TUTORIALS.QUERYTOOLS.FEATURE1"
AS "FM.TUTORIALS.QUERYTOOLS.FEATURE2"

The SQL wrappers around those aliases can change; compare on the feature names, not the full CTE text.

Syntax: SHOW CREATE .

CREATE TEMPORARY overlay

CREATE TEMPORARY builds a request overlay: later RETURN, SHOW, DESCRIBE, and EXPLAIN in the same request see those names, and the registry is unchanged. The SHOW CREATE examples above wrap temporary features that way.

A lone CREATE TEMPORARY plus RETURN can stay unwrapped. Several overlay mutations (DROP TEMPORARY, a second CREATE TEMPORARY) need START TRANSACTION / COMMIT, and the last inner statement must be the result you want.

EXPLAIN START TRANSACTION; …; COMMIT; and FORMAT START TRANSACTION; …; COMMIT; are request prefixes: they explain or format the trailing result against the overlay. They do not write the registry. Detail: EXPLAIN .

Do not mix persistent CREATE / ALTER / DROP with TEMPORARY in the same script (UE/TRANSACTION-INVALID-SHAPE). Publish with a persist-only transaction instead — Create features . The three script shapes are on Transactions .

SHOW DOCS

SHOW DOCS searches the built-in documentation without leaving the query environment:

FeatureQL
SHOW DOCS (
    EXCLUDE (CONTENT),
    INCLUDE (LENGTH(NAME) AS LNAME)
)
WHERE LNAME > 30 AND NAME LIKE 'docs/%'
ORDER BY NAME ASC
LIMIT 5
Result
NAME VARCHARURL VARCHARDISPLAY_ORDER ARRAY<BIGINT>TITLE VARCHARTAGS ARRAY<VARCHAR>RELATED_TAGS ARRAY<VARCHAR>LNAME BIGINT
docs/1-concepts/1-why_featuremesh.md/docs/concepts/why_featuremesh[1, 1]Why FeatureMesh?NULLNULL36
docs/1-concepts/3-in_the_enterprise.md/docs/concepts/in_the_enterprise[1, 3]FeatureMesh in the enterpriseNULLNULL38
docs/1-concepts/4-batch_analytics.md/docs/concepts/batch_analytics[1, 4]Batch analyticsNULLNULL36
docs/1-concepts/5-real_time_serving.md/docs/concepts/real_time_serving[1, 5]Real-time servingNULLNULL38
docs/1-concepts/6-business_use_cases.md/docs/concepts/business_use_cases[1, 6]Business use casesNULLNULL39

Filter by NAME prefix (docs/% for human docs, llms/% for help-tag pages). URL is the public link when the page is published. Search content with LIKE and sort results. Combined with SHOW FUNCTIONS and SHOW TESTS, these statements make FeatureQL largely self-documenting.

SHOW TESTS

SHOW TESTS lists executable documentation snippets. WHERE / LIKE / LIMIT select the snippets you asked for. Add WITH DEPENDENCIES to also return their transitive # depends: setup. Extra rows set IS_ONLY_DEPENDENCY to TRUE. LIMIT still counts seeds only.

FeatureQL
SHOW TESTS (
    COLUMNS (IS_ONLY_DEPENDENCY),
    INCLUDE (SPLIT_PART(SPLIT_PART(NAME, '#', 2), '.', 2) AS SNIPPET)
)
WHERE NAME LIKE '%.show_create_features_persisted'
ORDER BY SNIPPET
LIMIT 1
WITH DEPENDENCIES;
Result
IS_ONLY_DEPENDENCY BOOLEANSNIPPET VARCHAR
TRUEquerytools_setup
FALSEshow_create_features_persisted

This is a catalog query — it does not run the snippets. To execute the suite, see Conformance tests . The full statement is on SHOW .

SHOW FUNCTIONS

SHOW FUNCTIONS lists functions by name and category. Use LIKE patterns to narrow the results:

FeatureQL
SHOW FUNCTIONS (COLUMNS (NAME, CATEGORY)) LIKE 'ARR%' ORDER BY NAME LIMIT 10;
Result
NAME VARCHARCATEGORY ARRAY<VARCHAR>
ARRAYS_OVERLAP[Array, Set Operations]
ARRAY_AGG() GROUP BY ...[Group By, Collection]
ARRAY_AGG() OVER ...[Window Function, Collection]
ARRAY_AVG[Array, Aggregation And Statistics]
ARRAY_CONCAT[Array, Array Combination]
ARRAY_CONCAT_FN[Array, Array Combination]
ARRAY_COUNT[Array, Aggregation And Statistics]
ARRAY_DISTINCT[Array, Filtering And Transformation]
ARRAY_ENUMERATE[Array, Filtering And Transformation]
ARRAY_ENUMERATE_FLATTEN[Array, Filtering And Transformation]

Results include CATEGORY (as an array like ['Math', 'Arithmetic']), DISPLAY_ORDER for sorting, and optional columns like ALIASES, OPERATOR, PARAMETERS, and NOTES. Use INCLUDE (SIGNATURES, EXAMPLES) for nested ARRAY(ROW(...)) overloads and registry examples.

SHOW FUNCTIONS (INCLUDE (SIGNATURES)) returns an ARRAY(ROW(...)) of overloads. Flatten with hybrid SQL:

FeatureQL
SELECT
    f.NAME,
    (s).PARAMETER_NAMES AS PARAMETER_NAMES,
    (s).PARAMETER_TYPES AS PARAMETER_TYPES,
    (s).RETURN_TYPE AS RETURN_TYPE
FROM FEATUREQL(SHOW FUNCTIONS (INCLUDE (SIGNATURES)) WHERE NAME = 'ADD' LIMIT 1) f,
UNNEST(f.SIGNATURES) AS t(s);
Result
NAME VARCHARPARAMETER_NAMES ARRAY<VARCHAR>PARAMETER_TYPES ARRAY<VARCHAR>RETURN_TYPE VARCHAR
ADD[number1, number2][T, T]T
ADD[timestamp, interval][TIMESTAMP, INTERVAL]TIMESTAMP
ADD[date, interval][DATE, INTERVAL]TIMESTAMP
ADD[interval, timestamp][INTERVAL, TIMESTAMP]TIMESTAMP
ADD[interval, date][INTERVAL, DATE]TIMESTAMP

Each row is one overload. PARAMETER_NAMES and PARAMETER_TYPES are arrays, so ADD shows its numeric overloads and its date/interval overload side by side.

The same playgrounds appear on Operators and functions in the language tour. Syntax: SHOW .

Related