Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 34 additions & 34 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -174,22 +174,22 @@ sqlbuild-scopes = { path = "crates/sqlbuild-scopes" }
sqlbuild-sqltext = { path = "crates/sqlbuild-sqltext" }
sqlbuild-state = { path = "crates/sqlbuild-state" }
# SQL lint Rules, quality Rules and the formatter.
sqlclean = { git = "https://github.com/sqlstack-io/sqlclean.git", rev = "a4a006bd9e5849af6bf477814646ce921299a8a1" }
sqlclean = { git = "https://github.com/sqlstack-io/sqlclean.git", rev = "be41ae207344e127db81aa42d6a951682c3f35fa" }
# SQL change fingerprints over SQLQuack's tokenizers.
sqlquack-fingerprint = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlite", "sqlserver"] }
sqlquack-fingerprint = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlite", "sqlserver"] }
# Scopes, name resolution, types and lineage for the native analysis route.
sqlquack-semantics = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da", features = ["bigquery", "clickhouse", "databricks", "duckdb", "postgres", "snowflake", "sqlite", "sqlserver"] }
sqlquack-semantics = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66", features = ["bigquery", "clickhouse", "databricks", "duckdb", "postgres", "snowflake", "sqlite", "sqlserver"] }
# SQLQuack's Snowflake-family parser and tokenizer, reached as SQLQuack exposes them.
sqlquack-parse = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-parse = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
# SQLQuack's syntax tree and lossless tokens.
sqlquack-syntax = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax-bigquery = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax-clickhouse = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax-databricks = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax-duckdb = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax-postgres = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax-sqlite = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax-sqlserver = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "56c7c15ecafe61ea6650159469234db670dea8da" }
sqlquack-syntax = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
sqlquack-syntax-bigquery = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
sqlquack-syntax-clickhouse = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
sqlquack-syntax-databricks = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
sqlquack-syntax-duckdb = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
sqlquack-syntax-postgres = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
sqlquack-syntax-sqlite = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
sqlquack-syntax-sqlserver = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" }
stacker = "0.1"
syn = { version = "2", features = ["full", "visit", "extra-traits"] }
subtle = "2"
Expand Down
6 changes: 3 additions & 3 deletions benchmarks/duckshop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ project and does not change it:
`edge_running_peaks`, that a pre-hook of `int_edge_basket_running_peaks` creates
(`models/intermediate/edge_cases/_sqlbuild/_hooks/sql/`) and SQLBuild does not declare.

It has 161 models (13 staging, 134 intermediate, 14 marts), 5 Python functions, a SQL table
function, a hook-created JavaScript function, 186 unit tests and 4 scenarios, in nine groups:
It has 164 models (13 staging, 137 intermediate, 14 marts), 5 Python functions, a SQL table
function, a hook-created JavaScript function, 189 unit tests and 4 scenarios, in nine groups:

