From 9a651ff04bb87586c64f4881e8f7d101ac8ea47b Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 18:10:37 -0400 Subject: [PATCH 01/15] pMBQL --- core-spec/v1/schemas/card.yaml | 6 +- core-spec/v1/schemas/common/query.yaml | 398 ++++++++++-------- core-spec/v1/schemas/common/ref.yaml | 65 +-- core-spec/v1/schemas/measure.yaml | 54 +-- core-spec/v1/schemas/segment.yaml | 49 ++- core-spec/v1/schemas/transform.yaml | 2 +- .../main/dashboards/click_behaviors.yaml | 2 +- .../main/dashboards/inline_parameters.yaml | 4 +- .../main/dashboards/series_and_mappings.yaml | 4 +- .../monthly_avg_order.yaml | 10 +- .../monthly_cumulative.yaml | 8 +- .../series_and_mappings/monthly_orders.yaml | 8 +- .../series_and_mappings/monthly_revenue.yaml | 10 +- .../series_and_mappings/native_orders.yaml | 7 +- .../total_revenue_scalar.yaml | 8 +- .../main/dashboards/tabbed_dashboard.yaml | 2 +- .../tabbed_dashboard/products_table.yaml | 5 +- .../category_breakdown.yaml | 32 +- .../product_dashboard.yaml | 2 +- .../marketing_analytics/product_overview.yaml | 16 +- .../top_products_by_revenue.yaml | 41 +- .../main/queries/arithmetic_expressions.yaml | 201 ++++----- .../main/queries/basic_aggregations.yaml | 37 +- .../main/queries/comparison_filters.yaml | 32 +- .../queries/conditional_aggregations.yaml | 105 ++--- .../main/queries/conditional_and_type.yaml | 180 ++++---- .../queries/cumulative_and_statistical.yaml | 116 ++--- .../main/queries/geographic_filter.yaml | 50 +-- .../v1/collections/main/queries/joins.yaml | 146 ++++--- .../main/queries/math_functions.yaml | 150 ++++--- .../queries/metric_measure_segment_refs.yaml | 32 +- .../main/queries/native_card_and_snippet.yaml | 45 +- .../main/queries/native_field_filter.yaml | 101 ++--- .../main/queries/native_variables.yaml | 77 ++-- .../main/queries/nested_query.yaml | 47 ++- .../main/queries/null_and_string_filters.yaml | 51 ++- .../main/queries/source_card_reference.yaml | 13 +- .../main/queries/string_functions.yaml | 232 +++++----- .../queries/temporal_and_logical_filters.yaml | 19 +- .../main/queries/temporal_expressions.yaml | 153 +++---- .../main/queries/temporal_extraction.yaml | 278 ++++++------ .../main/queries/total_revenue_metric.yaml | 30 +- .../main/queries/url_functions.yaml | 85 ++-- .../main/queries/window_offset.yaml | 15 +- .../bar_chart_stacked.yaml | 13 +- .../main/visualization_settings/funnel.yaml | 8 +- .../main/visualization_settings/gauge.yaml | 8 +- .../visualization_settings/line_chart.yaml | 10 +- .../main/visualization_settings/map_pins.yaml | 5 +- .../visualization_settings/pie_chart.yaml | 8 +- .../visualization_settings/pivot_table.yaml | 16 +- .../visualization_settings/smart_scalar.yaml | 10 +- .../table_formatted.yaml | 5 +- .../visualization_settings/waterfall.yaml | 10 +- .../transforms/daily_order_summary.yaml | 20 +- .../transforms/hourly_product_stats.yaml | 39 +- .../transforms/mbql_transform.yaml | 39 +- .../transforms/monthly_sales_summary.yaml | 24 +- .../transforms/native_transform.yaml | 24 +- .../transforms/product_summary.yaml | 39 +- .../measures/avg_revenue_per_order.yaml | 8 +- .../orders/measures/median_order_total.yaml | 8 +- .../tables/orders/measures/order_count.yaml | 6 +- .../tables/orders/measures/total_revenue.yaml | 8 +- .../tables/orders/segments/large_orders.yaml | 8 +- .../tables/people/segments/nyc_area.yaml | 10 +- .../measures/average_product_price.yaml | 8 +- .../products/measures/avg_product_price.yaml | 8 +- .../products/measures/avg_widget_price.yaml | 8 +- .../products/measures/product_count.yaml | 8 +- .../products/segments/premium_widgets.yaml | 10 +- .../products/segments/recent_midrange.yaml | 19 +- .../segments/searchable_products.yaml | 23 +- .../products/segments/widget_products.yaml | 8 +- 74 files changed, 1841 insertions(+), 1505 deletions(-) diff --git a/core-spec/v1/schemas/card.yaml b/core-spec/v1/schemas/card.yaml index 3688193..a96ec64 100644 --- a/core-spec/v1/schemas/card.yaml +++ b/core-spec/v1/schemas/card.yaml @@ -57,7 +57,7 @@ properties: - "null" description: Database FK (database name), should match database in dataset_query dataset_query: - description: Query definition (MBQL or native) + description: Query definition in pMBQL format $ref: "common/query.yaml" visualization_settings: type: object @@ -117,12 +117,12 @@ properties: if: { type: string } then: { $ref: "common/id.yaml#/$defs/entity_id" } table_id: - description: Table FK, should match source-table in query + description: Table FK, should match source-table in the first stage type: [array, "null"] if: { type: array } then: { $ref: "common/id.yaml#/$defs/table_id" } source_card_id: - description: Source card FK + description: Source card FK, should match source-card in the first stage type: [string, "null"] if: { type: string } then: { $ref: "common/id.yaml#/$defs/entity_id" } diff --git a/core-spec/v1/schemas/common/query.yaml b/core-spec/v1/schemas/common/query.yaml index 2611a47..d4c510c 100644 --- a/core-spec/v1/schemas/common/query.yaml +++ b/core-spec/v1/schemas/common/query.yaml @@ -1,67 +1,75 @@ $schema: https://json-schema.org/draft/2020-12/schema title: Query description: > - A query definition in Metabase. Wraps either an MBQL structured query - or a native SQL query. The inner MBQL query supports recursive nesting - via source-query and recursive expression clauses. + A query definition in serialized pMBQL format. Contains a flat list of + stages (no recursive source-query nesting). Each stage is either an MBQL + structured stage or a native SQL stage. type: object required: + - "lib/type" - database - - type + - stages properties: + "lib/type": + type: string + const: mbql/query database: $ref: "id.yaml#/$defs/database_id" - type: - type: string - description: Query language type - enum: - - query - - native -allOf: - - if: - properties: - type: { const: query } - then: - required: [query] - properties: - query: - description: MBQL structured query - $ref: "#/$defs/mbql_query" - native: false - - if: - properties: - type: { const: native } - then: - required: [native] - properties: - native: - description: Native SQL query - $ref: "#/$defs/native_query" - query: false + stages: + type: array + description: > + Flat list of query stages. The first stage must have a source + (source-table or source-card for MBQL, native for native). + Subsequent stages build on the previous stage's output. + minItems: 1 + items: + $ref: "#/$defs/stage" $defs: - mbql_query: + stage: + description: > + A query stage — either MBQL structured or native SQL. + Dispatches on lib/type. + type: object + required: + - "lib/type" + properties: + "lib/type": + type: string + enum: + - mbql.stage/mbql + - mbql.stage/native + allOf: + - if: + properties: + "lib/type": { const: mbql.stage/mbql } + then: + $ref: "#/$defs/mbql_stage" + - if: + properties: + "lib/type": { const: mbql.stage/native } + then: + $ref: "#/$defs/native_stage" + + mbql_stage: type: object description: > - An MBQL structured query. Supports recursive nesting via source-query - and recursive expression clauses for filter, aggregation, breakout, - expressions, and order-by. + An MBQL structured query stage. The first stage in a query must have + either source-table or source-card. Subsequent stages have neither. properties: + "lib/type": + const: mbql.stage/mbql source-table: description: > - Data source. Either a Table FK array [database, schema, table] - for physical tables, or a Card entity_id string for saved - questions/models. - if: { type: array } - then: { $ref: "id.yaml#/$defs/table_id" } - else: { $ref: "id.yaml#/$defs/entity_id" } - source-query: + Table FK array [database, schema, table] for physical tables. + Only valid in the first stage. Mutually exclusive with source-card. + $ref: "id.yaml#/$defs/table_id" + source-card: description: > - Nested MBQL query used as the data source instead of a table. - Fields from the inner query are referenced by column name (string) - rather than a Field FK. Can be nested to arbitrary depth. - $ref: "#/$defs/mbql_query" + Card entity_id for saved questions/models. + Only valid in the first stage. Mutually exclusive with source-table. + $ref: "id.yaml#/$defs/entity_id" joins: type: array description: Join clauses @@ -76,17 +84,13 @@ $defs: $ref: "#/$defs/expression" filter: description: > - Filter clause. Either a single comparison [op, field, value] or - a compound filter [and/or, ...clauses]. + Filter clause. Either a single comparison [op, {}, field, value] + or a compound filter [and, {}, ...clauses]. $ref: "#/$defs/expression" aggregation: type: array description: > - Aggregation clauses. Each clause is [function, ...args] where - function is count, sum, avg, min, max, distinct, cum-count, - cum-sum, stddev, var, median, percentile, count-where, sum-where, - share, or metric. A metric clause references a saved metric card: - [metric, entity_id]. A measure clause: [measure, entity_id]. + Aggregation clauses. Each clause is [function, {}, ...args]. items: $ref: "#/$defs/expression" breakout: @@ -97,8 +101,7 @@ $defs: order-by: type: array description: > - Order-by clauses. Each is [direction, expression] where direction - is "asc" or "desc". + Order-by clauses. Each is [direction, {}, expression]. items: $ref: "#/$defs/expression" limit: @@ -110,8 +113,8 @@ $defs: expression: description: > An MBQL expression clause (recursive). Either a literal value or - an array [operator, ...args]. Uses if/then dispatch on the first - element for fast, strict per-operator validation. + an array [operator, options, ...args] where options is always an + object (empty {} when no options apply, never null). oneOf: - type: string - type: number @@ -141,141 +144,147 @@ $defs: $ref: "ref.yaml#/$defs/segment_ref" # --- Value literal --- - if: { prefixItems: [{ const: value }] } - then: { minItems: 2 } + then: + prefixItems: + - const: value + - type: object + - {} + minItems: 3 + maxItems: 3 # --- Arithmetic --- - if: { prefixItems: [{ enum: ["+", "-", "*", "/"] }] } then: prefixItems: - enum: ["+", "-", "*", "/"] + - type: object - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } - minItems: 2 + minItems: 3 # --- Logical --- - if: { prefixItems: [{ enum: [and, or] }] } then: prefixItems: - enum: [and, or] + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } - minItems: 3 + minItems: 4 - if: { prefixItems: [{ const: not }] } then: - prefixItems: [{ const: not }, { $ref: "#/$defs/expression" }] - minItems: 2 - maxItems: 2 + prefixItems: + - const: not + - type: object + - $ref: "#/$defs/expression" + minItems: 3 + maxItems: 3 # --- Comparison --- - if: { prefixItems: [{ enum: ["=", "!=", "<", ">", "<=", ">="] }] } then: prefixItems: - enum: ["=", "!=", "<", ">", "<=", ">="] + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } - minItems: 3 + minItems: 4 - if: { prefixItems: [{ enum: [in, not-in] }] } then: prefixItems: - enum: [in, not-in] + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } - minItems: 3 + minItems: 4 - if: { prefixItems: [{ const: between }] } then: prefixItems: - const: between + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - minItems: 4 - maxItems: 4 + minItems: 5 + maxItems: 5 - if: { prefixItems: [{ const: inside }] } then: prefixItems: - const: inside + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - { type: number } - { type: number } - { type: number } - { type: number } - minItems: 7 - maxItems: 7 + minItems: 8 + maxItems: 8 # --- Null/empty --- - if: { prefixItems: [{ enum: [is-null, not-null, is-empty, not-empty] }] } then: prefixItems: - enum: [is-null, not-null, is-empty, not-empty] - - $ref: "#/$defs/expression" - minItems: 2 - maxItems: 2 - # --- String filters --- - # 3 items: [op, field, value] - # 4 items: [op, field, value, options] - # 5+ items (multi-value): [op, options, field, value, value, ...] — options required in position 2 - - if: { prefixItems: [{ enum: [contains, does-not-contain, starts-with, ends-with] }], maxItems: 3 } - then: - prefixItems: - - enum: [contains, does-not-contain, starts-with, ends-with] - - $ref: "#/$defs/expression" + - type: object - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 - - if: { prefixItems: [{ enum: [contains, does-not-contain, starts-with, ends-with] }], minItems: 4, maxItems: 4 } - then: - prefixItems: - - enum: [contains, does-not-contain, starts-with, ends-with] - - $ref: "#/$defs/expression" - - $ref: "#/$defs/expression" - - $ref: "#/$defs/case_sensitive_options" - minItems: 4 - maxItems: 4 - - if: { prefixItems: [{ enum: [contains, does-not-contain, starts-with, ends-with] }], minItems: 5 } + # --- String filters --- + # Options always in position 2 (second argument). + # 2 value args: [op, {options}, field, value] + # 3+ value args: [op, {options}, field, value, value, ...] + - if: { prefixItems: [{ enum: [contains, does-not-contain, starts-with, ends-with] }] } then: prefixItems: - enum: [contains, does-not-contain, starts-with, ends-with] - $ref: "#/$defs/case_sensitive_options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } - minItems: 5 + minItems: 4 # --- Temporal filters --- - if: { prefixItems: [{ const: time-interval }] } then: prefixItems: - const: time-interval + - type: object - $ref: "#/$defs/expression" - if: { type: integer } then: { type: integer } else: { enum: [current, last, next] } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" - minItems: 4 - maxItems: 4 + minItems: 5 + maxItems: 5 - if: { prefixItems: [{ const: relative-time-interval }] } then: prefixItems: - const: relative-time-interval + - type: object - $ref: "#/$defs/expression" - { type: integer } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" - { type: integer } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" - minItems: 6 - maxItems: 6 + minItems: 7 + maxItems: 7 # --- Nullary --- - if: { prefixItems: [{ enum: [now, today] }] } - then: { minItems: 1, maxItems: 1 } + then: + prefixItems: + - enum: [now, today] + - type: object + minItems: 2 + maxItems: 2 # --- Interval --- - if: { prefixItems: [{ const: interval }] } then: prefixItems: - const: interval + - type: object - { type: integer } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" - minItems: 3 - maxItems: 3 + minItems: 4 + maxItems: 4 # --- Unary functions --- - if: prefixItems: @@ -283,153 +292,192 @@ $defs: then: prefixItems: - enum: [abs, ceil, floor, round, sqrt, exp, log, length, trim, ltrim, rtrim, upper, lower, host, domain, subdomain, path, get-year, get-quarter, get-month, get-day, get-hour, get-minute, get-second, text, integer, float, day-name, month-name, quarter-name, date] + - type: object - $ref: "#/$defs/expression" - minItems: 2 - maxItems: 2 + minItems: 3 + maxItems: 3 - if: { prefixItems: [{ const: datetime }] } then: prefixItems: - const: datetime - - $ref: "#/$defs/expression" - type: object properties: mode: type: string enum: [iso, simple, unix-seconds, unix-milliseconds, unix-microseconds, unix-nanoseconds, iso-bytes, simple-bytes] - minItems: 2 + - $ref: "#/$defs/expression" + minItems: 3 maxItems: 3 # --- Week mode functions --- - if: { prefixItems: [{ enum: [get-day-of-week, get-week] }] } then: prefixItems: - enum: [get-day-of-week, get-week] + - type: object - $ref: "#/$defs/expression" - { type: string, enum: [iso, us, instance] } - minItems: 2 - maxItems: 3 + minItems: 3 + maxItems: 4 # --- Binary/ternary --- - if: { prefixItems: [{ const: power }] } then: - prefixItems: [{ const: power }, { $ref: "#/$defs/expression" }, { $ref: "#/$defs/expression" }] - minItems: 3 - maxItems: 3 + prefixItems: + - const: power + - type: object + - $ref: "#/$defs/expression" + - $ref: "#/$defs/expression" + minItems: 4 + maxItems: 4 - if: { prefixItems: [{ enum: [replace, split-part] }] } then: prefixItems: - enum: [replace, split-part] + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - minItems: 4 - maxItems: 4 + minItems: 5 + maxItems: 5 - if: { prefixItems: [{ const: substring }] } then: prefixItems: - const: substring + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - minItems: 3 - maxItems: 4 + minItems: 4 + maxItems: 5 - if: { prefixItems: [{ const: collate }] } then: - prefixItems: [{ const: collate }, { $ref: "#/$defs/expression" }, { type: string }] - minItems: 3 - maxItems: 3 + prefixItems: + - const: collate + - type: object + - $ref: "#/$defs/expression" + - { type: string } + minItems: 4 + maxItems: 4 - if: { prefixItems: [{ const: regex-match-first }] } then: - prefixItems: [{ const: regex-match-first }, { $ref: "#/$defs/expression" }, { type: string }] - minItems: 3 - maxItems: 3 + prefixItems: + - const: regex-match-first + - type: object + - $ref: "#/$defs/expression" + - { type: string } + minItems: 4 + maxItems: 4 # --- Variadic --- - if: { prefixItems: [{ const: concat }] } then: - prefixItems: [{ const: concat }, { $ref: "#/$defs/expression" }, { $ref: "#/$defs/expression" }] + prefixItems: + - const: concat + - type: object + - $ref: "#/$defs/expression" + - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } - minItems: 3 + minItems: 4 - if: { prefixItems: [{ const: coalesce }] } then: - prefixItems: [{ const: coalesce }, { $ref: "#/$defs/expression" }, { $ref: "#/$defs/expression" }] + prefixItems: + - const: coalesce + - type: object + - $ref: "#/$defs/expression" + - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } - minItems: 3 + minItems: 4 # --- Datetime --- - if: { prefixItems: [{ enum: [datetime-add, datetime-subtract] }] } then: prefixItems: - enum: [datetime-add, datetime-subtract] + - type: object - $ref: "#/$defs/expression" - { type: integer } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" - minItems: 4 - maxItems: 4 + minItems: 5 + maxItems: 5 - if: { prefixItems: [{ const: datetime-diff }] } then: prefixItems: - const: datetime-diff + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/datetime_diff_unit" - minItems: 4 - maxItems: 4 + minItems: 5 + maxItems: 5 - if: { prefixItems: [{ const: convert-timezone }] } then: prefixItems: - const: convert-timezone + - type: object - $ref: "#/$defs/expression" - { type: string } - { type: string } - minItems: 3 - maxItems: 4 + minItems: 4 + maxItems: 5 - if: { prefixItems: [{ const: temporal-extract }] } then: prefixItems: - const: temporal-extract + - type: object - $ref: "#/$defs/expression" - $ref: "temporal_bucketing.yaml#/$defs/datetime_extraction_unit" - { type: string, enum: [iso, us, instance] } - minItems: 3 - maxItems: 4 + minItems: 4 + maxItems: 5 # --- Aggregations --- - if: { prefixItems: [{ enum: [count, cum-count] }] } then: - prefixItems: [{ enum: [count, cum-count] }] + prefixItems: + - enum: [count, cum-count] + - type: object items: { $ref: "#/$defs/expression" } - minItems: 1 - maxItems: 2 + minItems: 2 + maxItems: 3 - if: { prefixItems: [{ enum: [sum, avg, min, max, distinct, stddev, var, median, cum-sum] }] } then: prefixItems: - enum: [sum, avg, min, max, distinct, stddev, var, median, cum-sum] + - type: object - $ref: "#/$defs/expression" - minItems: 2 - maxItems: 2 - - if: { prefixItems: [{ const: percentile }] } - then: - prefixItems: [{ const: percentile }, { $ref: "#/$defs/expression" }, { type: number }] minItems: 3 maxItems: 3 + - if: { prefixItems: [{ const: percentile }] } + then: + prefixItems: + - const: percentile + - type: object + - $ref: "#/$defs/expression" + - { type: number } + minItems: 4 + maxItems: 4 - if: { prefixItems: [{ enum: [count-where, share] }] } then: - prefixItems: [{ enum: [count-where, share] }, { $ref: "#/$defs/expression" }] - minItems: 2 - maxItems: 2 + prefixItems: + - enum: [count-where, share] + - type: object + - $ref: "#/$defs/expression" + minItems: 3 + maxItems: 3 - if: { prefixItems: [{ enum: [sum-where, distinct-where] }] } then: prefixItems: - enum: [sum-where, distinct-where] + - type: object - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - minItems: 3 - maxItems: 3 + minItems: 4 + maxItems: 4 - if: { prefixItems: [{ const: aggregation-options }] } then: prefixItems: - const: aggregation-options - - $ref: "#/$defs/expression" - type: object properties: display-name: { type: string } name: { type: string } + - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 # --- Case/if --- @@ -437,23 +485,23 @@ $defs: then: prefixItems: - enum: [case, if] + - type: object + properties: + default: { $ref: "#/$defs/expression" } - type: array items: type: array prefixItems: [{ $ref: "#/$defs/expression" }, { $ref: "#/$defs/expression" }] minItems: 2 maxItems: 2 - - type: object - properties: - default: { $ref: "#/$defs/expression" } - minItems: 2 + minItems: 3 maxItems: 3 # --- Offset --- - if: { prefixItems: [{ const: offset }] } then: prefixItems: - const: offset - - type: "null" + - type: object - $ref: "#/$defs/expression" - type: integer minItems: 4 @@ -461,9 +509,12 @@ $defs: # --- Order-by direction --- - if: { prefixItems: [{ enum: [asc, desc] }] } then: - prefixItems: [{ enum: [asc, desc] }, { $ref: "#/$defs/expression" }] - minItems: 2 - maxItems: 2 + prefixItems: + - enum: [asc, desc] + - type: object + - $ref: "#/$defs/expression" + minItems: 3 + maxItems: 3 case_sensitive_options: type: object @@ -477,16 +528,28 @@ $defs: join: type: object - description: A join clause combining data from another table or query. + description: > + A join clause. In pMBQL, joins have their own stages array + instead of source-table/source-query. + required: + - stages + - conditions + - alias properties: - source-table: - description: Table FK or Card entity_id of the joined data source - if: { type: array } - then: { $ref: "id.yaml#/$defs/table_id" } - else: { $ref: "id.yaml#/$defs/entity_id" } - condition: - description: Join condition as MBQL expression clause - $ref: "#/$defs/expression" + stages: + type: array + description: > + Query stages for the joined data source. The first stage + must have source-table or source-card. + minItems: 1 + items: + $ref: "#/$defs/stage" + conditions: + type: array + description: Join conditions as MBQL expression clauses + minItems: 1 + items: + $ref: "#/$defs/expression" alias: type: string description: Join alias for referencing joined columns @@ -509,13 +572,16 @@ $defs: items: $ref: "#/$defs/expression" - native_query: + native_stage: type: object - description: A native SQL query with optional template tags for parameterization. + description: A native SQL query stage. required: - - query + - "lib/type" + - native properties: - query: + "lib/type": + const: mbql.stage/native + native: type: string description: SQL query string, may contain {{tag}} placeholders template-tags: diff --git a/core-spec/v1/schemas/common/ref.yaml b/core-spec/v1/schemas/common/ref.yaml index 5682926..bd04bd1 100644 --- a/core-spec/v1/schemas/common/ref.yaml +++ b/core-spec/v1/schemas/common/ref.yaml @@ -2,7 +2,8 @@ $schema: https://json-schema.org/draft/2020-12/schema title: Ref description: > Column and entity reference types used in MBQL expressions, - parameter mappings, and visualization settings. + parameter mappings, and visualization settings. In pMBQL format, + options are always the second element (an object, never null). $defs: base_type_options: @@ -67,87 +68,87 @@ $defs: field_ref: description: > - Field reference: [field, Field-FK-or-name, options-or-null]. + Field reference: [field, options, Field-FK-or-name]. + Options is always an object (empty {} when no options). Field FK is [database, schema, table, field, ...] (4+ elements for JSON paths). - For nested queries, the second element is a column name string. + For subsequent stages, the third element is a column name string. type: array prefixItems: - const: field - - description: Field FK (array) or column name (string, for nested queries) + - type: object + $ref: "#/$defs/field_options" + - description: Field FK (array) or column name (string, for subsequent stages) if: { type: array } then: { $ref: "id.yaml#/$defs/field_id" } - - type: [object, "null"] - if: { type: object } - then: { $ref: "#/$defs/field_options" } minItems: 3 maxItems: 3 expression_ref: description: > - Expression reference: [expression, name] or [expression, name, options]. + Expression reference: [expression, options, name]. + Options is always an object (empty {} when no options). type: array prefixItems: - const: expression + - type: object + $ref: "#/$defs/base_type_options" - type: string description: Expression name - - type: [object, "null"] - if: { type: object } - then: { $ref: "#/$defs/base_type_options" } - minItems: 2 + minItems: 3 maxItems: 3 aggregation_ref: description: > - Aggregation reference: [aggregation, index] or [aggregation, index, options]. + Aggregation reference: [aggregation, options, index]. + Options is always an object (empty {} when no options). type: array prefixItems: - const: aggregation + - type: object + $ref: "#/$defs/base_type_options" - type: integer description: Aggregation index (0-based) - - type: [object, "null"] - if: { type: object } - then: { $ref: "#/$defs/base_type_options" } - minItems: 2 + minItems: 3 maxItems: 3 metric_ref: description: > - Metric reference: [metric, entity_id] or [metric, entity_id, options-or-null]. + Metric reference: [metric, options, entity_id]. + Options is always an object (empty {} when no options). type: array prefixItems: - const: metric + - type: object + $ref: "#/$defs/base_type_options" - type: string description: Metric card entity_id - - type: [object, "null"] - if: { type: object } - then: { $ref: "#/$defs/base_type_options" } - minItems: 2 + minItems: 3 maxItems: 3 measure_ref: description: > - Measure reference: [measure, entity_id] or [measure, entity_id, options-or-null]. + Measure reference: [measure, options, entity_id]. + Options is always an object (empty {} when no options). type: array prefixItems: - const: measure + - type: object + $ref: "#/$defs/base_type_options" - type: string description: Measure entity_id - - type: [object, "null"] - if: { type: object } - then: { $ref: "#/$defs/base_type_options" } - minItems: 2 + minItems: 3 maxItems: 3 segment_ref: description: > - Segment reference: [segment, entity_id] or [segment, entity_id, options-or-null]. + Segment reference: [segment, options, entity_id]. + Options is always an object (empty {} when no options). type: array prefixItems: - const: segment + - type: object + $ref: "#/$defs/base_type_options" - type: string description: Segment entity_id - - type: [object, "null"] - if: { type: object } - then: { $ref: "#/$defs/base_type_options" } - minItems: 2 + minItems: 3 maxItems: 3 diff --git a/core-spec/v1/schemas/measure.yaml b/core-spec/v1/schemas/measure.yaml index 4818b81..960b9b3 100644 --- a/core-spec/v1/schemas/measure.yaml +++ b/core-spec/v1/schemas/measure.yaml @@ -25,36 +25,42 @@ properties: $ref: "common/id.yaml#/$defs/table_id" definition: description: > - Aggregation definition. Must use type: query with a physical table - source and exactly one aggregation clause. Measures cannot use filter, - breakout, joins, expressions, or other query clauses. + Aggregation definition in pMBQL format. Must have a single MBQL stage + with a physical table source and exactly one aggregation clause. + Measures cannot use filter, breakout, joins, expressions, or other + query clauses. allOf: - $ref: "common/query.yaml" - type: object required: + - "lib/type" - database - - type - - query + - stages properties: - type: - const: query - query: - type: object - required: - - source-table - - aggregation - additionalProperties: false - properties: - source-table: - description: > - Table FK [database, schema, table]. Measures must reference - a physical table, not a saved card/model. - $ref: "common/id.yaml#/$defs/table_id" - aggregation: - type: array - description: Exactly one aggregation clause - minItems: 1 - maxItems: 1 + stages: + type: array + minItems: 1 + maxItems: 1 + items: + type: object + required: + - "lib/type" + - source-table + - aggregation + additionalProperties: false + properties: + "lib/type": + const: mbql.stage/mbql + source-table: + description: > + Table FK [database, schema, table]. Measures must reference + a physical table, not a saved card/model. + $ref: "common/id.yaml#/$defs/table_id" + aggregation: + type: array + description: Exactly one aggregation clause + minItems: 1 + maxItems: 1 description: type: - string diff --git a/core-spec/v1/schemas/segment.yaml b/core-spec/v1/schemas/segment.yaml index 89abdb2..d35201d 100644 --- a/core-spec/v1/schemas/segment.yaml +++ b/core-spec/v1/schemas/segment.yaml @@ -25,34 +25,39 @@ properties: $ref: "common/id.yaml#/$defs/table_id" definition: description: > - Filter definition. Must use type: query with a physical table source - and a filter clause. Segments cannot use aggregation, breakout, joins, - expressions, or other query clauses. + Filter definition in pMBQL format. Must have a single MBQL stage + with a physical table source and a filter clause. Segments cannot + use aggregation, breakout, joins, expressions, or other query clauses. allOf: - $ref: "common/query.yaml" - type: object required: + - "lib/type" - database - - type - - query + - stages properties: - type: - const: query - query: - type: object - required: - - source-table - - filter - additionalProperties: false - properties: - source-table: - description: > - Table FK [database, schema, table]. Segments must reference - a physical table, not a saved card/model. - $ref: "common/id.yaml#/$defs/table_id" - filter: - description: Filter clause - $ref: "common/query.yaml#/$defs/expression" + stages: + type: array + minItems: 1 + maxItems: 1 + items: + type: object + required: + - "lib/type" + - source-table + - filter + additionalProperties: false + properties: + "lib/type": + const: mbql.stage/mbql + source-table: + description: > + Table FK [database, schema, table]. Segments must reference + a physical table, not a saved card/model. + $ref: "common/id.yaml#/$defs/table_id" + filter: + description: Filter clause + $ref: "common/query.yaml#/$defs/expression" description: type: - string diff --git a/core-spec/v1/schemas/transform.yaml b/core-spec/v1/schemas/transform.yaml index 5d781ed..7991762 100644 --- a/core-spec/v1/schemas/transform.yaml +++ b/core-spec/v1/schemas/transform.yaml @@ -119,7 +119,7 @@ $defs: type: string const: query query: - description: Query (MBQL or native) + description: Query in pMBQL format $ref: "common/query.yaml" source-incremental-strategy: type: object diff --git a/examples/v1/collections/main/dashboards/click_behaviors.yaml b/examples/v1/collections/main/dashboards/click_behaviors.yaml index 14f12cc..b01ed39 100644 --- a/examples/v1/collections/main/dashboards/click_behaviors.yaml +++ b/examples/v1/collections/main/dashboards/click_behaviors.yaml @@ -21,11 +21,11 @@ dashcards: target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null series: [] visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/dashboards/inline_parameters.yaml b/examples/v1/collections/main/dashboards/inline_parameters.yaml index 4379fcf..09b39a2 100644 --- a/examples/v1/collections/main/dashboards/inline_parameters.yaml +++ b/examples/v1/collections/main/dashboards/inline_parameters.yaml @@ -69,21 +69,21 @@ dashcards: target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - card_id: h5F2EjHsRd73Dqqh8sAtd parameter_id: d0000002-0000-0000-0000-000000000002 target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null series: [] visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/dashboards/series_and_mappings.yaml b/examples/v1/collections/main/dashboards/series_and_mappings.yaml index 48815d2..2bedb31 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings.yaml @@ -27,22 +27,22 @@ dashcards: target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - stage-number: 0 - card_id: dShCrdMnthlyOrdrs0001 parameter_id: c0000002-0000-0000-0000-000000000002 target: - dimension - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null series: - card_id: dShCrdMnthlyRevnu0002 position: 0 diff --git a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_avg_order.yaml b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_avg_order.yaml index 174c480..9a30ecf 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_avg_order.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_avg_order.yaml @@ -6,28 +6,30 @@ database_id: Sample Database dashboard_id: 8xFV0XmZs2olbGKXWenfS collection_id: cOlDaShBoArDs0ExAmPlx dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: {} serdes/meta: - id: dShCrdMnthlyAvgOr0003 diff --git a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_cumulative.yaml b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_cumulative.yaml index f015086..11bfaaf 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_cumulative.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_cumulative.yaml @@ -6,22 +6,24 @@ database_id: Sample Database dashboard_id: 8xFV0XmZs2olbGKXWenfS collection_id: cOlDaShBoArDs0ExAmPlx dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - cum-count + - {} breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: {} serdes/meta: - id: dShCrdMnthlyCumul0004 diff --git a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_orders.yaml b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_orders.yaml index a096537..0af54db 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_orders.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_orders.yaml @@ -6,22 +6,24 @@ database_id: Sample Database dashboard_id: 8xFV0XmZs2olbGKXWenfS collection_id: cOlDaShBoArDs0ExAmPlx dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - count + - {} breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: {} serdes/meta: - id: dShCrdMnthlyOrdrs0001 diff --git a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_revenue.yaml b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_revenue.yaml index cf42dae..0da1c84 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings/monthly_revenue.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings/monthly_revenue.yaml @@ -6,28 +6,30 @@ database_id: Sample Database dashboard_id: 8xFV0XmZs2olbGKXWenfS collection_id: cOlDaShBoArDs0ExAmPlx dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: {} serdes/meta: - id: dShCrdMnthlyRevnu0002 diff --git a/examples/v1/collections/main/dashboards/series_and_mappings/native_orders.yaml b/examples/v1/collections/main/dashboards/series_and_mappings/native_orders.yaml index 2062847..c253cd8 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings/native_orders.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings/native_orders.yaml @@ -6,10 +6,11 @@ database_id: Sample Database dashboard_id: 8xFV0XmZs2olbGKXWenfS collection_id: cOlDaShBoArDs0ExAmPlx dataset_query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: "SELECT * FROM ORDERS WHERE TOTAL > {{min_total}}" + stages: + - "lib/type": mbql.stage/native + native: "SELECT * FROM ORDERS WHERE TOTAL > {{min_total}}" template-tags: min_total: type: number diff --git a/examples/v1/collections/main/dashboards/series_and_mappings/total_revenue_scalar.yaml b/examples/v1/collections/main/dashboards/series_and_mappings/total_revenue_scalar.yaml index 7af60a3..e1a66d1 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings/total_revenue_scalar.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings/total_revenue_scalar.yaml @@ -7,21 +7,23 @@ database_id: Sample Database dashboard_id: 8xFV0XmZs2olbGKXWenfS collection_id: cOlDaShBoArDs0ExAmPlx dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float visualization_settings: {} serdes/meta: - id: dShCrdTtlRevScalr0006 diff --git a/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml b/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml index e8f7676..7e91381 100644 --- a/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml +++ b/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml @@ -33,11 +33,11 @@ dashcards: target: - dimension - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null series: [] visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/dashboards/tabbed_dashboard/products_table.yaml b/examples/v1/collections/main/dashboards/tabbed_dashboard/products_table.yaml index d5e3312..b7d30ea 100644 --- a/examples/v1/collections/main/dashboards/tabbed_dashboard/products_table.yaml +++ b/examples/v1/collections/main/dashboards/tabbed_dashboard/products_table.yaml @@ -6,9 +6,10 @@ database_id: Sample Database dashboard_id: 7RZUq1g5o1C5ws_e3ppKf collection_id: cOlDaShBoArDs0ExAmPlx dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC diff --git a/examples/v1/collections/main/documents/product_analysis_report/category_breakdown.yaml b/examples/v1/collections/main/documents/product_analysis_report/category_breakdown.yaml index 663eb3a..6944632 100644 --- a/examples/v1/collections/main/documents/product_analysis_report/category_breakdown.yaml +++ b/examples/v1/collections/main/documents/product_analysis_report/category_breakdown.yaml @@ -7,22 +7,24 @@ database_id: Sample Database document_id: dOc1PrOdAnAlYsIsRpTx2 collection_id: cOlDoCuMeNtS0ExAmPlx2 dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - aggregation: - - - count - breakout: - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - null + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + aggregation: + - - count + - {} + breakout: + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY visualization_settings: {} parameters: [] parameter_mappings: [] diff --git a/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml b/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml index 3ca6123..6725486 100644 --- a/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml +++ b/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml @@ -20,11 +20,11 @@ dashcards: target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null serdes/meta: - id: Q_jD-f-9clKLFZ2TfUG2h model: Dashboard diff --git a/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml b/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml index b2304ee..ef75eeb 100644 --- a/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml +++ b/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml @@ -4,39 +4,45 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS aggregation: - - count + - {} - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - PRODUCTS - PRICE - - base-type: type/Float - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - PRODUCTS - RATING - - base-type: type/Float breakout: - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null order-by: - - desc + - {} - - aggregation + - {} - 0 visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/minimal/marketing_analytics/top_products_by_revenue.yaml b/examples/v1/collections/main/minimal/marketing_analytics/top_products_by_revenue.yaml index c064b05..0b42558 100644 --- a/examples/v1/collections/main/minimal/marketing_analytics/top_products_by_revenue.yaml +++ b/examples/v1/collections/main/minimal/marketing_analytics/top_products_by_revenue.yaml @@ -4,27 +4,28 @@ creator_id: admin@example.com display: bar database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: |- - SELECT - p.TITLE, - p.CATEGORY, - SUM(o.TOTAL) AS revenue - FROM ORDERS o - JOIN PRODUCTS p ON o.PRODUCT_ID = p.ID - WHERE p.CATEGORY = {{category}} - GROUP BY p.TITLE, p.CATEGORY - ORDER BY revenue DESC - LIMIT 10 - template-tags: - category: - type: text - name: category - id: b2c3d4e5-f678-90ab-cdef-1234567890ab - display-name: Category - default: Widget + stages: + - "lib/type": mbql.stage/native + native: |- + SELECT + p.TITLE, + p.CATEGORY, + SUM(o.TOTAL) AS revenue + FROM ORDERS o + JOIN PRODUCTS p ON o.PRODUCT_ID = p.ID + WHERE p.CATEGORY = {{category}} + GROUP BY p.TITLE, p.CATEGORY + ORDER BY revenue DESC + LIMIT 10 + template-tags: + category: + type: text + name: category + id: b2c3d4e5-f678-90ab-cdef-1234567890ab + display-name: Category + default: Widget visualization_settings: {} serdes/meta: - id: FTxpeL9vY5pyb6Lc6lCDK diff --git a/examples/v1/collections/main/queries/arithmetic_expressions.yaml b/examples/v1/collections/main/queries/arithmetic_expressions.yaml index 8139c30..1937305 100644 --- a/examples/v1/collections/main/queries/arithmetic_expressions.yaml +++ b/examples/v1/collections/main/queries/arithmetic_expressions.yaml @@ -4,106 +4,117 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - expressions: - Total Plus Tax: - - "+" + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + expressions: + Total Plus Tax: + - "+" + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - SUBTOTAL + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TAX + Price Difference: + - "-" + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - SUBTOTAL + Double Quantity: + - "*" + - {} + - - field + - base-type: type/Integer + - - Sample Database + - PUBLIC + - ORDERS + - QUANTITY + - 2 + Per Unit Price: + - "/" + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - field + - base-type: type/Integer + - - Sample Database + - PUBLIC + - ORDERS + - QUANTITY + aggregation: + - - sum + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - SUBTOTAL + - - sum + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TAX + - - sum + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - avg + - {} + - - field + - base-type: type/Integer + - - Sample Database + - PUBLIC + - ORDERS + - QUANTITY + filter: + - ">" + - {} + - - expression + - {} + - Per Unit Price + - 10 + breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - - SUBTOTAL - - base-type: type/Float - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TAX - - base-type: type/Float - Price Difference: - - "-" - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - field - - - Sample Database - - PUBLIC - - ORDERS - - SUBTOTAL - - base-type: type/Float - Double Quantity: - - "*" - - - field - - - Sample Database - - PUBLIC - - ORDERS - - QUANTITY - - base-type: type/Integer - - 2 - Per Unit Price: - - "/" - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - field - - - Sample Database - - PUBLIC - - ORDERS - - QUANTITY - - base-type: type/Integer - aggregation: - - - sum - - - field - - - Sample Database - - PUBLIC - - ORDERS - - SUBTOTAL - - base-type: type/Float - - - sum - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TAX - - base-type: type/Float - - - sum - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - avg - - - field - - - Sample Database - - PUBLIC - - ORDERS - - QUANTITY - - base-type: type/Integer - filter: - - ">" - - - expression - - Per Unit Price - - 10 - breakout: - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - temporal-unit: month + - CREATED_AT visualization_settings: {} serdes/meta: - id: 1O_2jSo2fD6m3Qr6My7aa diff --git a/examples/v1/collections/main/queries/basic_aggregations.yaml b/examples/v1/collections/main/queries/basic_aggregations.yaml index 5e7839f..3ff291e 100644 --- a/examples/v1/collections/main/queries/basic_aggregations.yaml +++ b/examples/v1/collections/main/queries/basic_aggregations.yaml @@ -4,80 +4,93 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - count + - {} - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - - min + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - - max + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - - count + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - PRODUCT_ID - - null - - distinct + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - PRODUCT_ID - - null - - aggregation-options + - display-name: Total Revenue + name: total_revenue - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - - display-name: Total Revenue - name: total_revenue breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month order-by: - - desc + - {} - - aggregation + - {} - 0 - - asc + - {} - - aggregation + - {} - 1 limit: 12 visualization_settings: {} diff --git a/examples/v1/collections/main/queries/comparison_filters.yaml b/examples/v1/collections/main/queries/comparison_filters.yaml index 70ab53c..961af5b 100644 --- a/examples/v1/collections/main/queries/comparison_filters.yaml +++ b/examples/v1/collections/main/queries/comparison_filters.yaml @@ -4,86 +4,96 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS filter: - and + - {} - - between + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null - 10 - 200 - - ">" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - RATING - - null - 3 - - "<=" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - RATING - - null - 5 - - "!=" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - Doohickey - - = + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - Widget - Gadget - Gizmo - - in + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - Widget - Gadget - - not-in + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - Doohickey - Gizmo - - "=" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null - - value - - 42.0 - effective-type: type/Float + - 42.0 limit: 20 visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/queries/conditional_aggregations.yaml b/examples/v1/collections/main/queries/conditional_aggregations.yaml index df58395..a136d90 100644 --- a/examples/v1/collections/main/queries/conditional_aggregations.yaml +++ b/examples/v1/collections/main/queries/conditional_aggregations.yaml @@ -4,68 +4,77 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - aggregation: - - - count-where - - - ">" + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + aggregation: + - - count-where + - {} + - - ">" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - 100 + - - sum-where + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - null - - 100 - - - sum-where - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - ">" + - - ">" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - DISCOUNT + - 0 + - - distinct-where + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - - DISCOUNT - - null - - 0 - - - distinct-where + - USER_ID + - - ">" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - 50 + - - share + - {} + - - not-null + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - DISCOUNT + breakout: - - field + - temporal-unit: quarter - - Sample Database - PUBLIC - ORDERS - - USER_ID - - null - - - ">" - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - null - - 50 - - - share - - - not-null - - - field - - - Sample Database - - PUBLIC - - ORDERS - - DISCOUNT - - null - breakout: - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - temporal-unit: quarter + - CREATED_AT visualization_settings: {} serdes/meta: - id: irROiaJoSsiXPKGxwWvWY diff --git a/examples/v1/collections/main/queries/conditional_and_type.yaml b/examples/v1/collections/main/queries/conditional_and_type.yaml index bbbb7d5..1396f5f 100644 --- a/examples/v1/collections/main/queries/conditional_and_type.yaml +++ b/examples/v1/collections/main/queries/conditional_and_type.yaml @@ -4,92 +4,102 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - expressions: - Price Tier: - - case - - - - - ">" - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - - 100 - - Premium - - - - ">" - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - - 30 - - Standard - - default: Budget - Is Premium: - - if - - - - - ">" - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - - 100 - - true - - default: false - Simple Category: - - case - - - - - ">" - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - RATING - - null - - 4 - - Popular - Effective Price: - - coalesce - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - - 0 - Price as Text: - - text - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - Rating as Integer: - - integer - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - RATING - - null - Rating as Float: - - float - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - RATING - - null - limit: 10 + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + expressions: + Price Tier: + - case + - default: Budget + - - - - ">" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + - 100 + - Premium + - - - ">" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + - 30 + - Standard + Is Premium: + - if + - default: false + - - - - ">" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + - 100 + - true + Simple Category: + - case + - {} + - - - - ">" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - RATING + - 4 + - Popular + Effective Price: + - coalesce + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + - 0 + Price as Text: + - text + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + Rating as Integer: + - integer + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - RATING + Rating as Float: + - float + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - RATING + limit: 10 visualization_settings: {} serdes/meta: - id: 1hsUzNOepulZo3Jamzd1R diff --git a/examples/v1/collections/main/queries/cumulative_and_statistical.yaml b/examples/v1/collections/main/queries/cumulative_and_statistical.yaml index 8726a88..4a73593 100644 --- a/examples/v1/collections/main/queries/cumulative_and_statistical.yaml +++ b/examples/v1/collections/main/queries/cumulative_and_statistical.yaml @@ -4,65 +4,73 @@ creator_id: admin@example.com display: line database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - aggregation: - - - cum-count - - - cum-count + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + aggregation: + - - cum-count + - {} + - - cum-count + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - PRODUCT_ID + - - cum-sum + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - stddev + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - var + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - median + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - percentile + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - 0.9 + breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - - PRODUCT_ID - - null - - - cum-sum - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - stddev - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - var - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - median - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - - percentile - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - - 0.9 - breakout: - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - temporal-unit: month + - CREATED_AT visualization_settings: {} serdes/meta: - id: x61UtCMCuBNjw0TEFQeWG diff --git a/examples/v1/collections/main/queries/geographic_filter.yaml b/examples/v1/collections/main/queries/geographic_filter.yaml index 5624b7b..c71a9f3 100644 --- a/examples/v1/collections/main/queries/geographic_filter.yaml +++ b/examples/v1/collections/main/queries/geographic_filter.yaml @@ -4,31 +4,33 @@ creator_id: admin@example.com display: map database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PEOPLE - filter: - - inside - - - field - - - Sample Database - - PUBLIC - - PEOPLE - - LATITUDE - - null - - - field - - - Sample Database - - PUBLIC - - PEOPLE - - LONGITUDE - - null - - 40.8 - - -74.1 - - 40.6 - - -73.9 + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PEOPLE + filter: + - inside + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - LATITUDE + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - LONGITUDE + - 40.8 + - -74.1 + - 40.6 + - -73.9 visualization_settings: {} serdes/meta: - id: bK64P6yr9_Nx-A8S3PqOZ diff --git a/examples/v1/collections/main/queries/joins.yaml b/examples/v1/collections/main/queries/joins.yaml index 09569bc..8874bab 100644 --- a/examples/v1/collections/main/queries/joins.yaml +++ b/examples/v1/collections/main/queries/joins.yaml @@ -4,95 +4,107 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS joins: - - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - condition: - - = - - - field - - - Sample Database - - PUBLIC - - ORDERS - - PRODUCT_ID - - null - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - ID - - null + - stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + conditions: + - - "=" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - PRODUCT_ID + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - ID alias: Products strategy: left-join fields: all - - source-table: - - Sample Database - - PUBLIC - - PEOPLE - condition: - - = - - - field - - - Sample Database - - PUBLIC - - ORDERS - - USER_ID - - null - - - field - - - Sample Database - - PUBLIC - - PEOPLE - - ID - - null + - stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PEOPLE + conditions: + - - "=" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - USER_ID + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - ID alias: People strategy: inner-join fields: - - field + - join-alias: People - - Sample Database - PUBLIC - PEOPLE - NAME - - join-alias: People - - field + - join-alias: People - - Sample Database - PUBLIC - PEOPLE - STATE - - join-alias: People - - source-table: - - Sample Database - - PUBLIC - - REVIEWS - condition: - - and - - - = - - - field - - - Sample Database - - PUBLIC - - ORDERS - - PRODUCT_ID - - null - - - field - - - Sample Database - - PUBLIC - - REVIEWS - - PRODUCT_ID - - null - - - ">=" - - - field - - - Sample Database - - PUBLIC - - REVIEWS - - RATING - - null - - 4 + - stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - REVIEWS + conditions: + - - and + - {} + - - = + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - PRODUCT_ID + - - field + - {} + - - Sample Database + - PUBLIC + - REVIEWS + - PRODUCT_ID + - - ">=" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - REVIEWS + - RATING + - 4 alias: GoodReviews strategy: left-join fields: none diff --git a/examples/v1/collections/main/queries/math_functions.yaml b/examples/v1/collections/main/queries/math_functions.yaml index 350f0f4..e00c2ee 100644 --- a/examples/v1/collections/main/queries/math_functions.yaml +++ b/examples/v1/collections/main/queries/math_functions.yaml @@ -4,82 +4,92 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - expressions: - Absolute Discount: - - abs - - - "-" + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + expressions: + Absolute Discount: + - abs + - {} + - - "-" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + - 50 + Price Ceiling: + - ceil + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null - - 50 - Price Ceiling: - - ceil - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - Price Floor: - - floor - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - Rounded Price: - - round - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - Rating Squared: - - power - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - RATING - - null - - 2 - Price Sqrt: - - sqrt - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - Price Exp: - - exp - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - RATING - - null - Price Log: - - log - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - PRICE - - null - limit: 10 + Price Floor: + - floor + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + Rounded Price: + - round + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + Rating Squared: + - power + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - RATING + - 2 + Price Sqrt: + - sqrt + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + Price Exp: + - exp + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - RATING + Price Log: + - log + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + limit: 10 visualization_settings: {} serdes/meta: - id: jPrM-oh3r1BR42xSs4Ipj diff --git a/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml b/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml index caeda26..ad90129 100644 --- a/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml +++ b/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml @@ -4,21 +4,25 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - aggregation: - - - metric - - IW8kbqZVaMxdGtCM2F4U6 - - - measure - - DBap2523KuN4Lt-cYrUjF - filter: - - segment - - OaFXAvEzPvu9ZXW5PUMRa + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + aggregation: + - - metric + - {} + - IW8kbqZVaMxdGtCM2F4U6 + - - measure + - {} + - DBap2523KuN4Lt-cYrUjF + filter: + - segment + - {} + - OaFXAvEzPvu9ZXW5PUMRa visualization_settings: {} serdes/meta: - id: kBjQ5VXJ5z3vYSW72J6qa diff --git a/examples/v1/collections/main/queries/native_card_and_snippet.yaml b/examples/v1/collections/main/queries/native_card_and_snippet.yaml index cd0e18f..01865f1 100644 --- a/examples/v1/collections/main/queries/native_card_and_snippet.yaml +++ b/examples/v1/collections/main/queries/native_card_and_snippet.yaml @@ -4,29 +4,30 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: |- - SELECT * - FROM {{#1-basic_aggregations}} - WHERE {{snippet: Active Product Filter}} - ORDER BY "count" DESC - LIMIT 10 - template-tags: - "#1-basic_aggregations": - type: card - name: "#1-basic_aggregations" - id: cc000001-0000-0000-0000-000000000001 - display-name: Basic Aggregations - card-id: h5F2EjHsRd73Dqqh8sAtd - "snippet: Active Product Filter": - type: snippet - name: "snippet: Active Product Filter" - id: cc000002-0000-0000-0000-000000000002 - display-name: "Snippet: Active Product Filter" - snippet-name: Active Product Filter - snippet-id: WyQWnT23PF-SfbYLROllJ + stages: + - "lib/type": mbql.stage/native + native: |- + SELECT * + FROM {{#1-basic_aggregations}} + WHERE {{snippet: Active Product Filter}} + ORDER BY "count" DESC + LIMIT 10 + template-tags: + "#1-basic_aggregations": + type: card + name: "#1-basic_aggregations" + id: cc000001-0000-0000-0000-000000000001 + display-name: Basic Aggregations + card-id: h5F2EjHsRd73Dqqh8sAtd + "snippet: Active Product Filter": + type: snippet + name: "snippet: Active Product Filter" + id: cc000002-0000-0000-0000-000000000002 + display-name: "Snippet: Active Product Filter" + snippet-name: Active Product Filter + snippet-id: WyQWnT23PF-SfbYLROllJ visualization_settings: {} serdes/meta: - id: HiBFSt0BNx5s5MxVDLLKB diff --git a/examples/v1/collections/main/queries/native_field_filter.yaml b/examples/v1/collections/main/queries/native_field_filter.yaml index 132e276..85bb186 100644 --- a/examples/v1/collections/main/queries/native_field_filter.yaml +++ b/examples/v1/collections/main/queries/native_field_filter.yaml @@ -4,57 +4,58 @@ creator_id: admin@example.com display: line database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: |- - SELECT {{created_at}} AS period, PRODUCTS.CATEGORY, COUNT(*) AS cnt - FROM ORDERS - JOIN PRODUCTS ON ORDERS.PRODUCT_ID = PRODUCTS.ID - WHERE {{category_filter}} - AND {{date_filter}} - GROUP BY {{created_at}}, PRODUCTS.CATEGORY - template-tags: - category_filter: - type: dimension - name: category_filter - id: bb000001-0000-0000-0000-000000000001 - display-name: Category - dimension: - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - null - widget-type: string/= - date_filter: - type: dimension - name: date_filter - id: bb000002-0000-0000-0000-000000000002 - display-name: Order Date - dimension: - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - widget-type: date/range - created_at: - type: temporal-unit - sectionId: date - name: created_at - id: bb000003-0000-0000-0000-000000000003 - display-name: Group By - default: month - dimension: - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null + stages: + - "lib/type": mbql.stage/native + native: |- + SELECT {{created_at}} AS period, PRODUCTS.CATEGORY, COUNT(*) AS cnt + FROM ORDERS + JOIN PRODUCTS ON ORDERS.PRODUCT_ID = PRODUCTS.ID + WHERE {{category_filter}} + AND {{date_filter}} + GROUP BY {{created_at}}, PRODUCTS.CATEGORY + template-tags: + category_filter: + type: dimension + name: category_filter + id: bb000001-0000-0000-0000-000000000001 + display-name: Category + dimension: + - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + widget-type: string/= + date_filter: + type: dimension + name: date_filter + id: bb000002-0000-0000-0000-000000000002 + display-name: Order Date + dimension: + - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + widget-type: date/range + created_at: + type: temporal-unit + sectionId: date + name: created_at + id: bb000003-0000-0000-0000-000000000003 + display-name: Group By + default: month + dimension: + - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT visualization_settings: {} serdes/meta: - id: sk02d7sPWAk2TYH2Y7JhZ diff --git a/examples/v1/collections/main/queries/native_variables.yaml b/examples/v1/collections/main/queries/native_variables.yaml index 56f51c4..6c01667 100644 --- a/examples/v1/collections/main/queries/native_variables.yaml +++ b/examples/v1/collections/main/queries/native_variables.yaml @@ -4,45 +4,46 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: |- - SELECT * - FROM ORDERS - WHERE TOTAL > {{min_total}} - AND CREATED_AT > {{after_date}} - AND USER_ID = {{user_id}} - AND {{is_active}} - template-tags: - min_total: - type: number - sectionId: number - name: min_total - id: aa000001-0000-0000-0000-000000000001 - display-name: Minimum Total - default: 50 - required: true - after_date: - type: date - sectionId: date - name: after_date - id: aa000002-0000-0000-0000-000000000002 - display-name: After Date - default: '2024-01-01' - user_id: - type: text - name: user_id - id: aa000003-0000-0000-0000-000000000003 - display-name: User ID - default: '1' - is_active: - type: boolean - sectionId: boolean - name: is_active - id: aa000004-0000-0000-0000-000000000004 - display-name: Is Active - default: true + stages: + - "lib/type": mbql.stage/native + native: |- + SELECT * + FROM ORDERS + WHERE TOTAL > {{min_total}} + AND CREATED_AT > {{after_date}} + AND USER_ID = {{user_id}} + AND {{is_active}} + template-tags: + min_total: + type: number + sectionId: number + name: min_total + id: aa000001-0000-0000-0000-000000000001 + display-name: Minimum Total + default: 50 + required: true + after_date: + type: date + sectionId: date + name: after_date + id: aa000002-0000-0000-0000-000000000002 + display-name: After Date + default: '2024-01-01' + user_id: + type: text + name: user_id + id: aa000003-0000-0000-0000-000000000003 + display-name: User ID + default: '1' + is_active: + type: boolean + sectionId: boolean + name: is_active + id: aa000004-0000-0000-0000-000000000004 + display-name: Is Active + default: true visualization_settings: {} serdes/meta: - id: 2u10n8GV6u0LFYrq8yV5p diff --git a/examples/v1/collections/main/queries/nested_query.yaml b/examples/v1/collections/main/queries/nested_query.yaml index 8b3403a..966353a 100644 --- a/examples/v1/collections/main/queries/nested_query.yaml +++ b/examples/v1/collections/main/queries/nested_query.yaml @@ -4,41 +4,46 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - aggregation: - - - count - - - sum - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float - breakout: + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + aggregation: + - - count + - {} + - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - - USER_ID - - null + - TOTAL + breakout: + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - USER_ID + - "lib/type": mbql.stage/mbql filter: - ">" + - {} - - field - - count - base-type: type/Integer + - count - 5 order-by: - - desc + - {} - - field - - sum - base-type: type/Float + - sum limit: 20 visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/queries/null_and_string_filters.yaml b/examples/v1/collections/main/queries/null_and_string_filters.yaml index a3d69b2..65ae691 100644 --- a/examples/v1/collections/main/queries/null_and_string_filters.yaml +++ b/examples/v1/collections/main/queries/null_and_string_filters.yaml @@ -4,154 +4,163 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS filter: - and + - {} - - not-null + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - - not-empty + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - VENDOR - - null - - is-empty + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - VENDOR - - null # contains — 2 args, no options - - contains + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - widget # contains — 2 args, with options - - contains + - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - gadget - - case-sensitive: false # contains — 3+ args (multi-value), options required in position 2 - - contains - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - widget - gadget # does-not-contain — 2 args, no options - - does-not-contain + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - VENDOR - - null - LLC # does-not-contain — 2 args, with options - - does-not-contain + - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - VENDOR - - null - inc - - case-sensitive: false # does-not-contain — 3+ args (multi-value) - - does-not-contain - case-sensitive: true - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - VENDOR - - null - LLC - Corp # starts-with — 2 args, no options - - starts-with + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - Awesome # starts-with — 2 args, with options - - starts-with + - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - awesome - - case-sensitive: false # starts-with — 3+ args (multi-value) - - starts-with - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - Awesome - Incredible # ends-with — 2 args, no options - - ends-with + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - EAN - - null - "0" # ends-with — 2 args, with options - - ends-with + - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - EAN - - null - "9" - - case-sensitive: false # ends-with — 3+ args (multi-value) - - ends-with - case-sensitive: true - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - EAN - - null - "0" - "5" limit: 20 diff --git a/examples/v1/collections/main/queries/source_card_reference.yaml b/examples/v1/collections/main/queries/source_card_reference.yaml index 8cd7624..1cbd828 100644 --- a/examples/v1/collections/main/queries/source_card_reference.yaml +++ b/examples/v1/collections/main/queries/source_card_reference.yaml @@ -4,21 +4,24 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: h5F2EjHsRd73Dqqh8sAtd + stages: + - "lib/type": mbql.stage/mbql + source-card: h5F2EjHsRd73Dqqh8sAtd filter: - ">" + - {} - - field - - count - base-type: type/Integer + - count - 100 order-by: - - desc + - {} - - field - - count - base-type: type/Integer + - count visualization_settings: {} serdes/meta: - id: gt4OaWYAuDWRHn5Irnd4h diff --git a/examples/v1/collections/main/queries/string_functions.yaml b/examples/v1/collections/main/queries/string_functions.yaml index c0974e9..2261af3 100644 --- a/examples/v1/collections/main/queries/string_functions.yaml +++ b/examples/v1/collections/main/queries/string_functions.yaml @@ -4,117 +4,129 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - expressions: - Title and Category: - - concat - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - - " (" - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - null - - ")" - First 10 Chars: - - substring - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - - 1 - - 10 - Cleaned Vendor: - - replace - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - VENDOR - - null - - Inc. - - Incorporated - EAN Prefix: - - regex-match-first - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - EAN - - null - - "^\\d{3}" - Trimmed Title: - - trim - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - Left Trimmed: - - ltrim - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - Right Trimmed: - - rtrim - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - Upper Category: - - upper - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - null - Lower Title: - - lower - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - Title Length: - - length - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - Title From 5th Char: - - substring - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - - null - - 5 - limit: 10 + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + expressions: + Title and Category: + - concat + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + - " (" + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + - ")" + First 10 Chars: + - substring + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + - 1 + - 10 + Cleaned Vendor: + - replace + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - VENDOR + - Inc. + - Incorporated + EAN Prefix: + - regex-match-first + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - EAN + - "^\\d{3}" + Trimmed Title: + - trim + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + Left Trimmed: + - ltrim + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + Right Trimmed: + - rtrim + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + Upper Category: + - upper + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + Lower Title: + - lower + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + Title Length: + - length + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + Title From 5th Char: + - substring + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - TITLE + - 5 + limit: 10 visualization_settings: {} serdes/meta: - id: HeLFZSVb4Jm25p4tWfVP9 diff --git a/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml b/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml index 41d890b..dfec7b6 100644 --- a/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml +++ b/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml @@ -4,52 +4,59 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS filter: - and + - {} - - time-interval + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null - -30 - day - - time-interval + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null - current - month - - relative-time-interval + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null - -30 - day - -1 - month - - not + - {} - - is-null + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - DISCOUNT - - null limit: 20 visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/queries/temporal_expressions.yaml b/examples/v1/collections/main/queries/temporal_expressions.yaml index a67fec4..2fb01ff 100644 --- a/examples/v1/collections/main/queries/temporal_expressions.yaml +++ b/examples/v1/collections/main/queries/temporal_expressions.yaml @@ -4,80 +4,91 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - expressions: - Ship By: - - datetime-add - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - 7 - - day - Week Before: - - datetime-subtract - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - 1 - - week - Days Since Order: - - datetime-diff - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - - now - - day - Ship By Deadline: - - "+" - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - - interval + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + expressions: + Ship By: + - datetime-add + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT - 7 - day - Order Date: - - date - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Parsed Datetime: - - datetime - - "2024-06-15T10:30:00" - Parsed Unix: - - datetime - - - field - - - Sample Database - - PUBLIC - - ORDERS - - QUANTITY - - base-type: type/Integer - - mode: unix-seconds - Current Time: - - now - Today Date: - - today - limit: 10 + Week Before: + - datetime-subtract + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - 1 + - week + Days Since Order: + - datetime-diff + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - - now + - {} + - day + Ship By Deadline: + - "+" + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - - interval + - {} + - 7 + - day + Order Date: + - date + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Parsed Datetime: + - datetime + - {} + - "2024-06-15T10:30:00" + Parsed Unix: + - datetime + - mode: unix-seconds + - - field + - base-type: type/Integer + - - Sample Database + - PUBLIC + - ORDERS + - QUANTITY + Current Time: + - now + - {} + Today Date: + - today + - {} + limit: 10 visualization_settings: {} serdes/meta: - id: DBBrqcMAmOO0sbM_CzM_Z diff --git a/examples/v1/collections/main/queries/temporal_extraction.yaml b/examples/v1/collections/main/queries/temporal_extraction.yaml index f57763c..b3a92fe 100644 --- a/examples/v1/collections/main/queries/temporal_extraction.yaml +++ b/examples/v1/collections/main/queries/temporal_extraction.yaml @@ -4,152 +4,172 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - expressions: - Order Year: - - get-year - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Order Quarter: - - get-quarter - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Order Month: - - get-month - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Order Day: - - get-day - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Order Hour: - - get-hour - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Order Minute: - - get-minute - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Order Second: - - get-second - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Day of Week ISO: - - get-day-of-week - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - iso - Week Number: - - get-week - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - us - Month Name: - - month-name - - - get-month + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + expressions: + Order Year: + - get-year + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null - Quarter Name: - - quarter-name - - - get-quarter + Order Quarter: + - get-quarter + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null - Day Name: - - day-name - - - get-day-of-week + Order Month: + - get-month + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null + Order Day: + - get-day + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Order Hour: + - get-hour + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Order Minute: + - get-minute + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Order Second: + - get-second + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Day of Week ISO: + - get-day-of-week + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - iso + Week Number: + - get-week + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - us + Month Name: + - month-name + - {} + - - get-month + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Quarter Name: + - quarter-name + - {} + - - get-quarter + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Day Name: + - day-name + - {} + - - get-day-of-week + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - iso + Day of Week Default: + - get-day-of-week + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Week Number Default: + - get-week + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + Extracted Month: + - temporal-extract + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - month-of-year + Extracted Day of Week ISO: + - temporal-extract + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - day-of-week - iso - Day of Week Default: - - get-day-of-week - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Week Number Default: - - get-week - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - Extracted Month: - - temporal-extract - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - month-of-year - Extracted Day of Week ISO: - - temporal-extract - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - null - - day-of-week - - iso - limit: 10 + limit: 10 visualization_settings: {} serdes/meta: - id: bDK7jyPszEHzHh4aG4_SV diff --git a/examples/v1/collections/main/queries/total_revenue_metric.yaml b/examples/v1/collections/main/queries/total_revenue_metric.yaml index d63ecb7..b484216 100644 --- a/examples/v1/collections/main/queries/total_revenue_metric.yaml +++ b/examples/v1/collections/main/queries/total_revenue_metric.yaml @@ -5,21 +5,23 @@ display: scalar type: metric database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - aggregation: - - - sum - - - field - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - base-type: type/Float + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + aggregation: + - - sum + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL visualization_settings: {} serdes/meta: - id: IW8kbqZVaMxdGtCM2F4U6 diff --git a/examples/v1/collections/main/queries/url_functions.yaml b/examples/v1/collections/main/queries/url_functions.yaml index ab505fa..ddbf12f 100644 --- a/examples/v1/collections/main/queries/url_functions.yaml +++ b/examples/v1/collections/main/queries/url_functions.yaml @@ -4,47 +4,52 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PEOPLE - expressions: - Source Host: - - host - - - field - - - Sample Database - - PUBLIC - - PEOPLE - - SOURCE - - null - Source Domain: - - domain - - - field - - - Sample Database - - PUBLIC - - PEOPLE - - SOURCE - - null - Source Subdomain: - - subdomain - - - field - - - Sample Database - - PUBLIC - - PEOPLE - - SOURCE - - null - Source Path: - - path - - - field - - - Sample Database - - PUBLIC - - PEOPLE - - SOURCE - - null - limit: 10 + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PEOPLE + expressions: + Source Host: + - host + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - SOURCE + Source Domain: + - domain + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - SOURCE + Source Subdomain: + - subdomain + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - SOURCE + Source Path: + - path + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - SOURCE + limit: 10 visualization_settings: {} serdes/meta: - id: uwAeNRHymXTD1G_7lWV1d diff --git a/examples/v1/collections/main/queries/window_offset.yaml b/examples/v1/collections/main/queries/window_offset.yaml index e5335e8..e43dac1 100644 --- a/examples/v1/collections/main/queries/window_offset.yaml +++ b/examples/v1/collections/main/queries/window_offset.yaml @@ -4,38 +4,41 @@ creator_id: admin@example.com display: line database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - - offset - - null + - {} - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - -1 breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: {} serdes/meta: - id: ErQY8K5Tep4xBc3VY_-1e diff --git a/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml b/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml index 6a21829..f371a89 100644 --- a/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml +++ b/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml @@ -4,22 +4,24 @@ creator_id: admin@example.com display: bar database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - count + - {} breakout: - - field + - temporal-unit: quarter - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: quarter joins: - source-table: - Sample Database @@ -27,18 +29,19 @@ dataset_query: - PRODUCTS condition: - = + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - PRODUCT_ID - - null - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - ID - - null alias: Products strategy: left-join fields: all diff --git a/examples/v1/collections/main/visualization_settings/funnel.yaml b/examples/v1/collections/main/visualization_settings/funnel.yaml index 429de22..fdd252c 100644 --- a/examples/v1/collections/main/visualization_settings/funnel.yaml +++ b/examples/v1/collections/main/visualization_settings/funnel.yaml @@ -4,22 +4,24 @@ creator_id: admin@example.com display: funnel database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS aggregation: - - count + - {} breakout: - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null visualization_settings: "funnel.dimension": CATEGORY "funnel.metric": count diff --git a/examples/v1/collections/main/visualization_settings/gauge.yaml b/examples/v1/collections/main/visualization_settings/gauge.yaml index 96039fd..a9b7209 100644 --- a/examples/v1/collections/main/visualization_settings/gauge.yaml +++ b/examples/v1/collections/main/visualization_settings/gauge.yaml @@ -4,21 +4,23 @@ creator_id: admin@example.com display: gauge database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float visualization_settings: "gauge.segments": - min: 0 diff --git a/examples/v1/collections/main/visualization_settings/line_chart.yaml b/examples/v1/collections/main/visualization_settings/line_chart.yaml index 02b7d60..5f78821 100644 --- a/examples/v1/collections/main/visualization_settings/line_chart.yaml +++ b/examples/v1/collections/main/visualization_settings/line_chart.yaml @@ -4,28 +4,30 @@ creator_id: admin@example.com display: line database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: "graph.show_values": true "graph.label_values_frequency": fit diff --git a/examples/v1/collections/main/visualization_settings/map_pins.yaml b/examples/v1/collections/main/visualization_settings/map_pins.yaml index 62ca619..6a7b898 100644 --- a/examples/v1/collections/main/visualization_settings/map_pins.yaml +++ b/examples/v1/collections/main/visualization_settings/map_pins.yaml @@ -4,9 +4,10 @@ creator_id: admin@example.com display: map database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC diff --git a/examples/v1/collections/main/visualization_settings/pie_chart.yaml b/examples/v1/collections/main/visualization_settings/pie_chart.yaml index 9afdbb0..ff8cbc4 100644 --- a/examples/v1/collections/main/visualization_settings/pie_chart.yaml +++ b/examples/v1/collections/main/visualization_settings/pie_chart.yaml @@ -4,22 +4,24 @@ creator_id: admin@example.com display: pie database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS aggregation: - - count + - {} breakout: - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null visualization_settings: "pie.dimension": CATEGORY "pie.metric": count diff --git a/examples/v1/collections/main/visualization_settings/pivot_table.yaml b/examples/v1/collections/main/visualization_settings/pivot_table.yaml index 59b9e5c..4174dba 100644 --- a/examples/v1/collections/main/visualization_settings/pivot_table.yaml +++ b/examples/v1/collections/main/visualization_settings/pivot_table.yaml @@ -4,29 +4,32 @@ creator_id: admin@example.com display: pivot database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - count + - {} - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float breakout: - - field + - temporal-unit: quarter - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: quarter joins: - source-table: - Sample Database @@ -34,18 +37,19 @@ dataset_query: - PRODUCTS condition: - = + - {} - - field + - {} - - Sample Database - PUBLIC - ORDERS - PRODUCT_ID - - null - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - ID - - null alias: Products strategy: left-join fields: all diff --git a/examples/v1/collections/main/visualization_settings/smart_scalar.yaml b/examples/v1/collections/main/visualization_settings/smart_scalar.yaml index d8a5c52..ce23d1d 100644 --- a/examples/v1/collections/main/visualization_settings/smart_scalar.yaml +++ b/examples/v1/collections/main/visualization_settings/smart_scalar.yaml @@ -4,28 +4,30 @@ creator_id: admin@example.com display: smartscalar database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: "scalar.compact_primary_number": auto "scalar.comparisons": diff --git a/examples/v1/collections/main/visualization_settings/table_formatted.yaml b/examples/v1/collections/main/visualization_settings/table_formatted.yaml index b587a8e..d09bd5a 100644 --- a/examples/v1/collections/main/visualization_settings/table_formatted.yaml +++ b/examples/v1/collections/main/visualization_settings/table_formatted.yaml @@ -4,9 +4,10 @@ creator_id: admin@example.com display: table database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC diff --git a/examples/v1/collections/main/visualization_settings/waterfall.yaml b/examples/v1/collections/main/visualization_settings/waterfall.yaml index 6a81fee..3a5340e 100644 --- a/examples/v1/collections/main/visualization_settings/waterfall.yaml +++ b/examples/v1/collections/main/visualization_settings/waterfall.yaml @@ -4,28 +4,30 @@ creator_id: admin@example.com display: waterfall database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month visualization_settings: "waterfall.increase_color": "#88BF4D" "waterfall.decrease_color": "#EF8C8C" diff --git a/examples/v1/collections/transforms/daily_order_summary.yaml b/examples/v1/collections/transforms/daily_order_summary.yaml index aed25a0..fb8dd96 100644 --- a/examples/v1/collections/transforms/daily_order_summary.yaml +++ b/examples/v1/collections/transforms/daily_order_summary.yaml @@ -5,17 +5,17 @@ source_database_id: Sample Database source: type: query query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: |- - SELECT - DATE_TRUNC('day', CREATED_AT) AS order_date, - COUNT(*) AS order_count, - SUM(TOTAL) AS total_revenue - FROM ORDERS - GROUP BY 1 - template-tags: {} + stages: + - "lib/type": mbql.stage/native + native: |- + SELECT + DATE_TRUNC('day', CREATED_AT) AS order_date, + COUNT(*) AS order_count, + SUM(TOTAL) AS total_revenue + FROM ORDERS + GROUP BY 1 target: database: Sample Database type: table diff --git a/examples/v1/collections/transforms/hourly_product_stats.yaml b/examples/v1/collections/transforms/hourly_product_stats.yaml index 0b2effc..ace4d2b 100644 --- a/examples/v1/collections/transforms/hourly_product_stats.yaml +++ b/examples/v1/collections/transforms/hourly_product_stats.yaml @@ -5,29 +5,32 @@ source_database_id: Sample Database source: type: query query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - aggregation: - - - count - - - avg + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + aggregation: + - - count + - {} + - - avg + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + breakout: - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - - PRICE - - base-type: type/Float - breakout: - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - null + - CATEGORY target: database: Sample Database type: table diff --git a/examples/v1/collections/transforms/mbql_transform.yaml b/examples/v1/collections/transforms/mbql_transform.yaml index 4f280b9..d251322 100644 --- a/examples/v1/collections/transforms/mbql_transform.yaml +++ b/examples/v1/collections/transforms/mbql_transform.yaml @@ -5,29 +5,32 @@ source_database_id: Sample Database source: type: query query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - aggregation: - - - count - - - sum + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + aggregation: + - - count + - {} + - - sum + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - - TOTAL - - base-type: type/Float - breakout: - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - temporal-unit: month + - CREATED_AT target: database: Sample Database type: table diff --git a/examples/v1/collections/transforms/monthly_sales_summary.yaml b/examples/v1/collections/transforms/monthly_sales_summary.yaml index 94eb719..e6f36ba 100644 --- a/examples/v1/collections/transforms/monthly_sales_summary.yaml +++ b/examples/v1/collections/transforms/monthly_sales_summary.yaml @@ -5,19 +5,19 @@ source_database_id: Sample Database source: type: query query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: |- - SELECT - DATE_TRUNC('month', o.CREATED_AT) AS month, - p.CATEGORY, - COUNT(*) AS order_count, - SUM(o.TOTAL) AS total_revenue - FROM ORDERS o - JOIN PRODUCTS p ON o.PRODUCT_ID = p.ID - GROUP BY 1, 2 - template-tags: {} + stages: + - "lib/type": mbql.stage/native + native: |- + SELECT + DATE_TRUNC('month', o.CREATED_AT) AS month, + p.CATEGORY, + COUNT(*) AS order_count, + SUM(o.TOTAL) AS total_revenue + FROM ORDERS o + JOIN PRODUCTS p ON o.PRODUCT_ID = p.ID + GROUP BY 1, 2 target: database: Sample Database type: table diff --git a/examples/v1/collections/transforms/native_transform.yaml b/examples/v1/collections/transforms/native_transform.yaml index edde210..dd14125 100644 --- a/examples/v1/collections/transforms/native_transform.yaml +++ b/examples/v1/collections/transforms/native_transform.yaml @@ -5,19 +5,19 @@ source_database_id: Sample Database source: type: query query: + "lib/type": mbql/query database: Sample Database - type: native - native: - query: |- - SELECT - p.CATEGORY, - COUNT(DISTINCT o.ID) AS order_count, - SUM(o.TOTAL) AS total_revenue, - AVG(o.TOTAL) AS avg_order_value - FROM ORDERS o - JOIN PRODUCTS p ON o.PRODUCT_ID = p.ID - GROUP BY p.CATEGORY - template-tags: {} + stages: + - "lib/type": mbql.stage/native + native: |- + SELECT + p.CATEGORY, + COUNT(DISTINCT o.ID) AS order_count, + SUM(o.TOTAL) AS total_revenue, + AVG(o.TOTAL) AS avg_order_value + FROM ORDERS o + JOIN PRODUCTS p ON o.PRODUCT_ID = p.ID + GROUP BY p.CATEGORY target: database: Sample Database type: table diff --git a/examples/v1/collections/transforms/product_summary.yaml b/examples/v1/collections/transforms/product_summary.yaml index bdbde40..36478a6 100644 --- a/examples/v1/collections/transforms/product_summary.yaml +++ b/examples/v1/collections/transforms/product_summary.yaml @@ -5,29 +5,32 @@ source_database_id: Sample Database source: type: query query: + "lib/type": mbql/query database: Sample Database - type: query - query: - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - aggregation: - - - count - - - avg + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + aggregation: + - - count + - {} + - - avg + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - PRODUCTS + - PRICE + breakout: - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - - PRICE - - base-type: type/Float - breakout: - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - null + - CATEGORY target: database: Sample Database type: table diff --git a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/avg_revenue_per_order.yaml b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/avg_revenue_per_order.yaml index a07e9ec..6299fba 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/avg_revenue_per_order.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/avg_revenue_per_order.yaml @@ -7,21 +7,23 @@ table_id: - PUBLIC - ORDERS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float serdes/meta: - id: dc8eiyLh9S0IKwV_UuvTz label: avg_revenue_per_order diff --git a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/median_order_total.yaml b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/median_order_total.yaml index 7a94b9a..d70331f 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/median_order_total.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/median_order_total.yaml @@ -6,21 +6,23 @@ table_id: - PUBLIC - ORDERS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - median + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float serdes/meta: - id: d4G5fMj5smJ17Nd0dvE2A label: median_order_total diff --git a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/order_count.yaml b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/order_count.yaml index ce83069..fe0ccfa 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/order_count.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/order_count.yaml @@ -6,15 +6,17 @@ table_id: - PUBLIC - ORDERS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - count + - {} serdes/meta: - id: DBap2523KuN4Lt-cYrUjF label: order_count diff --git a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/total_revenue.yaml b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/total_revenue.yaml index d67c22e..f607245 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/total_revenue.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/orders/measures/total_revenue.yaml @@ -6,21 +6,23 @@ table_id: - PUBLIC - ORDERS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float serdes/meta: - id: 8WteUpyQQqObrxLv4KQ-j label: total_revenue diff --git a/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml b/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml index d2d55b3..0f25df4 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml @@ -6,21 +6,23 @@ table_id: - PUBLIC - ORDERS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS filter: - ">" + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float - 50 serdes/meta: - id: OaFXAvEzPvu9ZXW5PUMRa diff --git a/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml b/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml index 491ca39..4088ba0 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml @@ -7,27 +7,29 @@ table_id: - PUBLIC - PEOPLE definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PEOPLE filter: - inside + - {} - - field + - {} - - Sample Database - PUBLIC - PEOPLE - LATITUDE - - null - - field + - {} - - Sample Database - PUBLIC - PEOPLE - LONGITUDE - - null - 40.92 - -74.26 - 40.49 diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/average_product_price.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/average_product_price.yaml index a70bd9f..4699561 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/average_product_price.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/average_product_price.yaml @@ -6,21 +6,23 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS aggregation: - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - PRODUCTS - PRICE - - base-type: type/Float serdes/meta: - id: mSrAvgProdPrice00008x label: average_product_price diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_product_price.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_product_price.yaml index 4630e37..170929c 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_product_price.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_product_price.yaml @@ -6,21 +6,23 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS aggregation: - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - PRODUCTS - PRICE - - base-type: type/Float serdes/meta: - id: xK7mPqR2sT4uVwXyZ9a1b label: avg_product_price diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_widget_price.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_widget_price.yaml index 9a2fc37..452efff 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_widget_price.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/avg_widget_price.yaml @@ -7,21 +7,23 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS aggregation: - - avg + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - PRODUCTS - PRICE - - base-type: type/Float serdes/meta: - id: K7cMzOau9SI2h8hCx936w label: avg_widget_price diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/product_count.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/product_count.yaml index 9899b38..e8b2581 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/measures/product_count.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/measures/product_count.yaml @@ -6,21 +6,23 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS aggregation: - - distinct + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - ID - - null serdes/meta: - id: 8kxQ2Wr7PmN5dLf3hYz9v label: product_count diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml index 9e88678..d998b0c 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml @@ -7,24 +7,28 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS filter: - and + - {} - - segment + - {} - aB3kLmN9pQrStUvWxYz1a - - ">" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null - 50 serdes/meta: - id: 2hxhoN3HrQJIaWc5umpBn diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml index b58ae00..9f9d14a 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml @@ -7,48 +7,55 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS filter: - and + - {} - - between + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null - 20 - 100 - - not-null + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - RATING - - null - - time-interval + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CREATED_AT - - null - -1 - year - - not + - {} - - is-null + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - VENDOR - - null serdes/meta: - id: wdYkSSArR5ymVGa0pvb47 label: recent_midrange diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml index 5694fea..fdb6a8c 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml @@ -7,55 +7,60 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS filter: - and + - {} - - not-empty + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - - contains + - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - awesome - - case-sensitive: false - - starts-with + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - VENDOR - - null - A - - does-not-contain + - case-sensitive: false - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null - discontinued - - case-sensitive: false - - ends-with + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - EAN - - null - "0" serdes/meta: - id: yZptbJRR3S8L9S9r0ZF8M diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml index fd81c60..54381cc 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml @@ -6,21 +6,23 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS filter: - = + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - Widget serdes/meta: - id: aB3kLmN9pQrStUvWxYz1a From e5b8e4b744b2c15a6d69bb78db5ef8fdf1b0b661 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 18:36:09 -0400 Subject: [PATCH 02/15] fixes --- core-spec/v1/schemas/common/query.yaml | 242 ++++------ core-spec/v1/schemas/common/ref.yaml | 155 +++---- core-spec/v1/spec.md | 427 ++++++++++-------- .../marketing_analytics/product_overview.yaml | 4 +- .../main/queries/arithmetic_expressions.yaml | 20 +- .../main/queries/basic_aggregations.yaml | 8 +- .../main/queries/conditional_and_type.yaml | 33 +- .../main/queries/math_functions.yaml | 40 +- .../main/queries/string_functions.yaml | 55 +-- .../main/queries/temporal_expressions.yaml | 44 +- .../main/queries/temporal_extraction.yaml | 80 ++-- .../main/queries/url_functions.yaml | 20 +- package.json | 2 +- 13 files changed, 532 insertions(+), 598 deletions(-) diff --git a/core-spec/v1/schemas/common/query.yaml b/core-spec/v1/schemas/common/query.yaml index d4c510c..d9a210f 100644 --- a/core-spec/v1/schemas/common/query.yaml +++ b/core-spec/v1/schemas/common/query.yaml @@ -18,19 +18,71 @@ properties: $ref: "id.yaml#/$defs/database_id" stages: type: array - description: > - Flat list of query stages. The first stage must have a source - (source-table or source-card for MBQL, native for native). - Subsequent stages build on the previous stage's output. minItems: 1 items: $ref: "#/$defs/stage" $defs: - stage: + options: description: > - A query stage — either MBQL structured or native SQL. - Dispatches on lib/type. + Base options object for pMBQL clauses. Always present as the second + element of every clause array. Empty {} when no options apply. + type: object + properties: + base-type: + type: string + effective-type: + type: string + "lib/uuid": + type: string + format: uuid + "lib/expression-name": + type: string + + case_sensitive_options: + description: Options for string filter operators. + allOf: + - $ref: "#/$defs/options" + - type: object + properties: + case-sensitive: { type: boolean } + + time_interval_options: + description: Options for the time-interval operator. + allOf: + - $ref: "#/$defs/options" + - type: object + properties: + include-current: { type: boolean } + + aggregation_naming_options: + description: Options for aggregation-options (custom display name / name). + allOf: + - $ref: "#/$defs/options" + - type: object + properties: + display-name: { type: string } + name: { type: string } + + case_if_options: + description: Options for case/if operators. + allOf: + - $ref: "#/$defs/options" + - type: object + properties: + default: { $ref: "#/$defs/expression" } + + datetime_parse_options: + description: Options for the datetime parsing operator. + allOf: + - $ref: "#/$defs/options" + - type: object + properties: + mode: + type: string + enum: [iso, simple, unix-seconds, unix-milliseconds, unix-microseconds, unix-nanoseconds, iso-bytes, simple-bytes] + + stage: type: object required: - "lib/type" @@ -54,67 +106,44 @@ $defs: mbql_stage: type: object - description: > - An MBQL structured query stage. The first stage in a query must have - either source-table or source-card. Subsequent stages have neither. properties: "lib/type": const: mbql.stage/mbql source-table: - description: > - Table FK array [database, schema, table] for physical tables. - Only valid in the first stage. Mutually exclusive with source-card. $ref: "id.yaml#/$defs/table_id" source-card: - description: > - Card entity_id for saved questions/models. - Only valid in the first stage. Mutually exclusive with source-table. $ref: "id.yaml#/$defs/entity_id" joins: type: array - description: Join clauses items: $ref: "#/$defs/join" expressions: - type: object - description: > - Named computed columns. Keys are column names, values are MBQL - expression clauses. - additionalProperties: + type: array + items: $ref: "#/$defs/expression" filter: - description: > - Filter clause. Either a single comparison [op, {}, field, value] - or a compound filter [and, {}, ...clauses]. $ref: "#/$defs/expression" aggregation: type: array - description: > - Aggregation clauses. Each clause is [function, {}, ...args]. items: $ref: "#/$defs/expression" breakout: type: array - description: Breakout (GROUP BY) clauses items: $ref: "#/$defs/expression" order-by: type: array - description: > - Order-by clauses. Each is [direction, {}, expression]. items: $ref: "#/$defs/expression" limit: type: - integer - "null" - description: Row limit expression: description: > - An MBQL expression clause (recursive). Either a literal value or - an array [operator, options, ...args] where options is always an - object (empty {} when no options apply, never null). + An MBQL expression clause. Either a literal value or an array + [operator, options, ...args] where options is always an object. oneOf: - type: string - type: number @@ -123,7 +152,6 @@ $defs: - type: array minItems: 1 allOf: - # --- References --- - if: { prefixItems: [{ const: field }] } then: $ref: "ref.yaml#/$defs/field_ref" @@ -142,30 +170,27 @@ $defs: - if: { prefixItems: [{ const: segment }] } then: $ref: "ref.yaml#/$defs/segment_ref" - # --- Value literal --- - if: { prefixItems: [{ const: value }] } then: prefixItems: - const: value - - type: object - - {} + - $ref: "#/$defs/options" + - type: [string, number, boolean] minItems: 3 maxItems: 3 - # --- Arithmetic --- - if: { prefixItems: [{ enum: ["+", "-", "*", "/"] }] } then: prefixItems: - enum: ["+", "-", "*", "/"] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } minItems: 3 - # --- Logical --- - if: { prefixItems: [{ enum: [and, or] }] } then: prefixItems: - enum: [and, or] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } @@ -174,16 +199,15 @@ $defs: then: prefixItems: - const: not - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 - # --- Comparison --- - if: { prefixItems: [{ enum: ["=", "!=", "<", ">", "<=", ">="] }] } then: prefixItems: - enum: ["=", "!=", "<", ">", "<=", ">="] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } @@ -192,7 +216,7 @@ $defs: then: prefixItems: - enum: [in, not-in] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } @@ -201,7 +225,7 @@ $defs: then: prefixItems: - const: between - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" @@ -211,7 +235,7 @@ $defs: then: prefixItems: - const: inside - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - { type: number } @@ -220,19 +244,14 @@ $defs: - { type: number } minItems: 8 maxItems: 8 - # --- Null/empty --- - if: { prefixItems: [{ enum: [is-null, not-null, is-empty, not-empty] }] } then: prefixItems: - enum: [is-null, not-null, is-empty, not-empty] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 - # --- String filters --- - # Options always in position 2 (second argument). - # 2 value args: [op, {options}, field, value] - # 3+ value args: [op, {options}, field, value, value, ...] - if: { prefixItems: [{ enum: [contains, does-not-contain, starts-with, ends-with] }] } then: prefixItems: @@ -242,12 +261,11 @@ $defs: - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } minItems: 4 - # --- Temporal filters --- - if: { prefixItems: [{ const: time-interval }] } then: prefixItems: - const: time-interval - - type: object + - $ref: "#/$defs/time_interval_options" - $ref: "#/$defs/expression" - if: { type: integer } then: { type: integer } @@ -259,7 +277,7 @@ $defs: then: prefixItems: - const: relative-time-interval - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - { type: integer } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" @@ -267,32 +285,29 @@ $defs: - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" minItems: 7 maxItems: 7 - # --- Nullary --- - if: { prefixItems: [{ enum: [now, today] }] } then: prefixItems: - enum: [now, today] - - type: object + - $ref: "#/$defs/options" minItems: 2 maxItems: 2 - # --- Interval --- - if: { prefixItems: [{ const: interval }] } then: prefixItems: - const: interval - - type: object + - $ref: "#/$defs/options" - { type: integer } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" minItems: 4 maxItems: 4 - # --- Unary functions --- - if: prefixItems: - enum: [abs, ceil, floor, round, sqrt, exp, log, length, trim, ltrim, rtrim, upper, lower, host, domain, subdomain, path, get-year, get-quarter, get-month, get-day, get-hour, get-minute, get-second, text, integer, float, day-name, month-name, quarter-name, date] then: prefixItems: - enum: [abs, ceil, floor, round, sqrt, exp, log, length, trim, ltrim, rtrim, upper, lower, host, domain, subdomain, path, get-year, get-quarter, get-month, get-day, get-hour, get-minute, get-second, text, integer, float, day-name, month-name, quarter-name, date] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 @@ -300,30 +315,24 @@ $defs: then: prefixItems: - const: datetime - - type: object - properties: - mode: - type: string - enum: [iso, simple, unix-seconds, unix-milliseconds, unix-microseconds, unix-nanoseconds, iso-bytes, simple-bytes] + - $ref: "#/$defs/datetime_parse_options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 - # --- Week mode functions --- - if: { prefixItems: [{ enum: [get-day-of-week, get-week] }] } then: prefixItems: - enum: [get-day-of-week, get-week] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - { type: string, enum: [iso, us, instance] } minItems: 3 maxItems: 4 - # --- Binary/ternary --- - if: { prefixItems: [{ const: power }] } then: prefixItems: - const: power - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" minItems: 4 @@ -332,7 +341,7 @@ $defs: then: prefixItems: - enum: [replace, split-part] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" @@ -342,7 +351,7 @@ $defs: then: prefixItems: - const: substring - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" @@ -352,7 +361,7 @@ $defs: then: prefixItems: - const: collate - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - { type: string } minItems: 4 @@ -361,17 +370,16 @@ $defs: then: prefixItems: - const: regex-match-first - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - { type: string } minItems: 4 maxItems: 4 - # --- Variadic --- - if: { prefixItems: [{ const: concat }] } then: prefixItems: - const: concat - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } @@ -380,17 +388,16 @@ $defs: then: prefixItems: - const: coalesce - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" items: { $ref: "#/$defs/expression" } minItems: 4 - # --- Datetime --- - if: { prefixItems: [{ enum: [datetime-add, datetime-subtract] }] } then: prefixItems: - enum: [datetime-add, datetime-subtract] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - { type: integer } - $ref: "temporal_bucketing.yaml#/$defs/datetime_truncation_unit" @@ -400,7 +407,7 @@ $defs: then: prefixItems: - const: datetime-diff - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" - $ref: "#/$defs/datetime_diff_unit" @@ -410,7 +417,7 @@ $defs: then: prefixItems: - const: convert-timezone - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - { type: string } - { type: string } @@ -420,18 +427,17 @@ $defs: then: prefixItems: - const: temporal-extract - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "temporal_bucketing.yaml#/$defs/datetime_extraction_unit" - { type: string, enum: [iso, us, instance] } minItems: 4 maxItems: 5 - # --- Aggregations --- - if: { prefixItems: [{ enum: [count, cum-count] }] } then: prefixItems: - enum: [count, cum-count] - - type: object + - $ref: "#/$defs/options" items: { $ref: "#/$defs/expression" } minItems: 2 maxItems: 3 @@ -439,7 +445,7 @@ $defs: then: prefixItems: - enum: [sum, avg, min, max, distinct, stddev, var, median, cum-sum] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 @@ -447,7 +453,7 @@ $defs: then: prefixItems: - const: percentile - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - { type: number } minItems: 4 @@ -456,7 +462,7 @@ $defs: then: prefixItems: - enum: [count-where, share] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 @@ -464,7 +470,7 @@ $defs: then: prefixItems: - enum: [sum-where, distinct-where] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - $ref: "#/$defs/expression" minItems: 4 @@ -473,21 +479,15 @@ $defs: then: prefixItems: - const: aggregation-options - - type: object - properties: - display-name: { type: string } - name: { type: string } + - $ref: "#/$defs/aggregation_naming_options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 - # --- Case/if --- - if: { prefixItems: [{ enum: [case, if] }] } then: prefixItems: - enum: [case, if] - - type: object - properties: - default: { $ref: "#/$defs/expression" } + - $ref: "#/$defs/case_if_options" - type: array items: type: array @@ -496,41 +496,30 @@ $defs: maxItems: 2 minItems: 3 maxItems: 3 - # --- Offset --- - if: { prefixItems: [{ const: offset }] } then: prefixItems: - const: offset - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" - type: integer minItems: 4 maxItems: 4 - # --- Order-by direction --- - if: { prefixItems: [{ enum: [asc, desc] }] } then: prefixItems: - enum: [asc, desc] - - type: object + - $ref: "#/$defs/options" - $ref: "#/$defs/expression" minItems: 3 maxItems: 3 - case_sensitive_options: - type: object - properties: - case-sensitive: { type: boolean } - datetime_diff_unit: - description: Units for datetime-diff (no millisecond). type: string enum: [second, minute, hour, day, week, month, quarter, year] join: type: object - description: > - A join clause. In pMBQL, joins have their own stages array - instead of source-table/source-query. required: - stages - conditions @@ -538,33 +527,24 @@ $defs: properties: stages: type: array - description: > - Query stages for the joined data source. The first stage - must have source-table or source-card. minItems: 1 items: $ref: "#/$defs/stage" conditions: type: array - description: Join conditions as MBQL expression clauses minItems: 1 items: $ref: "#/$defs/expression" alias: type: string - description: Join alias for referencing joined columns strategy: type: string - description: Join strategy enum: - left-join - right-join - inner-join - full-join fields: - description: > - Which fields to include from the joined table. "all" for all, - "none" for none, or an array of field reference clauses. if: { type: string } then: { enum: [all, none] } else: @@ -574,7 +554,6 @@ $defs: native_stage: type: object - description: A native SQL query stage. required: - "lib/type" - native @@ -583,18 +562,13 @@ $defs: const: mbql.stage/native native: type: string - description: SQL query string, may contain {{tag}} placeholders template-tags: type: object - description: > - Template tag definitions. Keys match {{tag}} placeholders in the - SQL query string. additionalProperties: $ref: "#/$defs/template_tag" template_tag: type: object - description: A template tag for parameterizing native SQL queries. required: - type - name @@ -602,7 +576,6 @@ $defs: properties: type: type: string - description: Tag type enum: - text - number @@ -615,19 +588,15 @@ $defs: - table name: type: string - description: Tag name (matches the {{name}} placeholder) id: type: string - description: UUID identifier format: uuid display-name: type: string - description: Human-readable label default: description: Default value (type depends on tag type) required: type: boolean - description: Whether a value is required allOf: - if: properties: @@ -636,17 +605,13 @@ $defs: required: [dimension, widget-type] properties: dimension: - description: Field reference $ref: "#/$defs/expression" widget-type: type: string - description: Filter widget type (e.g., string/=, date/range) options: type: object - description: Options for generated filter clause (e.g., case-sensitive) alias: type: string - description: SQL column identifier used inside the generated expression (e.g., the column in DATE_TRUNC(unit, column)) - if: properties: type: { const: temporal-unit } @@ -654,11 +619,9 @@ $defs: required: [dimension] properties: dimension: - description: Field reference — the temporal column to group $ref: "#/$defs/expression" alias: type: string - description: SQL column identifier used inside the generated expression (e.g., the column in DATE_TRUNC(unit, column)) - if: properties: type: { const: card } @@ -666,7 +629,6 @@ $defs: required: [card-id] properties: card-id: - description: Card entity_id of the referenced card $ref: "id.yaml#/$defs/entity_id" - if: properties: @@ -676,9 +638,7 @@ $defs: properties: snippet-name: type: string - description: Snippet name snippet-id: - description: Snippet entity_id $ref: "id.yaml#/$defs/entity_id" - if: properties: @@ -687,8 +647,6 @@ $defs: required: [table-id] properties: table-id: - description: Table FK $ref: "id.yaml#/$defs/table_id" emit-alias: type: boolean - description: Whether to emit the table name as an alias diff --git a/core-spec/v1/schemas/common/ref.yaml b/core-spec/v1/schemas/common/ref.yaml index bd04bd1..7c484d8 100644 --- a/core-spec/v1/schemas/common/ref.yaml +++ b/core-spec/v1/schemas/common/ref.yaml @@ -2,153 +2,112 @@ $schema: https://json-schema.org/draft/2020-12/schema title: Ref description: > Column and entity reference types used in MBQL expressions, - parameter mappings, and visualization settings. In pMBQL format, - options are always the second element (an object, never null). + parameter mappings, and visualization settings. Options are always + the second element (an object, never null). $defs: - base_type_options: - description: Options with only base-type hint. - type: object - properties: - base-type: - type: string - description: Base type hint (e.g., type/Float, type/Integer) - field_options: - description: Full field options (only valid on field refs). - type: object - properties: - base-type: - type: string - description: Base type hint (e.g., type/Float, type/Integer) - temporal-unit: - $ref: "temporal_bucketing.yaml#/$defs/datetime_bucketing_unit" - join-alias: - type: string - description: Alias of the join this field belongs to - binning: - type: object - description: > - Binning strategy: {strategy: num-bins, num-bins: N}, - {strategy: bin-width, bin-width: N}, or {strategy: default}. - required: - - strategy + description: Options for field refs. + allOf: + - $ref: "query.yaml#/$defs/options" + - type: object properties: - strategy: + temporal-unit: + $ref: "temporal_bucketing.yaml#/$defs/datetime_bucketing_unit" + join-alias: + type: string + binning: + type: object + required: + - strategy + properties: + strategy: + type: string + enum: [default, num-bins, bin-width] + allOf: + - if: + properties: + strategy: { const: bin-width } + then: + required: [bin-width] + properties: + bin-width: + type: number + exclusiveMinimum: 0 + - if: + properties: + strategy: { const: num-bins } + then: + required: [num-bins] + properties: + num-bins: + type: integer + minimum: 1 + source-field: + $ref: "id.yaml#/$defs/field_id" + source-field-name: + type: string + source-field-join-alias: type: string - enum: [default, num-bins, bin-width] - allOf: - - if: - properties: - strategy: { const: bin-width } - then: - required: [bin-width] - properties: - bin-width: - type: number - exclusiveMinimum: 0 - - if: - properties: - strategy: { const: num-bins } - then: - required: [num-bins] - properties: - num-bins: - type: integer - minimum: 1 - source-field: - description: FK field reference for implicit joins - $ref: "id.yaml#/$defs/field_id" - source-field-name: - type: string - description: FK field name for implicit joins in nested queries - source-field-join-alias: - type: string - description: Join alias when FK table is explicitly joined field_ref: - description: > - Field reference: [field, options, Field-FK-or-name]. - Options is always an object (empty {} when no options). - Field FK is [database, schema, table, field, ...] (4+ elements for JSON paths). - For subsequent stages, the third element is a column name string. + description: "[field, options, Field-FK-or-name]" type: array prefixItems: - const: field - - type: object - $ref: "#/$defs/field_options" - - description: Field FK (array) or column name (string, for subsequent stages) - if: { type: array } + - $ref: "#/$defs/field_options" + - if: { type: array } then: { $ref: "id.yaml#/$defs/field_id" } minItems: 3 maxItems: 3 expression_ref: - description: > - Expression reference: [expression, options, name]. - Options is always an object (empty {} when no options). + description: "[expression, options, name]" type: array prefixItems: - const: expression - - type: object - $ref: "#/$defs/base_type_options" + - $ref: "query.yaml#/$defs/options" - type: string - description: Expression name minItems: 3 maxItems: 3 aggregation_ref: - description: > - Aggregation reference: [aggregation, options, index]. - Options is always an object (empty {} when no options). + description: "[aggregation, options, uuid] — uuid matches the lib/uuid on the aggregation clause" type: array prefixItems: - const: aggregation - - type: object - $ref: "#/$defs/base_type_options" - - type: integer - description: Aggregation index (0-based) + - $ref: "query.yaml#/$defs/options" + - type: string + format: uuid minItems: 3 maxItems: 3 metric_ref: - description: > - Metric reference: [metric, options, entity_id]. - Options is always an object (empty {} when no options). + description: "[metric, options, entity_id]" type: array prefixItems: - const: metric - - type: object - $ref: "#/$defs/base_type_options" + - $ref: "query.yaml#/$defs/options" - type: string - description: Metric card entity_id minItems: 3 maxItems: 3 measure_ref: - description: > - Measure reference: [measure, options, entity_id]. - Options is always an object (empty {} when no options). + description: "[measure, options, entity_id]" type: array prefixItems: - const: measure - - type: object - $ref: "#/$defs/base_type_options" + - $ref: "query.yaml#/$defs/options" - type: string - description: Measure entity_id minItems: 3 maxItems: 3 segment_ref: - description: > - Segment reference: [segment, options, entity_id]. - Options is always an object (empty {} when no options). + description: "[segment, options, entity_id]" type: array prefixItems: - const: segment - - type: object - $ref: "#/$defs/base_type_options" + - $ref: "query.yaml#/$defs/options" - type: string - description: Segment entity_id minItems: 3 maxItems: 3 diff --git a/core-spec/v1/spec.md b/core-spec/v1/spec.md index b9290a6..d311e1c 100644 --- a/core-spec/v1/spec.md +++ b/core-spec/v1/spec.md @@ -172,9 +172,10 @@ MBQL (Metabase Query Language) queries are constructed via the graphical query e ### Structure ```yaml +"lib/type": mbql/query database: Sample Database # Database FK -type: query -query: +stages: +- "lib/type": mbql.stage/mbql source-table: # Table FK - Sample Database - PUBLIC @@ -185,9 +186,7 @@ This is equivalent to `SELECT * FROM PUBLIC.PRODUCTS`. ### Source Table -`source-table` specifies the primary data source. It can be either a **Table FK** (array) for physical tables, or a **Card entity_id** (string) for saved questions and models. - -**Physical table:** +`source-table` specifies a physical table as the data source using a **Table FK** (array). ```yaml source-table: @@ -196,50 +195,55 @@ source-table: - PRODUCTS ``` -**Saved card/model as source:** +### Source Card -When `source-table` is a string (NanoID), it references a saved card. Fields from the card's results are referenced by column name (string) rather than a Field FK: +`source-card` specifies a saved card (question or model) as the data source using its **Card entity_id** (string). Fields from the card's results are referenced by column name (string) rather than a Field FK: ```yaml +"lib/type": mbql/query database: Sample Database -type: query -query: - source-table: f1C68pznmrpN1F5xFDj6d # entity_id of a saved card +stages: +- "lib/type": mbql.stage/mbql + source-card: f1C68pznmrpN1F5xFDj6d # entity_id of a saved card filter: - ">" + - {} - - field - - PRICE - base-type: type/Float + - PRICE - 50 ``` -### Source Query (nested queries) +### Stages (multi-stage queries) -A query can use another MBQL query as its source instead of a table. The inner query has the same structure as a regular MBQL query. Fields from the inner query's results are referenced by column name (string) rather than a Field FK. Nested queries can be stacked to arbitrary depth. +A query can have multiple stages, where each stage operates on the results of the previous one. Stages are a flat array — there is no nesting. Fields from a previous stage's results are referenced by column name (string) rather than a Field FK. Stages can be stacked to arbitrary depth. ```yaml +"lib/type": mbql/query database: Sample Database -type: query -query: - source-query: - source-table: - - Sample Database - - PUBLIC - - ORDERS - aggregation: - - - count - breakout: - - - field - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT - - temporal-unit: month +stages: +- "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + aggregation: + - - count + - "lib/uuid": 11111111-1111-1111-1111-111111111111 + breakout: + - - field + - temporal-unit: month + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT +- "lib/type": mbql.stage/mbql filter: - ">" + - {} - - field - - count - base-type: type/Integer + - count - 10 ``` @@ -247,18 +251,18 @@ This is equivalent to `SELECT * FROM (SELECT DATE_TRUNC('month', CREATED_AT), CO ### Field References -Fields are referenced using a `field` clause with a Field FK: +Fields are referenced using a `field` clause with options as the second argument and a Field FK as the third: ```yaml - field +- {} # field options (always a map, never null) - - Sample Database # database name - PUBLIC # schema (null for schemaless) - ORDERS # table name - TOTAL # field name -- null # field options (see below) ``` -Field options (second argument) can be `null` or a map: +Field options (second argument) is always a map (use `{}` when no options are needed): | Option | Type | Description | |--------|------|-------------| @@ -267,7 +271,7 @@ Field options (second argument) can be `null` or a map: | `join-alias` | string | Alias of the join this field belongs to | | `binning` | map | Binning strategy (see [Binning](#binning)) | | `source-field` | array | Implicit join: FK field reference in the source table (see below) | -| `source-field-name` | string | Implicit join: FK field by name, for nested queries | +| `source-field-name` | string | Implicit join: FK field by name, for multi-stage queries | | `source-field-join-alias` | string | Implicit join: join-alias when the FK table is explicitly joined | #### Implicit Joins @@ -279,89 +283,94 @@ Use `source-field` to specify the FK field in the source table that links to the ```yaml # Get PRODUCTS.TITLE via ORDERS.PRODUCT_ID (implicit join) - field -- - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - source-field: - Sample Database - PUBLIC - ORDERS - PRODUCT_ID +- - Sample Database + - PUBLIC + - PRODUCTS + - TITLE ``` The `source-field` value is a raw Field FK (`[database, schema, table, field]`), not a field clause. -For **nested queries** (when `source-query` or `source-table` is a card entity_id), additionally set `source-field-name` to reference the FK column by its string name in the inner query's results. This is needed when the source query returns multiple fields that are both the same FK: +For **multi-stage queries** (when `source-card` is set), additionally set `source-field-name` to reference the FK column by its string name in the previous stage's results. This is needed when the source query returns multiple fields that are both the same FK: ```yaml - field -- - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - source-field: - Sample Database - PUBLIC - ORDERS - PRODUCT_ID source-field-name: PRODUCT_ID +- - Sample Database + - PUBLIC + - PRODUCTS + - TITLE ``` When the source (FK) table is itself joined via an explicit `joins` clause, use `source-field-join-alias` to disambiguate which join the FK field comes from. The value must match the `alias` of the corresponding join: ```yaml - field -- - Sample Database - - PUBLIC - - PRODUCTS - - TITLE - source-field: - Sample Database - PUBLIC - ORDERS - PRODUCT_ID source-field-join-alias: Joined Orders +- - Sample Database + - PUBLIC + - PRODUCTS + - TITLE ``` Expression references use the `expression` keyword: ```yaml - expression +- {} - Profit ``` -Aggregation references use the `aggregation` keyword with the aggregation index: +Aggregation references use the `aggregation` keyword with a UUID that matches the `lib/uuid` of the referenced aggregation clause: ```yaml - aggregation -- 0 # index of the aggregation clause +- {} +- "11111111-1111-1111-1111-111111111111" ``` ### Joins -Joins combine data from multiple tables: +Joins combine data from multiple tables. Each join has its own `stages` array (defining the joined data source) and a `conditions` array (one or more join conditions): ```yaml joins: -- source-table: - - Sample Database - - PUBLIC - - PRODUCTS - condition: - - = - - - field - - - Sample Database - - PUBLIC - - ORDERS - - PRODUCT_ID - - null - - - field - - - Sample Database - - PUBLIC - - PRODUCTS - - ID - - null +- stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + conditions: + - - = + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - PRODUCT_ID + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - ID alias: Products strategy: left-join fields: all @@ -369,8 +378,8 @@ joins: | Property | Type | Required | Description | |----------|------|----------|-------------| -| `source-table` | array | Yes | Table FK of the joined table | -| `condition` | array | Yes | Join condition as a filter clause | +| `stages` | array | Yes | Array of stage objects defining the joined data source | +| `conditions` | array | Yes | Array of join conditions, each a filter clause | | `alias` | string | Yes | Join alias (used in field references) | | `strategy` | string | Yes | `"left-join"`, `"right-join"`, `"inner-join"`, `"full-join"` | | `fields` | any | No | `"all"`, `"none"`, or list of field clauses | @@ -379,33 +388,33 @@ Joined fields are referenced with a `join-alias` option: ```yaml - field +- join-alias: Products - - Sample Database - PUBLIC - PRODUCTS - TITLE -- join-alias: Products ``` ### Expressions -Computed columns defined as named clauses in an `expressions` map: +Computed columns defined as an array of clauses. Each expression operator's options map includes `lib/expression-name` to name the resulting column: ```yaml expressions: - Profit: - - - +- - "-" + - "lib/expression-name": Profit - - field + - {} - - Sample Database - PUBLIC - ORDERS - TOTAL - - null - - field + - {} - - Sample Database - PUBLIC - ORDERS - TAX - - null ``` See [Expression Operators](#expression-operators) for the full operator reference. @@ -417,6 +426,7 @@ Filters restrict which rows are included: ```yaml filter: - +- {} - - ``` @@ -426,21 +436,24 @@ Compound filters use `and` / `or` / `not`: ```yaml filter: - and +- {} - - ">=" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null - 10 - - "<" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null - 100 ``` @@ -448,18 +461,20 @@ See [Filter Operators](#filter-operators) for the full operator reference. ### Aggregations -Aggregations compute summary values. Multiple aggregations can be combined: +Aggregations compute summary values. Multiple aggregations can be combined. When an aggregation is referenced elsewhere (e.g., in `order-by` or a later stage), its options map must include a `lib/uuid`: ```yaml aggregation: - - count + - {} - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float ``` See [Aggregation Functions](#aggregation-functions) for the full reference. @@ -471,11 +486,11 @@ Breakouts group results by columns (like `GROUP BY`): ```yaml breakout: - - field + - temporal-unit: month - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - temporal-unit: month ``` ### Order By @@ -483,21 +498,24 @@ breakout: ```yaml order-by: - - asc # "asc" or "desc" + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - - null ``` -Sort by aggregation result: +Sort by aggregation result (using the UUID from the aggregation's `lib/uuid`): ```yaml order-by: - - desc + - {} - - aggregation - - 0 + - {} + - "11111111-1111-1111-1111-111111111111" ``` ### Limit @@ -518,14 +536,14 @@ The `temporal-unit` field option groups a datetime column into time buckets. Thi # Breakout by month breakout: - - field - - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - temporal-unit: month + - [Sample Database, PUBLIC, ORDERS, CREATED_AT] # Breakout by day of week breakout: - - field - - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - temporal-unit: day-of-week + - [Sample Database, PUBLIC, ORDERS, CREATED_AT] ``` Bucketing units truncate the datetime (e.g., `month` groups `2024-03-15` into `2024-03-01`). Extraction units extract a numeric component (e.g., `day-of-week` returns 1–7). @@ -546,18 +564,18 @@ Three strategies are available: # 10 equal bins breakout: - - field - - [Sample Database, PUBLIC, PRODUCTS, PRICE] - binning: strategy: num-bins num-bins: 10 + - [Sample Database, PUBLIC, PRODUCTS, PRICE] # Bins of width 25 breakout: - - field - - [Sample Database, PUBLIC, PRODUCTS, PRICE] - binning: strategy: bin-width bin-width: 25 + - [Sample Database, PUBLIC, PRODUCTS, PRICE] ``` --- @@ -575,15 +593,18 @@ breakout: ```yaml # AND - and +- {} - - ">" + - {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, PRICE] - - null - 50 - - "!=" + - {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, CATEGORY] - - null - Doohickey ``` @@ -603,36 +624,40 @@ breakout: ```yaml # Equals - = +- {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, CATEGORY] - - null - Widget # Multi-value equals (IN) - = +- {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, CATEGORY] - - null - Widget - Gadget - Gizmo # Between - between +- {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, PRICE] - - null - 10 - 100 # Inside (bounding box) - inside +- {} - - field + - {} - [Sample Database, PUBLIC, PEOPLE, LATITUDE] - - null - - field + - {} - [Sample Database, PUBLIC, PEOPLE, LONGITUDE] - - null - 40.8 # north latitude - -74.1 # west longitude - 40.6 # south latitude @@ -650,19 +675,21 @@ breakout: ```yaml - is-null +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, DISCOUNT] - - null - not-empty +- {} - - field + - {} - [Sample Database, PUBLIC, PEOPLE, EMAIL] - - null ``` #### String -All string filter operators accept a `case-sensitive` option (default: `true`). They are N-ary — multiple values are combined with OR. When multiple values are present, the options map goes in the **second position** (after the operator, before the field). +All string filter operators accept a `case-sensitive` option (default: `true`). They are N-ary — multiple values are combined with OR. The options map is always in the **second position** (after the operator, before the field). | Operator | Arguments | Description | |----------|-----------|-------------| @@ -672,20 +699,20 @@ All string filter operators accept a `case-sensitive` option (default: `true`). | `ends-with` | 2+ string values | Ends with suffix | ```yaml -# Single value, case-insensitive (options go last) +# Single value, case-insensitive - contains +- case-sensitive: false - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, TITLE] - - null - widget -- case-sensitive: false -# Multiple values (options map in second position, can be empty {}) +# Multiple values (empty options) - starts-with - {} - - field + - {} - [Sample Database, PUBLIC, PEOPLE, NAME] - - null - John - Jane @@ -693,8 +720,8 @@ All string filter operators accept a `case-sensitive` option (default: `true`). - starts-with - case-sensitive: false - - field + - {} - [Sample Database, PUBLIC, PEOPLE, NAME] - - null - John - Jane - Charlie @@ -712,25 +739,28 @@ All string filter operators accept a `case-sensitive` option (default: `true`). ```yaml # Last 30 days - time-interval +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null - -30 - day # Current month - time-interval +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null - current - month # Last 30 days, offset by 1 month - relative-time-interval +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null - -30 - day - -1 @@ -743,6 +773,7 @@ Reference a saved segment by entity_id: ```yaml - segment +- {} - aB3kLmN9pQrStUvWxYz1a ``` @@ -765,21 +796,25 @@ Reference a saved segment by entity_id: # Count all rows aggregation: - - count + - {} # Sum with field aggregation: - - sum + - {} - - field - - [Sample Database, PUBLIC, ORDERS, TOTAL] - base-type: type/Float + - [Sample Database, PUBLIC, ORDERS, TOTAL] # Multiple aggregations aggregation: - - count + - {} - - avg + - {} - - field - - [Sample Database, PUBLIC, ORDERS, TOTAL] - base-type: type/Float + - [Sample Database, PUBLIC, ORDERS, TOTAL] ``` #### Cumulative @@ -792,9 +827,10 @@ aggregation: ```yaml aggregation: - - cum-sum + - {} - - field - - [Sample Database, PUBLIC, ORDERS, TOTAL] - base-type: type/Float + - [Sample Database, PUBLIC, ORDERS, TOTAL] ``` #### Statistical @@ -810,9 +846,10 @@ aggregation: # 90th percentile aggregation: - - percentile + - {} - - field - - [Sample Database, PUBLIC, ORDERS, TOTAL] - base-type: type/Float + - [Sample Database, PUBLIC, ORDERS, TOTAL] - 0.9 ``` @@ -829,37 +866,42 @@ aggregation: # Count where aggregation: - - count-where + - {} - - ">" + - {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, TOTAL] - - null - 100 # Share aggregation: - - share + - {} - - = + - {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, CATEGORY] - - null - Widget ``` #### Named Aggregations -Aggregations can have a custom display name using the `aggregation-options` wrapper: +Aggregations can have a custom display name using the `aggregation-options` wrapper. The options map (with `display-name`) is the second argument, before the aggregation clause: ```yaml aggregation: - - aggregation-options + - display-name: Total Revenue - - sum + - {} - - field - - [Sample Database, PUBLIC, ORDERS, TOTAL] - base-type: type/Float - - display-name: Total Revenue + - [Sample Database, PUBLIC, ORDERS, TOTAL] ``` -The structure is `[aggregation-options, aggregation-clause, {display-name: "Name"}]`. +The structure is `[aggregation-options, {display-name: "Name"}, aggregation-clause]`. #### Metric and Measure References @@ -868,6 +910,7 @@ A `metric` clause references a saved metric (a card with `type: metric`) by its ```yaml aggregation: - - metric + - {} - f1C68pznmrpN1F5xFDj6d # entity_id of a metric card ``` @@ -876,6 +919,7 @@ A `measure` clause references a saved measure by its entity_id. Measures can ref ```yaml aggregation: - - measure + - {} - xK7mPqR2sT4uVwXyZ9a1b # entity_id of a saved measure ``` @@ -897,23 +941,24 @@ aggregation: ```yaml # Subtraction: TOTAL - TAX expressions: - Profit: - - "-" +- - "-" + - "lib/expression-name": Profit - - field + - {} - [Sample Database, PUBLIC, ORDERS, TOTAL] - - null - - field + - {} - [Sample Database, PUBLIC, ORDERS, TAX] - - null # Date arithmetic: CREATED_AT + 7 days expressions: - Due Date: - - + +- - + + - "lib/expression-name": Due Date - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null - - interval + - {} - 7 - day ``` @@ -934,22 +979,25 @@ expressions: ```yaml # Absolute value - abs +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, DISCOUNT] - - null # Power - power +- {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, RATING] - - null - 2 # Square root - sqrt +- {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, PRICE] - - null ``` #### String Functions @@ -975,43 +1023,48 @@ expressions: ```yaml # Concat - concat +- {} - - field + - {} - [Sample Database, PUBLIC, PEOPLE, NAME] - - null - " <" - - field + - {} - [Sample Database, PUBLIC, PEOPLE, EMAIL] - - null - ">" # Substring (characters 1-3) - substring +- {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, TITLE] - - null - 1 - 3 # Replace - replace +- {} - - field + - {} - [Sample Database, PUBLIC, PEOPLE, EMAIL] - - null - "@example.com" - "@company.com" # Regex match - regex-match-first +- {} - - field + - {} - [Sample Database, PUBLIC, PEOPLE, EMAIL] - - null - "^[^@]+" # Domain from URL - domain +- {} - - field + - {} - [Sample Database, PUBLIC, PEOPLE, SOURCE] - - null ``` #### Temporal Functions @@ -1048,31 +1101,36 @@ Extraction units for `temporal-extract`: `year-of-era`, `quarter-of-year`, `mont ```yaml # Add 7 days - datetime-add +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null - 7 - day # Difference in months - datetime-diff +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null - - now + - {} - month # Extract year - get-year +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null # Convert timezone - convert-timezone +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, CREATED_AT] - - null - America/New_York - UTC ``` @@ -1087,43 +1145,47 @@ Extraction units for `temporal-extract`: `year-of-era`, `quarter-of-year`, `mont ```yaml - integer +- {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, PRICE] - - null ``` #### Conditional | Operator | Arguments | Returns | Description | |----------|-----------|---------|-------------| -| `case` | pairs of [condition, value], optional default | value type | Conditional expression (if/then/else) | +| `case` | pairs of [condition, value] (default in options) | value type | Conditional expression (if/then/else) | | `if` | same as `case` | value type | Alias for `case` | | `coalesce` | 2+ expressions | first non-null type | First non-null value | ```yaml # Case expression expressions: - Price Tier: - - case +- - case + - "lib/expression-name": Price Tier + default: Standard - - - - ">" + - {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, PRICE] - - null - 100 - Premium - - - "<=" + - {} - - field + - {} - [Sample Database, PUBLIC, PRODUCTS, PRICE] - - null - 20 - Budget - - Standard # default value # Coalesce - coalesce +- {} - - field + - {} - [Sample Database, PUBLIC, ORDERS, DISCOUNT] - - null - 0 ``` @@ -1133,20 +1195,22 @@ Window functions can only be used inside the `aggregation` clause. | Operator | Arguments | Returns | Description | |----------|-----------|---------|-------------| -| `offset` | null, expression, n | same type | Value from n rows before (negative) or after (positive). Second element is always `null`. | +| `offset` | expression, n | same type | Value from n rows before (negative) or after (positive). | ```yaml aggregation: - - sum + - {} - - field - - [Sample Database, PUBLIC, ORDERS, TOTAL] - base-type: type/Float + - [Sample Database, PUBLIC, ORDERS, TOTAL] - - offset - - null + - {} - - sum + - {} - - field - - [Sample Database, PUBLIC, ORDERS, TOTAL] - base-type: type/Float + - [Sample Database, PUBLIC, ORDERS, TOTAL] - -1 ``` @@ -1159,10 +1223,11 @@ Native queries use plain SQL with Metabase template tags for dynamic values. ### Structure ```yaml +"lib/type": mbql/query database: Sample Database -type: native -native: - query: SELECT * FROM PRODUCTS +stages: +- "lib/type": mbql.stage/native + native: SELECT * FROM PRODUCTS template-tags: {} ``` @@ -1293,7 +1358,7 @@ When no value is provided, the entire `WHERE {{tag}}` clause is omitted (the que | Property | Type | Required | Description | |----------|------|----------|-------------| -| `dimension` | array | Yes | Field clause: `[field, Field FK, options]` (see [Field References](#field-references)) | +| `dimension` | array | Yes | Field clause: `[field, options, Field FK]` (see [Field References](#field-references)) | | `widget-type` | string | Yes | Filter widget type — any value from [Parameter Types](#parameter-types) | | `default` | any | No | Default filter value | | `required` | boolean | No | Whether a value must be provided | @@ -1310,11 +1375,11 @@ native: display-name: Category dimension: - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null widget-type: string/= default: null ``` @@ -1331,7 +1396,7 @@ A temporal grouping variable. Metabase replaces the tag with a `DATE_TRUNC(unit, | Property | Type | Required | Description | |----------|------|----------|-------------| -| `dimension` | array | Yes | Field clause: `[field, Field FK, options]` — the temporal column to group | +| `dimension` | array | Yes | Field clause: `[field, options, Field FK]` — the temporal column to group | | `default` | string | No | Default temporal unit (e.g., `month`) | | `alias` | string | No | Overrides the SQL column name used inside the generated expression. By default Metabase uses the column name from `dimension` (e.g., `CREATED_AT`). When the SQL uses a table alias, set `alias` to match so the generated expression references the correct name. | @@ -1349,11 +1414,11 @@ native: default: month dimension: - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null ``` Compiled SQL (value `month`): `SELECT DATE_TRUNC('month', CREATED_AT) AS created_at, COUNT(*) FROM ORDERS GROUP BY DATE_TRUNC('month', CREATED_AT)` @@ -1373,11 +1438,11 @@ native: alias: o.CREATED_AT dimension: - field + - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - - null ``` Compiled SQL (value `month`): `SELECT DATE_TRUNC('month', o.CREATED_AT) AS created_at, COUNT(*) FROM ORDERS o GROUP BY DATE_TRUNC('month', o.CREATED_AT)` @@ -1843,11 +1908,11 @@ click_behavior: dimension: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - ID - - null ``` ### Parameter Mapping Structure @@ -1912,18 +1977,18 @@ values_source_config: card_id: f1C68pznmrpN1F5xFDj6d value_field: - field + - {} - - Sample Database - PUBLIC - PRODUCTS - ID - - null label_field: - field + - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - - null ``` | Property | Type | Description | @@ -1989,11 +2054,11 @@ An optional third element `{stage-number: N}` can specify which query stage the target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null ``` **MBQL — multi-stage field reference:** @@ -2002,11 +2067,11 @@ target: target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - stage-number: 1 ``` @@ -2016,6 +2081,7 @@ target: target: - dimension - - expression + - {} - Profit ``` @@ -2148,9 +2214,10 @@ creator_id: internal@metabase.com type: question database_id: Sample Database dataset_query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC @@ -2312,11 +2379,11 @@ dashcards: target: - dimension - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null series: - card_id: OMuZ0wHe2O5Z_59-cLmn4 position: 0 @@ -2495,7 +2562,7 @@ Segments are stored under their table's directory: `databases/{db_slug}/schemas/ | `entity_id` | string | Yes | NanoID identifier | | `creator_id` | string | Yes | User FK (email) | | `table_id` | array | Yes | Table FK `[database, schema, table]` — must match `source-table` in definition | -| `definition` | object | Yes | Filter definition with `database`, `type: query`, and `query` containing `source-table` and `filter` | +| `definition` | object | Yes | Filter definition with `"lib/type": mbql/query`, `database`, and `stages` containing `source-table` and `filter` | | `serdes/meta` | array | Yes | Identity path with `model: Segment` | | `description` | string | No | Description | | `archived` | boolean | No | Whether archived (default: `false`) | @@ -2512,21 +2579,23 @@ table_id: - PUBLIC - PRODUCTS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - PRODUCTS filter: - = + - {} - - field + - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - null - Widget serdes/meta: - id: aB3kLmN9pQrStUvWxYz1a @@ -2552,7 +2621,7 @@ Measures are stored under their table's directory: `databases/{db_slug}/schemas/ | `entity_id` | string | Yes | NanoID identifier | | `creator_id` | string | Yes | User FK (email) | | `table_id` | array | Yes | Table FK `[database, schema, table]` — must match `source-table` in definition | -| `definition` | object | Yes | Aggregation definition with `database`, `type: query`, and `query` containing `source-table` and exactly one `aggregation`. Measures cannot use `filter`. | +| `definition` | object | Yes | Aggregation definition with `"lib/type": mbql/query`, `database`, and `stages` containing `source-table` and exactly one `aggregation`. Measures cannot use `filter`. | | `serdes/meta` | array | Yes | Identity path with `model: Measure` | | `description` | string | No | Description | | `archived` | boolean | No | Whether archived (default: `false`) | @@ -2569,21 +2638,23 @@ table_id: - PUBLIC - ORDERS definition: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC - ORDERS aggregation: - - sum + - {} - - field + - base-type: type/Float - - Sample Database - PUBLIC - ORDERS - TOTAL - - base-type: type/Float serdes/meta: - id: xK7mPqR2sT4uVwXyZ9a1b label: total_revenue @@ -2660,9 +2731,10 @@ When `source.type` is `query`, the source wraps an MBQL or native query. See [MB source: type: query query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC @@ -2796,9 +2868,10 @@ source_database_id: Sample Database source: type: query query: + "lib/type": mbql/query database: Sample Database - type: query - query: + stages: + - "lib/type": mbql.stage/mbql source-table: - Sample Database - PUBLIC diff --git a/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml b/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml index ef75eeb..c1da8f3 100644 --- a/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml +++ b/examples/v1/collections/main/minimal/marketing_analytics/product_overview.yaml @@ -14,7 +14,7 @@ dataset_query: - PRODUCTS aggregation: - - count - - {} + - "lib/uuid": 11111111-1111-1111-1111-111111111111 - - avg - {} - - field @@ -43,7 +43,7 @@ dataset_query: - {} - - aggregation - {} - - 0 + - 11111111-1111-1111-1111-111111111111 visualization_settings: {} serdes/meta: - id: f1C68pznmrpN1F5xFDj6d diff --git a/examples/v1/collections/main/queries/arithmetic_expressions.yaml b/examples/v1/collections/main/queries/arithmetic_expressions.yaml index 1937305..5731ea2 100644 --- a/examples/v1/collections/main/queries/arithmetic_expressions.yaml +++ b/examples/v1/collections/main/queries/arithmetic_expressions.yaml @@ -13,9 +13,8 @@ dataset_query: - PUBLIC - ORDERS expressions: - Total Plus Tax: - - "+" - - {} + - - "+" + - "lib/expression-name": Total Plus Tax - - field - base-type: type/Float - - Sample Database @@ -28,9 +27,8 @@ dataset_query: - PUBLIC - ORDERS - TAX - Price Difference: - - "-" - - {} + - - "-" + - "lib/expression-name": Price Difference - - field - base-type: type/Float - - Sample Database @@ -43,9 +41,8 @@ dataset_query: - PUBLIC - ORDERS - SUBTOTAL - Double Quantity: - - "*" - - {} + - - "*" + - "lib/expression-name": Double Quantity - - field - base-type: type/Integer - - Sample Database @@ -53,9 +50,8 @@ dataset_query: - ORDERS - QUANTITY - 2 - Per Unit Price: - - "/" - - {} + - - "/" + - "lib/expression-name": Per Unit Price - - field - base-type: type/Float - - Sample Database diff --git a/examples/v1/collections/main/queries/basic_aggregations.yaml b/examples/v1/collections/main/queries/basic_aggregations.yaml index 3ff291e..b0f55bd 100644 --- a/examples/v1/collections/main/queries/basic_aggregations.yaml +++ b/examples/v1/collections/main/queries/basic_aggregations.yaml @@ -14,9 +14,9 @@ dataset_query: - ORDERS aggregation: - - count - - {} + - "lib/uuid": 11111111-1111-1111-1111-111111111111 - - sum - - {} + - "lib/uuid": 22222222-2222-2222-2222-222222222222 - - field - base-type: type/Float - - Sample Database @@ -86,12 +86,12 @@ dataset_query: - {} - - aggregation - {} - - 0 + - 11111111-1111-1111-1111-111111111111 - - asc - {} - - aggregation - {} - - 1 + - 22222222-2222-2222-2222-222222222222 limit: 12 visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/queries/conditional_and_type.yaml b/examples/v1/collections/main/queries/conditional_and_type.yaml index 1396f5f..7ed3894 100644 --- a/examples/v1/collections/main/queries/conditional_and_type.yaml +++ b/examples/v1/collections/main/queries/conditional_and_type.yaml @@ -13,9 +13,9 @@ dataset_query: - PUBLIC - PRODUCTS expressions: - Price Tier: - - case + - - case - default: Budget + "lib/expression-name": Price Tier - - - - ">" - {} - - field @@ -36,9 +36,9 @@ dataset_query: - PRICE - 30 - Standard - Is Premium: - - if + - - if - default: false + "lib/expression-name": Is Premium - - - - ">" - {} - - field @@ -49,9 +49,8 @@ dataset_query: - PRICE - 100 - true - Simple Category: - - case - - {} + - - case + - "lib/expression-name": Simple Category - - - - ">" - {} - - field @@ -62,9 +61,8 @@ dataset_query: - RATING - 4 - Popular - Effective Price: - - coalesce - - {} + - - coalesce + - "lib/expression-name": Effective Price - - field - {} - - Sample Database @@ -72,27 +70,24 @@ dataset_query: - PRODUCTS - PRICE - 0 - Price as Text: - - text - - {} + - - text + - "lib/expression-name": Price as Text - - field - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - Rating as Integer: - - integer - - {} + - - integer + - "lib/expression-name": Rating as Integer - - field - {} - - Sample Database - PUBLIC - PRODUCTS - RATING - Rating as Float: - - float - - {} + - - float + - "lib/expression-name": Rating as Float - - field - {} - - Sample Database diff --git a/examples/v1/collections/main/queries/math_functions.yaml b/examples/v1/collections/main/queries/math_functions.yaml index e00c2ee..9157ac5 100644 --- a/examples/v1/collections/main/queries/math_functions.yaml +++ b/examples/v1/collections/main/queries/math_functions.yaml @@ -13,9 +13,8 @@ dataset_query: - PUBLIC - PRODUCTS expressions: - Absolute Discount: - - abs - - {} + - - abs + - "lib/expression-name": Absolute Discount - - "-" - {} - - field @@ -25,36 +24,32 @@ dataset_query: - PRODUCTS - PRICE - 50 - Price Ceiling: - - ceil - - {} + - - ceil + - "lib/expression-name": Price Ceiling - - field - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - Price Floor: - - floor - - {} + - - floor + - "lib/expression-name": Price Floor - - field - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - Rounded Price: - - round - - {} + - - round + - "lib/expression-name": Rounded Price - - field - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - Rating Squared: - - power - - {} + - - power + - "lib/expression-name": Rating Squared - - field - {} - - Sample Database @@ -62,27 +57,24 @@ dataset_query: - PRODUCTS - RATING - 2 - Price Sqrt: - - sqrt - - {} + - - sqrt + - "lib/expression-name": Price Sqrt - - field - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE - Price Exp: - - exp - - {} + - - exp + - "lib/expression-name": Price Exp - - field - {} - - Sample Database - PUBLIC - PRODUCTS - RATING - Price Log: - - log - - {} + - - log + - "lib/expression-name": Price Log - - field - {} - - Sample Database diff --git a/examples/v1/collections/main/queries/string_functions.yaml b/examples/v1/collections/main/queries/string_functions.yaml index 2261af3..58be47e 100644 --- a/examples/v1/collections/main/queries/string_functions.yaml +++ b/examples/v1/collections/main/queries/string_functions.yaml @@ -13,9 +13,8 @@ dataset_query: - PUBLIC - PRODUCTS expressions: - Title and Category: - - concat - - {} + - - concat + - "lib/expression-name": Title and Category - - field - {} - - Sample Database @@ -30,9 +29,8 @@ dataset_query: - PRODUCTS - CATEGORY - ")" - First 10 Chars: - - substring - - {} + - - substring + - "lib/expression-name": First 10 Chars - - field - {} - - Sample Database @@ -41,9 +39,8 @@ dataset_query: - TITLE - 1 - 10 - Cleaned Vendor: - - replace - - {} + - - replace + - "lib/expression-name": Cleaned Vendor - - field - {} - - Sample Database @@ -52,9 +49,8 @@ dataset_query: - VENDOR - Inc. - Incorporated - EAN Prefix: - - regex-match-first - - {} + - - regex-match-first + - "lib/expression-name": EAN Prefix - - field - {} - - Sample Database @@ -62,63 +58,56 @@ dataset_query: - PRODUCTS - EAN - "^\\d{3}" - Trimmed Title: - - trim - - {} + - - trim + - "lib/expression-name": Trimmed Title - - field - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - Left Trimmed: - - ltrim - - {} + - - ltrim + - "lib/expression-name": Left Trimmed - - field - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - Right Trimmed: - - rtrim - - {} + - - rtrim + - "lib/expression-name": Right Trimmed - - field - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - Upper Category: - - upper - - {} + - - upper + - "lib/expression-name": Upper Category - - field - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - Lower Title: - - lower - - {} + - - lower + - "lib/expression-name": Lower Title - - field - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - Title Length: - - length - - {} + - - length + - "lib/expression-name": Title Length - - field - {} - - Sample Database - PUBLIC - PRODUCTS - TITLE - Title From 5th Char: - - substring - - {} + - - substring + - "lib/expression-name": Title From 5th Char - - field - {} - - Sample Database diff --git a/examples/v1/collections/main/queries/temporal_expressions.yaml b/examples/v1/collections/main/queries/temporal_expressions.yaml index 2fb01ff..09aabba 100644 --- a/examples/v1/collections/main/queries/temporal_expressions.yaml +++ b/examples/v1/collections/main/queries/temporal_expressions.yaml @@ -13,9 +13,8 @@ dataset_query: - PUBLIC - ORDERS expressions: - Ship By: - - datetime-add - - {} + - - datetime-add + - "lib/expression-name": Ship By - - field - {} - - Sample Database @@ -24,9 +23,8 @@ dataset_query: - CREATED_AT - 7 - day - Week Before: - - datetime-subtract - - {} + - - datetime-subtract + - "lib/expression-name": Week Before - - field - {} - - Sample Database @@ -35,9 +33,8 @@ dataset_query: - CREATED_AT - 1 - week - Days Since Order: - - datetime-diff - - {} + - - datetime-diff + - "lib/expression-name": Days Since Order - - field - {} - - Sample Database @@ -47,9 +44,8 @@ dataset_query: - - now - {} - day - Ship By Deadline: - - "+" - - {} + - - "+" + - "lib/expression-name": Ship By Deadline - - field - {} - - Sample Database @@ -60,34 +56,30 @@ dataset_query: - {} - 7 - day - Order Date: - - date - - {} + - - date + - "lib/expression-name": Order Date - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Parsed Datetime: - - datetime - - {} + - - datetime + - "lib/expression-name": Parsed Datetime - "2024-06-15T10:30:00" - Parsed Unix: - - datetime + - - datetime - mode: unix-seconds + "lib/expression-name": Parsed Unix - - field - base-type: type/Integer - - Sample Database - PUBLIC - ORDERS - QUANTITY - Current Time: - - now - - {} - Today Date: - - today - - {} + - - now + - "lib/expression-name": Current Time + - - today + - "lib/expression-name": Today Date limit: 10 visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/queries/temporal_extraction.yaml b/examples/v1/collections/main/queries/temporal_extraction.yaml index b3a92fe..76f48c1 100644 --- a/examples/v1/collections/main/queries/temporal_extraction.yaml +++ b/examples/v1/collections/main/queries/temporal_extraction.yaml @@ -13,72 +13,64 @@ dataset_query: - PUBLIC - ORDERS expressions: - Order Year: - - get-year - - {} + - - get-year + - "lib/expression-name": Order Year - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Order Quarter: - - get-quarter - - {} + - - get-quarter + - "lib/expression-name": Order Quarter - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Order Month: - - get-month - - {} + - - get-month + - "lib/expression-name": Order Month - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Order Day: - - get-day - - {} + - - get-day + - "lib/expression-name": Order Day - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Order Hour: - - get-hour - - {} + - - get-hour + - "lib/expression-name": Order Hour - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Order Minute: - - get-minute - - {} + - - get-minute + - "lib/expression-name": Order Minute - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Order Second: - - get-second - - {} + - - get-second + - "lib/expression-name": Order Second - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Day of Week ISO: - - get-day-of-week - - {} + - - get-day-of-week + - "lib/expression-name": Day of Week ISO - - field - {} - - Sample Database @@ -86,9 +78,8 @@ dataset_query: - ORDERS - CREATED_AT - iso - Week Number: - - get-week - - {} + - - get-week + - "lib/expression-name": Week Number - - field - {} - - Sample Database @@ -96,9 +87,8 @@ dataset_query: - ORDERS - CREATED_AT - us - Month Name: - - month-name - - {} + - - month-name + - "lib/expression-name": Month Name - - get-month - {} - - field @@ -107,9 +97,8 @@ dataset_query: - PUBLIC - ORDERS - CREATED_AT - Quarter Name: - - quarter-name - - {} + - - quarter-name + - "lib/expression-name": Quarter Name - - get-quarter - {} - - field @@ -118,9 +107,8 @@ dataset_query: - PUBLIC - ORDERS - CREATED_AT - Day Name: - - day-name - - {} + - - day-name + - "lib/expression-name": Day Name - - get-day-of-week - {} - - field @@ -130,27 +118,24 @@ dataset_query: - ORDERS - CREATED_AT - iso - Day of Week Default: - - get-day-of-week - - {} + - - get-day-of-week + - "lib/expression-name": Day of Week Default - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Week Number Default: - - get-week - - {} + - - get-week + - "lib/expression-name": Week Number Default - - field - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT - Extracted Month: - - temporal-extract - - {} + - - temporal-extract + - "lib/expression-name": Extracted Month - - field - {} - - Sample Database @@ -158,9 +143,8 @@ dataset_query: - ORDERS - CREATED_AT - month-of-year - Extracted Day of Week ISO: - - temporal-extract - - {} + - - temporal-extract + - "lib/expression-name": Extracted Day of Week ISO - - field - {} - - Sample Database diff --git a/examples/v1/collections/main/queries/url_functions.yaml b/examples/v1/collections/main/queries/url_functions.yaml index ddbf12f..fb75751 100644 --- a/examples/v1/collections/main/queries/url_functions.yaml +++ b/examples/v1/collections/main/queries/url_functions.yaml @@ -13,36 +13,32 @@ dataset_query: - PUBLIC - PEOPLE expressions: - Source Host: - - host - - {} + - - host + - "lib/expression-name": Source Host - - field - {} - - Sample Database - PUBLIC - PEOPLE - SOURCE - Source Domain: - - domain - - {} + - - domain + - "lib/expression-name": Source Domain - - field - {} - - Sample Database - PUBLIC - PEOPLE - SOURCE - Source Subdomain: - - subdomain - - {} + - - subdomain + - "lib/expression-name": Source Subdomain - - field - {} - - Sample Database - PUBLIC - PEOPLE - SOURCE - Source Path: - - path - - {} + - - path + - "lib/expression-name": Source Path - - field - {} - - Sample Database diff --git a/package.json b/package.json index bd2f8b1..7fb26e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metabase/representations", - "version": "0.0.1", + "version": "1.0.0", "description": "Metabase representation format specification and schema validator", "license": "SEE LICENSE IN LICENSE.txt", "repository": { From bd7831a9aae7b5440470997a64eec8b5b7e05fdf Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 18:37:21 -0400 Subject: [PATCH 03/15] fixes --- .../bar_chart_stacked.yaml | 38 ++++++++++--------- .../visualization_settings/pivot_table.yaml | 38 ++++++++++--------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml b/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml index f371a89..da940a7 100644 --- a/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml +++ b/examples/v1/collections/main/visualization_settings/bar_chart_stacked.yaml @@ -23,25 +23,27 @@ dataset_query: - ORDERS - CREATED_AT joins: - - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - condition: - - = - - {} - - - field - - {} - - - Sample Database - - PUBLIC - - ORDERS - - PRODUCT_ID - - - field + - stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + conditions: + - - = - {} - - - Sample Database - - PUBLIC - - PRODUCTS - - ID + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - PRODUCT_ID + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - ID alias: Products strategy: left-join fields: all diff --git a/examples/v1/collections/main/visualization_settings/pivot_table.yaml b/examples/v1/collections/main/visualization_settings/pivot_table.yaml index 4174dba..f0ebc83 100644 --- a/examples/v1/collections/main/visualization_settings/pivot_table.yaml +++ b/examples/v1/collections/main/visualization_settings/pivot_table.yaml @@ -31,25 +31,27 @@ dataset_query: - ORDERS - CREATED_AT joins: - - source-table: - - Sample Database - - PUBLIC - - PRODUCTS - condition: - - = - - {} - - - field - - {} - - - Sample Database - - PUBLIC - - ORDERS - - PRODUCT_ID - - - field + - stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - PRODUCTS + conditions: + - - = - {} - - - Sample Database - - PUBLIC - - PRODUCTS - - ID + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - PRODUCT_ID + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - ID alias: Products strategy: left-join fields: all From dd61009288d189c3a4b2caf07dee67777a46faea Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 18:40:52 -0400 Subject: [PATCH 04/15] fixes --- bin/cli.js | 0 core-spec/v1/schemas/common/query.yaml | 23 ------------------- core-spec/v1/spec.md | 15 +++++------- .../main/queries/basic_aggregations.yaml | 16 ++++++------- 4 files changed, 13 insertions(+), 41 deletions(-) mode change 100644 => 100755 bin/cli.js diff --git a/bin/cli.js b/bin/cli.js old mode 100644 new mode 100755 diff --git a/core-spec/v1/schemas/common/query.yaml b/core-spec/v1/schemas/common/query.yaml index d9a210f..f89fc9d 100644 --- a/core-spec/v1/schemas/common/query.yaml +++ b/core-spec/v1/schemas/common/query.yaml @@ -55,15 +55,6 @@ $defs: properties: include-current: { type: boolean } - aggregation_naming_options: - description: Options for aggregation-options (custom display name / name). - allOf: - - $ref: "#/$defs/options" - - type: object - properties: - display-name: { type: string } - name: { type: string } - case_if_options: description: Options for case/if operators. allOf: @@ -86,12 +77,6 @@ $defs: type: object required: - "lib/type" - properties: - "lib/type": - type: string - enum: - - mbql.stage/mbql - - mbql.stage/native allOf: - if: properties: @@ -475,14 +460,6 @@ $defs: - $ref: "#/$defs/expression" minItems: 4 maxItems: 4 - - if: { prefixItems: [{ const: aggregation-options }] } - then: - prefixItems: - - const: aggregation-options - - $ref: "#/$defs/aggregation_naming_options" - - $ref: "#/$defs/expression" - minItems: 3 - maxItems: 3 - if: { prefixItems: [{ enum: [case, if] }] } then: prefixItems: diff --git a/core-spec/v1/spec.md b/core-spec/v1/spec.md index d311e1c..9917746 100644 --- a/core-spec/v1/spec.md +++ b/core-spec/v1/spec.md @@ -888,21 +888,18 @@ aggregation: #### Named Aggregations -Aggregations can have a custom display name using the `aggregation-options` wrapper. The options map (with `display-name`) is the second argument, before the aggregation clause: +Aggregations can have a custom display name by setting `display-name` and/or `name` directly in the aggregation clause's options: ```yaml aggregation: -- - aggregation-options +- - sum - display-name: Total Revenue - - - sum - - {} - - - field - - base-type: type/Float - - [Sample Database, PUBLIC, ORDERS, TOTAL] + name: total_revenue + - - field + - base-type: type/Float + - [Sample Database, PUBLIC, ORDERS, TOTAL] ``` -The structure is `[aggregation-options, {display-name: "Name"}, aggregation-clause]`. - #### Metric and Measure References A `metric` clause references a saved metric (a card with `type: metric`) by its entity_id: diff --git a/examples/v1/collections/main/queries/basic_aggregations.yaml b/examples/v1/collections/main/queries/basic_aggregations.yaml index b0f55bd..8a90529 100644 --- a/examples/v1/collections/main/queries/basic_aggregations.yaml +++ b/examples/v1/collections/main/queries/basic_aggregations.yaml @@ -63,17 +63,15 @@ dataset_query: - PUBLIC - ORDERS - PRODUCT_ID - - - aggregation-options + - - sum - display-name: Total Revenue name: total_revenue - - - sum - - {} - - - field - - base-type: type/Float - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL breakout: - - field - temporal-unit: month From 1f1e6843b5f9b9355f8d5cb3e5ac56459aa4f887 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 18:58:17 -0400 Subject: [PATCH 05/15] fix --- .github/workflows/import.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index beeb49b..ad2448b 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -17,7 +17,7 @@ jobs: docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ - metabase/metabase-enterprise:latest + metabase/metabase-dev:serdes-mbql-5 echo "Waiting for Metabase to start..." timeout 180 bash -c ' From 41b1bd6366183c9e1a7181b48b2b23a1c74c3992 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 18:58:59 -0400 Subject: [PATCH 06/15] fix --- .github/workflows/import.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index ad2448b..beeb49b 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -17,7 +17,7 @@ jobs: docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ - metabase/metabase-dev:serdes-mbql-5 + metabase/metabase-enterprise:latest echo "Waiting for Metabase to start..." timeout 180 bash -c ' From 11e3d28361605e295ca5dfd01c5b2aa59298600a Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 19:25:56 -0400 Subject: [PATCH 07/15] fixes --- .github/workflows/import.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index beeb49b..9e81599 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -14,6 +14,7 @@ jobs: - name: Start Metabase run: | + docker pull metabase/metabase-enterprise:latest docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ From 3c0b4d2fdb7889e826526f0fca1d89b1573c5385 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 19:35:27 -0400 Subject: [PATCH 08/15] fixes --- .github/workflows/import.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 9e81599..4d55df6 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -14,11 +14,11 @@ jobs: - name: Start Metabase run: | - docker pull metabase/metabase-enterprise:latest + docker pull metabase/metabase-enterprise@sha256:da42a30cee78d0f4f9e9a1f2ea229fd8a6bb996b3ff5b49ece9bdf29c8be7b79 docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ - metabase/metabase-enterprise:latest + metabase/metabase-enterprise@sha256:da42a30cee78d0f4f9e9a1f2ea229fd8a6bb996b3ff5b49ece9bdf29c8be7b79 echo "Waiting for Metabase to start..." timeout 180 bash -c ' From 9e17d7c83e60705e175d86a4ab161c0760ce5967 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 19:36:35 -0400 Subject: [PATCH 09/15] fixes --- .github/workflows/import.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 4d55df6..9e81599 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -14,11 +14,11 @@ jobs: - name: Start Metabase run: | - docker pull metabase/metabase-enterprise@sha256:da42a30cee78d0f4f9e9a1f2ea229fd8a6bb996b3ff5b49ece9bdf29c8be7b79 + docker pull metabase/metabase-enterprise:latest docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ - metabase/metabase-enterprise@sha256:da42a30cee78d0f4f9e9a1f2ea229fd8a6bb996b3ff5b49ece9bdf29c8be7b79 + metabase/metabase-enterprise:latest echo "Waiting for Metabase to start..." timeout 180 bash -c ' From 09ed36cf52bade8ef8d5eb57b246ce6e99d682ae Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 19:38:51 -0400 Subject: [PATCH 10/15] fixes --- .github/workflows/import.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 9e81599..09f40ae 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -14,11 +14,11 @@ jobs: - name: Start Metabase run: | - docker pull metabase/metabase-enterprise:latest + docker pull metabase/metabase-enterprise@sha256:2751c33d5c603ae6bdeb9615c91bd6bfd268ced67104d6df69416016d4e8ecfd docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ - metabase/metabase-enterprise:latest + metabase/metabase-enterprise@sha256:2751c33d5c603ae6bdeb9615c91bd6bfd268ced67104d6df69416016d4e8ecfd echo "Waiting for Metabase to start..." timeout 180 bash -c ' From b6d8c3354b08e5f07438e2247ff958faf7029f69 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 19:40:20 -0400 Subject: [PATCH 11/15] fixes --- .github/workflows/import.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 09f40ae..9d0641d 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -14,11 +14,11 @@ jobs: - name: Start Metabase run: | - docker pull metabase/metabase-enterprise@sha256:2751c33d5c603ae6bdeb9615c91bd6bfd268ced67104d6df69416016d4e8ecfd + docker pull metabase/metabase-enterprise@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ - metabase/metabase-enterprise@sha256:2751c33d5c603ae6bdeb9615c91bd6bfd268ced67104d6df69416016d4e8ecfd + metabase/metabase-enterprise@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 echo "Waiting for Metabase to start..." timeout 180 bash -c ' From bb474f65648be0ea3b3e75486a950f6d170589b1 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 19:40:52 -0400 Subject: [PATCH 12/15] fix --- .github/workflows/import.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 9d0641d..70186e0 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -14,7 +14,7 @@ jobs: - name: Start Metabase run: | - docker pull metabase/metabase-enterprise@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 + docker pull --platform linux/amd64 metabase/metabase-enterprise@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ From 2240b50f3a91bd0b22d039418807f067adc4cab8 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 19:42:21 -0400 Subject: [PATCH 13/15] fix --- .github/workflows/import.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/import.yml b/.github/workflows/import.yml index 70186e0..cb3bd82 100644 --- a/.github/workflows/import.yml +++ b/.github/workflows/import.yml @@ -14,11 +14,11 @@ jobs: - name: Start Metabase run: | - docker pull --platform linux/amd64 metabase/metabase-enterprise@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 + docker pull metabase/metabase-enterprise-head@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 docker run -d --name metabase \ -e MB_PREMIUM_EMBEDDING_TOKEN=${{ secrets.MB_PREMIUM_EMBEDDING_TOKEN }} \ -p 3000:3000 \ - metabase/metabase-enterprise@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 + metabase/metabase-enterprise-head@sha256:b9f65f48f7121602cc37732ffeab4a4afdcbf7d945e49bed25d40264a95b18c8 echo "Waiting for Metabase to start..." timeout 180 bash -c ' From ce3b5cfe544c4ee9c58d7e5b6568ba91248e4dc3 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 20:57:43 -0400 Subject: [PATCH 14/15] fix --- core-spec/v1/schemas/common/parameter.yaml | 10 +- core-spec/v1/schemas/common/query.yaml | 30 ++- core-spec/v1/schemas/common/ref.yaml | 21 ++ core-spec/v1/schemas/segment.yaml | 12 +- core-spec/v1/schemas/transform.yaml | 15 +- core-spec/v1/spec.md | 187 ++++++++++++------ .../main/dashboards/click_behaviors.yaml | 2 +- .../main/dashboards/inline_parameters.yaml | 4 +- .../main/dashboards/series_and_mappings.yaml | 5 +- .../main/dashboards/tabbed_dashboard.yaml | 2 +- .../product_dashboard.yaml | 2 +- .../main/queries/arithmetic_expressions.yaml | 12 +- .../main/queries/comparison_filters.yaml | 4 +- .../main/queries/fields_and_expressions.yaml | 57 ++++++ .../main/queries/geographic_filter.yaml | 36 ++-- .../queries/metric_measure_segment_refs.yaml | 8 +- .../main/queries/nested_query.yaml | 14 +- .../main/queries/null_and_string_filters.yaml | 4 +- .../main/queries/source_card_reference.yaml | 14 +- .../queries/temporal_and_logical_filters.yaml | 4 +- .../tables/orders/segments/large_orders.yaml | 20 +- .../tables/people/segments/nyc_area.yaml | 36 ++-- .../products/segments/premium_widgets.yaml | 4 +- .../products/segments/recent_midrange.yaml | 4 +- .../segments/searchable_products.yaml | 4 +- .../products/segments/widget_products.yaml | 18 +- 26 files changed, 339 insertions(+), 190 deletions(-) create mode 100644 examples/v1/collections/main/queries/fields_and_expressions.yaml diff --git a/core-spec/v1/schemas/common/parameter.yaml b/core-spec/v1/schemas/common/parameter.yaml index afd5d68..e1ec46a 100644 --- a/core-spec/v1/schemas/common/parameter.yaml +++ b/core-spec/v1/schemas/common/parameter.yaml @@ -97,10 +97,8 @@ properties: $defs: parameter_target: description: > - Parameter target for dashboard parameter mappings. - For MBQL columns: [dimension, ref] where ref is a field, expression, or aggregation ref. - For native dimension tags: [dimension, [template-tag, tag_name]]. - For native variable tags: [variable, [template-tag, tag_name]]. + Parameter target for dashboard parameter mappings. Uses legacy + MBQL format: [field, Field-FK, null-or-options]. type: array minItems: 2 allOf: @@ -112,9 +110,9 @@ $defs: minItems: 2 allOf: - if: { prefixItems: [{ const: field }] } - then: { $ref: "ref.yaml#/$defs/field_ref" } + then: { $ref: "ref.yaml#/$defs/legacy_field_ref" } - if: { prefixItems: [{ const: expression }] } - then: { $ref: "ref.yaml#/$defs/expression_ref" } + then: { $ref: "ref.yaml#/$defs/legacy_expression_ref" } - if: { prefixItems: [{ const: template-tag }] } then: prefixItems: [{ const: template-tag }, { type: string }] diff --git a/core-spec/v1/schemas/common/query.yaml b/core-spec/v1/schemas/common/query.yaml index f89fc9d..d180de2 100644 --- a/core-spec/v1/schemas/common/query.yaml +++ b/core-spec/v1/schemas/common/query.yaml @@ -106,8 +106,21 @@ $defs: type: array items: $ref: "#/$defs/expression" - filter: - $ref: "#/$defs/expression" + fields: + type: array + items: + type: array + allOf: + - if: { prefixItems: [{ const: field }] } + then: + $ref: "ref.yaml#/$defs/field_ref" + - if: { prefixItems: [{ const: expression }] } + then: + $ref: "ref.yaml#/$defs/expression_ref" + filters: + type: array + items: + $ref: "#/$defs/expression" aggregation: type: array items: @@ -129,14 +142,11 @@ $defs: description: > An MBQL expression clause. Either a literal value or an array [operator, options, ...args] where options is always an object. - oneOf: - - type: string - - type: number - - type: boolean - - type: "null" - - type: array - minItems: 1 - allOf: + type: [string, number, boolean, "null", array] + if: { type: array } + then: + minItems: 1 + allOf: - if: { prefixItems: [{ const: field }] } then: $ref: "ref.yaml#/$defs/field_ref" diff --git a/core-spec/v1/schemas/common/ref.yaml b/core-spec/v1/schemas/common/ref.yaml index 7c484d8..4fc74c6 100644 --- a/core-spec/v1/schemas/common/ref.yaml +++ b/core-spec/v1/schemas/common/ref.yaml @@ -111,3 +111,24 @@ $defs: - type: string minItems: 3 maxItems: 3 + + legacy_field_ref: + description: "[field, Field-FK-or-name, null-or-options] — legacy format used in parameter targets" + type: array + prefixItems: + - const: field + - if: { type: array } + then: { $ref: "id.yaml#/$defs/field_id" } + - type: [object, "null"] + minItems: 3 + maxItems: 3 + + legacy_expression_ref: + description: "[expression, name] or [expression, name, null-or-options] — legacy format used in parameter targets" + type: array + prefixItems: + - const: expression + - type: string + - type: [object, "null"] + minItems: 2 + maxItems: 3 diff --git a/core-spec/v1/schemas/segment.yaml b/core-spec/v1/schemas/segment.yaml index d35201d..89f9a6f 100644 --- a/core-spec/v1/schemas/segment.yaml +++ b/core-spec/v1/schemas/segment.yaml @@ -45,19 +45,17 @@ properties: required: - "lib/type" - source-table - - filter + - filters additionalProperties: false properties: "lib/type": const: mbql.stage/mbql source-table: - description: > - Table FK [database, schema, table]. Segments must reference - a physical table, not a saved card/model. $ref: "common/id.yaml#/$defs/table_id" - filter: - description: Filter clause - $ref: "common/query.yaml#/$defs/expression" + filters: + type: array + items: + $ref: "common/query.yaml#/$defs/expression" description: type: - string diff --git a/core-spec/v1/schemas/transform.yaml b/core-spec/v1/schemas/transform.yaml index 7991762..d5db964 100644 --- a/core-spec/v1/schemas/transform.yaml +++ b/core-spec/v1/schemas/transform.yaml @@ -24,9 +24,18 @@ properties: description: > Source definition — either a query (type: query) or a Python script (type: python). - oneOf: - - $ref: "#/$defs/query_source" - - $ref: "#/$defs/python_source" + type: object + allOf: + - if: + properties: + type: { const: query } + then: + $ref: "#/$defs/query_source" + - if: + properties: + type: { const: python } + then: + $ref: "#/$defs/python_source" target: type: object description: Where the resulting table is written diff --git a/core-spec/v1/spec.md b/core-spec/v1/spec.md index 9917746..42c9cea 100644 --- a/core-spec/v1/spec.md +++ b/core-spec/v1/spec.md @@ -205,13 +205,13 @@ database: Sample Database stages: - "lib/type": mbql.stage/mbql source-card: f1C68pznmrpN1F5xFDj6d # entity_id of a saved card - filter: - - ">" - - {} - - - field - - base-type: type/Float - - PRICE - - 50 + filters: + - - ">" + - {} + - - field + - base-type: type/Float + - PRICE + - 50 ``` ### Stages (multi-stage queries) @@ -238,13 +238,13 @@ stages: - ORDERS - CREATED_AT - "lib/type": mbql.stage/mbql - filter: - - ">" - - {} - - - field - - base-type: type/Integer - - count - - 10 + filters: + - - ">" + - {} + - - field + - base-type: type/Integer + - count + - 10 ``` This is equivalent to `SELECT * FROM (SELECT DATE_TRUNC('month', CREATED_AT), COUNT(*) AS count FROM ORDERS GROUP BY 1) WHERE count > 10`. @@ -344,6 +344,53 @@ Aggregation references use the `aggregation` keyword with a UUID that matches th - "11111111-1111-1111-1111-111111111111" ``` +### Fields + +Restricts which columns are included in the results. Each item is a `field` or `expression` reference: + +```yaml +fields: +- - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL +- - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT +- - expression + - {} + - Profit +``` + +When `fields` is omitted, all columns are included. If `fields` is present and the stage has `expressions`, every expression must be included in `fields` as an `expression` reference: + +```yaml +fields: +- - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL +- - expression + - {} + - Profit +expressions: +- - "-" + - "lib/expression-name": Profit + - - field + - {} + - [Sample Database, PUBLIC, ORDERS, TOTAL] + - - field + - {} + - [Sample Database, PUBLIC, ORDERS, TAX] +``` + ### Joins Joins combine data from multiple tables. Each join has its own `stages` array (defining the joined data source) and a `conditions` array (one or more join conditions): @@ -421,22 +468,20 @@ See [Expression Operators](#expression-operators) for the full operator referenc ### Filters -Filters restrict which rows are included: +`filters` is an array of filter clauses that restrict which rows are included. Multiple clauses are implicitly ANDed together. To use OR logic, include an explicit `[or, {}, ...]` clause as one of the array items. ```yaml -filter: -- -- {} -- -- +filters: +- - + - {} + - + - ``` -Compound filters use `and` / `or` / `not`: +Multiple filter clauses (implicitly ANDed): ```yaml -filter: -- and -- {} +filters: - - ">=" - {} - - field @@ -457,8 +502,48 @@ filter: - 100 ``` +To use OR, place an explicit `or` clause as an item in the array: + +```yaml +filters: +- - or + - {} + - - = + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + - Widget + - - = + - {} + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + - Gadget +``` + See [Filter Operators](#filter-operators) for the full operator reference. +### Breakouts + +Breakouts group results by columns (like `GROUP BY`): + +```yaml +breakout: +- - field + - temporal-unit: month + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT +``` + ### Aggregations Aggregations compute summary values. Multiple aggregations can be combined. When an aggregation is referenced elsewhere (e.g., in `order-by` or a later stage), its options map must include a `lib/uuid`: @@ -479,20 +564,6 @@ aggregation: See [Aggregation Functions](#aggregation-functions) for the full reference. -### Breakouts - -Breakouts group results by columns (like `GROUP BY`): - -```yaml -breakout: -- - field - - temporal-unit: month - - - Sample Database - - PUBLIC - - ORDERS - - CREATED_AT -``` - ### Order By ```yaml @@ -2043,7 +2114,9 @@ Parameter targets specify which column or variable a parameter maps to. The oute - **`dimension`** — for MBQL column references (`field`, `expression`) and for native template tags of type `dimension` or `temporal-unit` - **`variable`** — for native template tags of type `text`, `number`, `date`, or `boolean` -An optional third element `{stage-number: N}` can specify which query stage the target belongs to (0 = first stage). +An optional third element `{stage-number: N}` or `null` can specify which query stage the target belongs to (0 = first stage). + +**Important:** Field and expression references inside parameter targets use **legacy format** (`[field, Field-FK, null-or-options]`, `[expression, name]`), not pMBQL format. This differs from references inside `dataset_query.stages`, which use pMBQL format (`[field, options, Field-FK]`). **MBQL — field reference:** @@ -2051,24 +2124,21 @@ An optional third element `{stage-number: N}` can specify which query stage the target: - dimension - - field - - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY + - null ``` -**MBQL — multi-stage field reference:** +**MBQL — multi-stage field reference (column name, not Field FK):** ```yaml target: - dimension - - field - - {} - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY + - CATEGORY + - null - stage-number: 1 ``` @@ -2078,7 +2148,6 @@ target: target: - dimension - - expression - - {} - Profit ``` @@ -2376,11 +2445,11 @@ dashcards: target: - dimension - - field - - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY + - null series: - card_id: OMuZ0wHe2O5Z_59-cLmn4 position: 0 @@ -2559,7 +2628,7 @@ Segments are stored under their table's directory: `databases/{db_slug}/schemas/ | `entity_id` | string | Yes | NanoID identifier | | `creator_id` | string | Yes | User FK (email) | | `table_id` | array | Yes | Table FK `[database, schema, table]` — must match `source-table` in definition | -| `definition` | object | Yes | Filter definition with `"lib/type": mbql/query`, `database`, and `stages` containing `source-table` and `filter` | +| `definition` | object | Yes | Filter definition with `"lib/type": mbql/query`, `database`, and `stages` containing `source-table` and `filters` | | `serdes/meta` | array | Yes | Identity path with `model: Segment` | | `description` | string | No | Description | | `archived` | boolean | No | Whether archived (default: `false`) | @@ -2584,16 +2653,16 @@ definition: - Sample Database - PUBLIC - PRODUCTS - filter: - - = - - {} - - - field + filters: + - - = - {} - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - Widget + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + - Widget serdes/meta: - id: aB3kLmN9pQrStUvWxYz1a label: widget_products @@ -2618,7 +2687,7 @@ Measures are stored under their table's directory: `databases/{db_slug}/schemas/ | `entity_id` | string | Yes | NanoID identifier | | `creator_id` | string | Yes | User FK (email) | | `table_id` | array | Yes | Table FK `[database, schema, table]` — must match `source-table` in definition | -| `definition` | object | Yes | Aggregation definition with `"lib/type": mbql/query`, `database`, and `stages` containing `source-table` and exactly one `aggregation`. Measures cannot use `filter`. | +| `definition` | object | Yes | Aggregation definition with `"lib/type": mbql/query`, `database`, and `stages` containing `source-table` and exactly one `aggregation`. Measures cannot use `filters`. | | `serdes/meta` | array | Yes | Identity path with `model: Measure` | | `description` | string | No | Description | | `archived` | boolean | No | Whether archived (default: `false`) | diff --git a/examples/v1/collections/main/dashboards/click_behaviors.yaml b/examples/v1/collections/main/dashboards/click_behaviors.yaml index b01ed39..14f12cc 100644 --- a/examples/v1/collections/main/dashboards/click_behaviors.yaml +++ b/examples/v1/collections/main/dashboards/click_behaviors.yaml @@ -21,11 +21,11 @@ dashcards: target: - dimension - - field - - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY + - null series: [] visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/dashboards/inline_parameters.yaml b/examples/v1/collections/main/dashboards/inline_parameters.yaml index 09b39a2..4379fcf 100644 --- a/examples/v1/collections/main/dashboards/inline_parameters.yaml +++ b/examples/v1/collections/main/dashboards/inline_parameters.yaml @@ -69,21 +69,21 @@ dashcards: target: - dimension - - field - - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY + - null - card_id: h5F2EjHsRd73Dqqh8sAtd parameter_id: d0000002-0000-0000-0000-000000000002 target: - dimension - - field - - {} - - Sample Database - PUBLIC - PRODUCTS - PRICE + - null series: [] visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/dashboards/series_and_mappings.yaml b/examples/v1/collections/main/dashboards/series_and_mappings.yaml index 2bedb31..8ced13e 100644 --- a/examples/v1/collections/main/dashboards/series_and_mappings.yaml +++ b/examples/v1/collections/main/dashboards/series_and_mappings.yaml @@ -27,22 +27,21 @@ dashcards: target: - dimension - - field - - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY - - stage-number: 0 + - null - card_id: dShCrdMnthlyOrdrs0001 parameter_id: c0000002-0000-0000-0000-000000000002 target: - dimension - - field - - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT + - null series: - card_id: dShCrdMnthlyRevnu0002 position: 0 diff --git a/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml b/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml index 7e91381..e8f7676 100644 --- a/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml +++ b/examples/v1/collections/main/dashboards/tabbed_dashboard.yaml @@ -33,11 +33,11 @@ dashcards: target: - dimension - - field - - {} - - Sample Database - PUBLIC - ORDERS - CREATED_AT + - null series: [] visualization_settings: {} serdes/meta: diff --git a/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml b/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml index 6725486..3ca6123 100644 --- a/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml +++ b/examples/v1/collections/main/minimal/marketing_analytics/product_dashboard.yaml @@ -20,11 +20,11 @@ dashcards: target: - dimension - - field - - {} - - Sample Database - PUBLIC - PRODUCTS - CATEGORY + - null serdes/meta: - id: Q_jD-f-9clKLFZ2TfUG2h model: Dashboard diff --git a/examples/v1/collections/main/queries/arithmetic_expressions.yaml b/examples/v1/collections/main/queries/arithmetic_expressions.yaml index 5731ea2..c5acda7 100644 --- a/examples/v1/collections/main/queries/arithmetic_expressions.yaml +++ b/examples/v1/collections/main/queries/arithmetic_expressions.yaml @@ -97,13 +97,13 @@ dataset_query: - PUBLIC - ORDERS - QUANTITY - filter: - - ">" - - {} - - - expression + filters: + - - ">" - {} - - Per Unit Price - - 10 + - - expression + - {} + - Per Unit Price + - 10 breakout: - - field - temporal-unit: month diff --git a/examples/v1/collections/main/queries/comparison_filters.yaml b/examples/v1/collections/main/queries/comparison_filters.yaml index 961af5b..1339ed7 100644 --- a/examples/v1/collections/main/queries/comparison_filters.yaml +++ b/examples/v1/collections/main/queries/comparison_filters.yaml @@ -12,9 +12,7 @@ dataset_query: - Sample Database - PUBLIC - PRODUCTS - filter: - - and - - {} + filters: - - between - {} - - field diff --git a/examples/v1/collections/main/queries/fields_and_expressions.yaml b/examples/v1/collections/main/queries/fields_and_expressions.yaml new file mode 100644 index 0000000..8e75c71 --- /dev/null +++ b/examples/v1/collections/main/queries/fields_and_expressions.yaml @@ -0,0 +1,57 @@ +name: "Fields and Expressions" +entity_id: fLdExPr3sS10nS0ExAmPl +creator_id: admin@example.com +display: table +database_id: Sample Database +dataset_query: + "lib/type": mbql/query + database: Sample Database + stages: + - "lib/type": mbql.stage/mbql + source-table: + - Sample Database + - PUBLIC + - ORDERS + fields: + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - CREATED_AT + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - field + - {} + - - Sample Database + - PUBLIC + - ORDERS + - TAX + - - expression + - {} + - Profit + expressions: + - - "-" + - "lib/expression-name": Profit + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TAX + limit: 100 +visualization_settings: {} +serdes/meta: +- id: fLdExPr3sS10nS0ExAmPl + label: fields_and_expressions + model: Card diff --git a/examples/v1/collections/main/queries/geographic_filter.yaml b/examples/v1/collections/main/queries/geographic_filter.yaml index c71a9f3..7047515 100644 --- a/examples/v1/collections/main/queries/geographic_filter.yaml +++ b/examples/v1/collections/main/queries/geographic_filter.yaml @@ -12,25 +12,25 @@ dataset_query: - Sample Database - PUBLIC - PEOPLE - filter: - - inside - - {} - - - field + filters: + - - inside - {} - - - Sample Database - - PUBLIC - - PEOPLE - - LATITUDE - - - field - - {} - - - Sample Database - - PUBLIC - - PEOPLE - - LONGITUDE - - 40.8 - - -74.1 - - 40.6 - - -73.9 + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - LATITUDE + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - LONGITUDE + - 40.8 + - -74.1 + - 40.6 + - -73.9 visualization_settings: {} serdes/meta: - id: bK64P6yr9_Nx-A8S3PqOZ diff --git a/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml b/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml index ad90129..c0e3398 100644 --- a/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml +++ b/examples/v1/collections/main/queries/metric_measure_segment_refs.yaml @@ -19,10 +19,10 @@ dataset_query: - - measure - {} - DBap2523KuN4Lt-cYrUjF - filter: - - segment - - {} - - OaFXAvEzPvu9ZXW5PUMRa + filters: + - - segment + - {} + - OaFXAvEzPvu9ZXW5PUMRa visualization_settings: {} serdes/meta: - id: kBjQ5VXJ5z3vYSW72J6qa diff --git a/examples/v1/collections/main/queries/nested_query.yaml b/examples/v1/collections/main/queries/nested_query.yaml index 966353a..86b8ddd 100644 --- a/examples/v1/collections/main/queries/nested_query.yaml +++ b/examples/v1/collections/main/queries/nested_query.yaml @@ -31,13 +31,13 @@ dataset_query: - ORDERS - USER_ID - "lib/type": mbql.stage/mbql - filter: - - ">" - - {} - - - field - - base-type: type/Integer - - count - - 5 + filters: + - - ">" + - {} + - - field + - base-type: type/Integer + - count + - 5 order-by: - - desc - {} diff --git a/examples/v1/collections/main/queries/null_and_string_filters.yaml b/examples/v1/collections/main/queries/null_and_string_filters.yaml index 65ae691..730c8ac 100644 --- a/examples/v1/collections/main/queries/null_and_string_filters.yaml +++ b/examples/v1/collections/main/queries/null_and_string_filters.yaml @@ -12,9 +12,7 @@ dataset_query: - Sample Database - PUBLIC - PRODUCTS - filter: - - and - - {} + filters: - - not-null - {} - - field diff --git a/examples/v1/collections/main/queries/source_card_reference.yaml b/examples/v1/collections/main/queries/source_card_reference.yaml index 1cbd828..63b3ad7 100644 --- a/examples/v1/collections/main/queries/source_card_reference.yaml +++ b/examples/v1/collections/main/queries/source_card_reference.yaml @@ -9,13 +9,13 @@ dataset_query: stages: - "lib/type": mbql.stage/mbql source-card: h5F2EjHsRd73Dqqh8sAtd - filter: - - ">" - - {} - - - field - - base-type: type/Integer - - count - - 100 + filters: + - - ">" + - {} + - - field + - base-type: type/Integer + - count + - 100 order-by: - - desc - {} diff --git a/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml b/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml index dfec7b6..4886b62 100644 --- a/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml +++ b/examples/v1/collections/main/queries/temporal_and_logical_filters.yaml @@ -12,9 +12,7 @@ dataset_query: - Sample Database - PUBLIC - ORDERS - filter: - - and - - {} + filters: - - time-interval - {} - - field diff --git a/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml b/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml index 0f25df4..04f51f9 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/orders/segments/large_orders.yaml @@ -14,16 +14,16 @@ definition: - Sample Database - PUBLIC - ORDERS - filter: - - ">" - - {} - - - field - - base-type: type/Float - - - Sample Database - - PUBLIC - - ORDERS - - TOTAL - - 50 + filters: + - - ">" + - {} + - - field + - base-type: type/Float + - - Sample Database + - PUBLIC + - ORDERS + - TOTAL + - 50 serdes/meta: - id: OaFXAvEzPvu9ZXW5PUMRa label: large_orders diff --git a/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml b/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml index 4088ba0..eeec4fb 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/people/segments/nyc_area.yaml @@ -15,25 +15,25 @@ definition: - Sample Database - PUBLIC - PEOPLE - filter: - - inside - - {} - - - field + filters: + - - inside - {} - - - Sample Database - - PUBLIC - - PEOPLE - - LATITUDE - - - field - - {} - - - Sample Database - - PUBLIC - - PEOPLE - - LONGITUDE - - 40.92 - - -74.26 - - 40.49 - - -73.70 + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - LATITUDE + - - field + - {} + - - Sample Database + - PUBLIC + - PEOPLE + - LONGITUDE + - 40.92 + - -74.26 + - 40.49 + - -73.70 serdes/meta: - id: D2R9JpvI8sMfYWqfPsTkx label: nyc_area diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml index d998b0c..723a7b0 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/premium_widgets.yaml @@ -15,9 +15,7 @@ definition: - Sample Database - PUBLIC - PRODUCTS - filter: - - and - - {} + filters: - - segment - {} - aB3kLmN9pQrStUvWxYz1a diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml index 9f9d14a..e0b727d 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/recent_midrange.yaml @@ -15,9 +15,7 @@ definition: - Sample Database - PUBLIC - PRODUCTS - filter: - - and - - {} + filters: - - between - {} - - field diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml index fdb6a8c..4ebaa6b 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/searchable_products.yaml @@ -15,9 +15,7 @@ definition: - Sample Database - PUBLIC - PRODUCTS - filter: - - and - - {} + filters: - - not-empty - {} - - field diff --git a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml index 54381cc..c151d7b 100644 --- a/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml +++ b/examples/v1/databases/sample_database/schemas/public/tables/products/segments/widget_products.yaml @@ -14,16 +14,16 @@ definition: - Sample Database - PUBLIC - PRODUCTS - filter: - - = - - {} - - - field + filters: + - - = - {} - - - Sample Database - - PUBLIC - - PRODUCTS - - CATEGORY - - Widget + - - field + - {} + - - Sample Database + - PUBLIC + - PRODUCTS + - CATEGORY + - Widget serdes/meta: - id: aB3kLmN9pQrStUvWxYz1a label: widget_products From 448bb0c3dfbc0b288011552155ce8426254e6fa7 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin Date: Tue, 31 Mar 2026 20:59:49 -0400 Subject: [PATCH 15/15] fix --- examples/v1/python_libraries/{common.py.yaml => shared.py.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename examples/v1/python_libraries/{common.py.yaml => shared.py.yaml} (89%) diff --git a/examples/v1/python_libraries/common.py.yaml b/examples/v1/python_libraries/shared.py.yaml similarity index 89% rename from examples/v1/python_libraries/common.py.yaml rename to examples/v1/python_libraries/shared.py.yaml index f9998b5..55e63ad 100644 --- a/examples/v1/python_libraries/common.py.yaml +++ b/examples/v1/python_libraries/shared.py.yaml @@ -1,5 +1,5 @@ entity_id: kb0QxR8AyP5W8SVHGYZr8 -path: common.py +path: shared.py source: |- def helper(): return 42