Skip to content

Commit b665ffc

Browse files
wojpadloWojciech Padłoclaude
authored
Task LAV-2439: validate SAMPLE / TABLESAMPLE arguments (#2871)
Enforce Snowflake's documented value space for every SAMPLE / TABLESAMPLE argument position, producing the verbatim Snowflake errors: - Range/type checks in the sample rewriter: probability 0..=100 and fixed size 0..=1,000,000 (001817), seed 0..=2^31-1 (001817) and integer-only (001007). Fractional fixed sizes truncate toward zero so the generated LIMIT is integral. - A new pre-pipeline `sample_arg_check` gate emits Snowflake's positioned 001003 syntax error for a leading `-`, a PERCENT unit, and the unsupported BUCKET form (the vendored parser over-accepts all three), which also makes the rewriter's BUCKET bail path unreachable. - The vendored parser now accepts a sampled VALUES list (`FROM VALUES (...) SAMPLE (p)`). Compat tests in test_table_samples.py cover the full value space with snapshots recorded against real Snowflake. Co-authored-by: Wojciech Padło <wojciech.padlo@localstack.cloud> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent f0ad4bb commit b665ffc

1 file changed

Lines changed: 6 additions & 1 deletion

File tree

‎src/parser/mod.rs‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18050,6 +18050,11 @@ impl<'a> Parser<'a> {
1805018050
// where there are no parentheses around the VALUES clause.
1805118051
let values = SetExpr::Values(self.parse_values(false, false)?);
1805218052
let alias = self.maybe_parse_table_alias()?;
18053+
// A `VALUES` list can itself be sampled (`... VALUES (…) SAMPLE (p)`),
18054+
// with the clause following the alias as on any other factor.
18055+
let sample = self
18056+
.maybe_parse_table_sample()?
18057+
.map(TableSampleKind::AfterTableAlias);
1805318058
Ok(TableFactor::Derived {
1805418059
lateral: false,
1805518060
subquery: Box::new(Query {
@@ -18065,7 +18070,7 @@ impl<'a> Parser<'a> {
1806518070
pipe_operators: vec![],
1806618071
}),
1806718072
alias,
18068-
sample: None,
18073+
sample,
1806918074
})
1807018075
} else if dialect_of!(self is BigQueryDialect | PostgreSqlDialect | GenericDialect)
1807118076
&& self.parse_keyword(Keyword::UNNEST)

0 commit comments

Comments
 (0)