From 1e84302bb3ee8ee8e5e2792157b68720d88c5432 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Fri, 6 Nov 2026 05:14:21 +0000 Subject: [PATCH 1/2] Parse TRUNC and TRUNCATE's bare second argument as a column A bare identifier as TRUNC's second argument is a date part in Snowflake only when no column of that name is in scope: TRUNC(1, DAY) compiled with no table (receipt sf.functions.trunc2.ka4427f986c78), while TRUNC(x, s) with a column s truncated numerically (C's slice 1 cases trunc.trunc/trunc.truncate t001, t005, t006, t007). The parser cannot see scope, so it keeps the identifier as a column, as polyglot does, instead of rewriting date-part spellings to a date part. --- .../src/parser/_helpers/expressions/grouping.rs | 8 -------- crates/sqlquack-syntax/tests/parser/test_fixes.rs | 14 ++++++++------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/crates/sqlquack-syntax/src/parser/_helpers/expressions/grouping.rs b/crates/sqlquack-syntax/src/parser/_helpers/expressions/grouping.rs index 76981407d..6cec95e18 100644 --- a/crates/sqlquack-syntax/src/parser/_helpers/expressions/grouping.rs +++ b/crates/sqlquack-syntax/src/parser/_helpers/expressions/grouping.rs @@ -1860,14 +1860,6 @@ impl Parser { "DATE_TRUNC" | "DATETRUNC" if !args.is_empty() => Some(0), "DATEDIFF" | "TIMEDIFF" | "TIMESTAMPDIFF" if args.len() == TERNARY_ARITY => Some(0), "EXTRACT" if args.len() == BINARY_ARITY => Some(0), - "TRUNC" | "TRUNCATE" - if args.len() == BINARY_ARITY - && matches!(&args[1], Expression::Column(c) - if c.table.is_none() && !c.name.quoted) - && self.try_parse_date_part_unit_expr(&args[1]).is_some() => - { - Some(1) - } _ => None, }, _ => None, diff --git a/crates/sqlquack-syntax/tests/parser/test_fixes.rs b/crates/sqlquack-syntax/tests/parser/test_fixes.rs index 7e951b62f..498db414d 100644 --- a/crates/sqlquack-syntax/tests/parser/test_fixes.rs +++ b/crates/sqlquack-syntax/tests/parser/test_fixes.rs @@ -451,16 +451,18 @@ fn given_auditor_tree_findings_when_parsing_faithfully_then_the_tree_records_wha expected_value: json!("DAY"), }, ProjectionTestCase { - description: "TRUNC's date part is a date part", - sql: "SELECT TRUNC(1, DAY)", - pointer: "/function/args/1/var/this", + description: + "TRUNC's bare second argument stays a column, a date part only by the first's type", + sql: "SELECT TRUNC(x, DAY)", + pointer: "/function/args/1/column/name/name", expected_value: json!("DAY"), }, ProjectionTestCase { - description: "TRUNC's numeric scale column stays a column", - sql: "SELECT TRUNC(1, c1)", + description: + "TRUNCATE's scale column named like a date part abbreviation stays a column", + sql: "SELECT TRUNCATE(x, s)", pointer: "/function/args/1/column/name/name", - expected_value: json!("c1"), + expected_value: json!("s"), }, ProjectionTestCase { description: "unary plus keeps its operator", From 75a8d5bd88002da478672f1f871f5995380bddec Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Fri, 6 Nov 2026 05:17:15 +0000 Subject: [PATCH 2/2] coverage: re-record the syntax baseline on the TRUNC column parse Only change: sf.functions.trunc2 verified -> unverified, because its auditor review fingerprints the old tree of SELECT TRUNC ( 1 , DAY ). Satisfied obligations 68,585, parsed/refused cases and the 5,128 known parser/receipt disagreements are unchanged; no receipt verdict moves. The auditor renews the review under D118. --- coverage/syntax/baseline.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coverage/syntax/baseline.json b/coverage/syntax/baseline.json index 98c6abccb..0786c3971 100644 --- a/coverage/syntax/baseline.json +++ b/coverage/syntax/baseline.json @@ -15,7 +15,7 @@ "catalogue/utility.toml": "55b30dcf06bf8182232a0da6b1da75462ae171e015cc8c9b8b95b36a722b44c5", "sources.toml": "a180c722616dfefc1568edf41938a0abf491f5a89f9609a1f666a50aa5aead94" }, - "parser_tree": "2de58a44aca56391ee1dbe36a091556e469b7a9d", + "parser_tree": "cc21b65e16782fc53d833e5ec10a9bc3ba9fdc04", "forms": { "sf.classes.anomaly-detection.commands.create-anomaly-detection": "unverified", "sf.classes.anomaly-detection.commands.drop-anomaly-detection": "unverified", @@ -2637,7 +2637,7 @@ "sf.functions.trim": "verified", "sf.functions.trunc.trunc": "verified", "sf.functions.trunc.truncate": "verified", - "sf.functions.trunc2": "verified", + "sf.functions.trunc2": "unverified", "sf.functions.try-base64-decode-binary": "verified", "sf.functions.try-base64-decode-string": "verified", "sf.functions.try-cast": "verified",