| Group | Covers |
|-------|--------|
Expand All @@ -134,7 +134,7 @@ function, a hook-created JavaScript function, 186 unit tests and 4 scenarios, in
| VARIANT comparisons | `ARRAY_MAX`, `ARRAY_MIN` and `ARRAY_REVERSE` over arrays mixing numbers, strings, booleans, JSON nulls and integers past 2^53; `MAX` across kinds and non-ASCII strings; `=` and `EQUAL_NULL` for `1`, `"1"` and `1.0`, reordered keys, JSON null and DATE or TIMESTAMP values held in a `VARIANT` against their text; `MIN_BY` and `MAX_BY` of `VARIANT` values; `PARTITION BY`, `SELECT DISTINCT` and `ARRAY_AGG(DISTINCT)` over `VARIANT`; JSON nulls in `ARRAY_REMOVE`, `ARRAY_DISTINCT` and `ARRAYS_OVERLAP`; decimals with trailing zeros in `ARRAY_CONTAINS` and `ARRAY_POSITION`; `OBJECT_CONSTRUCT(* EXCLUDE ("note"))` |
| Dates and times | `TRY_TO_TIMESTAMP_NTZ` and its siblings over free text; epoch milliseconds as numbers and text; daylight-saving gaps and overlaps; fractional offsets; nanosecond truncation and epoch parts after 2242; pre-1970 text with sub-microsecond digits; date-part normalisation; month ends and leap days; week numbering across a year; sentinel timestamps; `TRY_TO_DATE` with numeric and month-name formats over unpadded fields, two-digit years, ISO `T` and `Z`, trailing letters, a long s, mixed separators and runs of spaces; text read as `TIMESTAMP_TZ` and `TIMESTAMP_LTZ` with `T`, `Z`, `+00:00`, `+0000`, `+09:00` and `-05:30`, back as the UTC instant, date, year and day start, and compared with text, `TIMESTAMP_NTZ` and `DATE`; `FIRST_VALUE` of a zoned value as a `DATE`; `DATEADD` and `TIMEADD` on `TIME(3)` and the type they return; `DATEDIFF` across units; `TIME(9)`, `FF3` and bare `FF` formats truncating; `DATE`, `TO_TIME`, `TRY_TO_TIMESTAMP` and `TO_TIMESTAMP_LTZ` of clock text, and `CURRENT_DATE` and `SYSDATE` read only for facts that hold on any day |
| Ordering, numbers and text | NULL ordering under `DESC`; ties in ordered aggregates, `MAX_BY`, `MODE` and `ANY_VALUE`; default window frames; `UNION ALL BY NAME`; `ROUND` half-way values, decimal division, `MOD` and 38-digit amounts; integers past 2^53 against `FLOAT`; regular expressions and backslash escapes; `LIKE ... ESCAPE` and `ILIKE ANY`; `SPLIT_PART` and `SUBSTR` before the start; `NOT IN` with a NULL; names in many scripts; `JOIN ... USING` between `NUMBER(18,0)`, `NUMBER(38,0)` and text keys, with the types of the merged and qualified keys; NULL arithmetic and the types of NULL, decimal and exponent literals, `COUNT`, `ROW_NUMBER`, `%` and `NULLIF`; `MEDIAN` at scales 0 to 15; `DIV0` by literal zeros; `MODE`, `MEDIAN` and `COUNT_IF` over no rows; aggregates inside window functions and `QUALIFY`; `ROLLUP` totals; `TRUNC` of `FLOAT`; infinity words in other scripts; `CASE` without `ELSE` and `DECODE` over text; regular expressions with a `?` after a lazy quantifier, classes opening with `]`, empty matches and `.` against a carriage return; case-insensitive matches outside ASCII; `ILIKE` with a long s; `JAROWINKLER_SIMILARITY` of accented names in both cases; Base64 text with line feeds; `STARTSWITH`, `ENDSWITH`, `SUBSTRING`, `POSITION` with `IN` and with a comma, `CHARINDEX`, `CHR`, `REGEXP_SUBSTR_ALL`, `::STRING` and `CAST ... AS STRING`; `HEX_ENCODE`, `HEX_DECODE_STRING`, `TRY_HEX_DECODE_STRING` and `TRY_BASE64_DECODE_BINARY`; a comment attached to a text literal; `FLOOR` with and without a scale, `BITAND`, `ZEROIFNULL`, `::BIGINT` and `::DOUBLE`; `IS NOT DISTINCT FROM` and `EQUAL_NULL`; a comma join after an explicit join; `HASH_AGG` read in two row orders |
| Lineage and analysis | clauses whose columns decide rows without being output (`WHERE`, `QUALIFY`, `GROUP BY` by position and `ALL`, `ORDER BY` under `LIMIT`, `EXISTS`, a `FLATTEN` input, `ROLLUP` by position, `EXCEPT` under `LIMIT`); `RIGHT JOIN ... USING`, `NATURAL JOIN`, a `USING` key under a later outer join, and unmatched `ASOF JOIN` rows; `CONNECT BY` beside a column named `level`; a recursive CTE without `RECURSIVE` whose columns shift per iteration; `LAST_DAY` with a date part; positional columns and the names Snowflake gives unaliased expressions; `TEXT(5)` and widened `COUNT` contracts |
| Lineage and analysis | clauses whose columns decide rows without being output (`WHERE`, `QUALIFY`, `GROUP BY` by position and `ALL`, `ORDER BY` under `LIMIT`, `EXISTS`, a `FLATTEN` input, `ROLLUP` by position, `EXCEPT` under `LIMIT`); `RIGHT JOIN ... USING`, `NATURAL JOIN`, a `USING` key under a later outer join, and unmatched `ASOF JOIN` rows; `CONNECT BY` beside a column named `level`; a recursive CTE without `RECURSIVE` whose columns shift per iteration; `LAST_DAY` with a date part; positional columns and the names Snowflake gives unaliased expressions; `TEXT(5)` and widened `COUNT` contracts; `LAG` and `LEAD` with one, two and three arguments; a comma-joined `LATERAL` whose nested derived table reads the left item; untyped and typed `FILTER` lambdas over `ARRAY_AGG` in a grouped query |
| Python functions | volatile tokens and numbers from a column, a constant and no argument, and `DIV0` of a volatile call beside look-alike names, checked by assertions that hold for any values; a handler answering NULL input without `STRICT`; Python `None` as JSON null, and datetimes, Decimals and integers past 2^53 handed to `VARIANT` and `FLOAT` results |
| Scenarios and lifecycle | typed values across model boundaries; `VARIANT` expected output; a star under a lower-case contract and a quoted camelCase export; a snapshot keyed and compared on quoted camelCase columns; a cursor-window incremental model over far-apart fixture loads; a change log merged across two loads, checked against a full rebuild |
| Translation refusals | one model per construct that translation tools refuse or guard, most putting a construct refused only under strict checking before one refused by default, so a model shows both: `FLOAT` values through sums, averages, running totals, arrays, objects, `HASH`, `TO_CHAR` and `::NUMBER(38, 10)`; `VARIANT` dates, decimals and XML; `ARRAY_AGG` without `WITHIN GROUP`, sparse arrays and `ARRAY(NUMBER)` casts; `REDUCE`, `FILTER` and `TRANSFORM` lambdas; patterns and `REGEXP_REPLACE` replacements built from columns, and lazy patterns; `TRY_TO_DATE` with a format from a column; zoned literals, `CONVERT_TIMEZONE` from `CURRENT_TIMESTAMP`, `SEQ8`, `GENERATOR` with an expression `ROWCOUNT`; `PIVOT`, `ANY_VALUE`, `IGNORE NULLS` around `IFF`, unaliased columns read by Snowflake's name, `UNION` branches whose column is always NULL; `TO_NUMBER`, `TO_DECIMAL` and `TRY_BASE64_DECODE_BINARY`; an open (uncontracted) source `edge__supplier_notes`, the table function, read for one basket and after `LATERAL` for every basket, and the hook-created function. `rpt_edge_case_model_keys` and `rpt_edge_case_array_model_keys` read every model in the group, so a refusal there also refuses a downstream model |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
MODEL (
description """
One row per basket with the number of its red lines and of its SKUs longer than nine characters,
counted by an untyped and a typed FILTER lambda over ARRAY_AGG in the grouped query
""",
tags [edge_case],
columns (
basket_id (type VARCHAR, nullable false, audits [not_null, unique]),
red_line_count (type NUMBER(38, 0)),
long_sku_count (type NUMBER(38, 0)),
),
);

WITH final AS (
SELECT
l.basket_id,
ARRAY_SIZE(
FILTER(
ARRAY_AGG(l.sku) WITHIN GROUP (ORDER BY l.line_no, l.line_id),
s -> s::VARCHAR LIKE 'DK-RED-%'
)
)::NUMBER(38, 0) AS red_line_count,
ARRAY_SIZE(
FILTER(
ARRAY_AGG(l.sku) WITHIN GROUP (ORDER BY l.line_no, l.line_id),
s VARCHAR -> LENGTH(s) > 9
)
)::NUMBER(38, 0) AS long_sku_count
FROM __ref("stg_edge_basket_lines") AS l
GROUP BY
l.basket_id
)

SELECT *
FROM final
Loading
Loading