diff --git a/Cargo.lock b/Cargo.lock index ac5e0d42..4a6c4d54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -605,7 +605,7 @@ dependencies = [ [[package]] name = "polyglot-sql" -version = "0.13.5" +version = "0.13.6" dependencies = [ "criterion", "once_cell", @@ -624,7 +624,7 @@ dependencies = [ [[package]] name = "polyglot-sql-ast-derive" -version = "0.13.5" +version = "0.13.6" dependencies = [ "proc-macro2", "quote", @@ -633,7 +633,7 @@ dependencies = [ [[package]] name = "polyglot-sql-ffi" -version = "0.13.5" +version = "0.13.6" dependencies = [ "cbindgen", "polyglot-sql", @@ -643,11 +643,11 @@ dependencies = [ [[package]] name = "polyglot-sql-function-catalogs" -version = "0.13.5" +version = "0.13.6" [[package]] name = "polyglot-sql-python" -version = "0.13.5" +version = "0.13.6" dependencies = [ "polyglot-sql", "pyo3", @@ -658,7 +658,7 @@ dependencies = [ [[package]] name = "polyglot-sql-wasm" -version = "0.13.5" +version = "0.13.6" dependencies = [ "console_error_panic_hook", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index bb38d7ea..59bd6d81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ exclude = [ ] [workspace.package] -version = "0.13.5" +version = "0.13.6" edition = "2021" license = "MIT" authors = ["polyglot contributors"] diff --git a/README.md b/README.md index 225f2966..d9695225 100644 --- a/README.md +++ b/README.md @@ -306,7 +306,7 @@ If you want to disable `stacker` for a native Rust build, turn off default featu ```toml [dependencies] -polyglot-sql = { version = "0.13.5", default-features = false, features = ["all-dialects", "transpile"] } +polyglot-sql = { version = "0.13.6", default-features = false, features = ["all-dialects", "transpile"] } ``` That can reduce overhead slightly on trusted inputs, but you lose the default stack-growth protection for deeply nested SQL. diff --git a/crates/polyglot-sql-function-catalogs/README.md b/crates/polyglot-sql-function-catalogs/README.md index 157fb145..c677fdf6 100644 --- a/crates/polyglot-sql-function-catalogs/README.md +++ b/crates/polyglot-sql-function-catalogs/README.md @@ -25,7 +25,7 @@ With `polyglot-sql` compile-time wiring (recommended): ```toml [dependencies] -polyglot-sql = { version = "0.13.5", features = ["function-catalog-clickhouse"] } +polyglot-sql = { version = "0.13.6", features = ["function-catalog-clickhouse"] } ``` Then run schema validation with type checks: diff --git a/crates/polyglot-sql/Cargo.toml b/crates/polyglot-sql/Cargo.toml index c37b1d68..983d8774 100644 --- a/crates/polyglot-sql/Cargo.toml +++ b/crates/polyglot-sql/Cargo.toml @@ -100,14 +100,14 @@ function-catalog-all-dialects = [ [dependencies] regex = { version = "1", optional = true } -polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.13.5" } +polyglot-sql-ast-derive = { path = "../polyglot-sql-ast-derive", version = "0.13.6" } serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } unicode-segmentation = { workspace = true } stacker = { version = "0.1", optional = true } ts-rs = { version = "12.0", features = ["serde-compat"], optional = true } -polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.13.5", optional = true, default-features = false } +polyglot-sql-function-catalogs = { path = "../polyglot-sql-function-catalogs", version = "0.13.6", optional = true, default-features = false } [dev-dependencies] pretty_assertions = "1.4" diff --git a/crates/polyglot-sql/README.md b/crates/polyglot-sql/README.md index c5fe2ebd..01c87eff 100644 --- a/crates/polyglot-sql/README.md +++ b/crates/polyglot-sql/README.md @@ -25,12 +25,12 @@ By default, `polyglot-sql` enables the full public API. Parser-only consumers ca disable default features and opt into only the dialect parsers they need: ```toml -polyglot-sql = { version = "0.13.5", default-features = false } +polyglot-sql = { version = "0.13.6", default-features = false } ``` ```toml polyglot-sql = { - version = "0.13.5", + version = "0.13.6", default-features = false, features = ["dialect-clickhouse"], } @@ -44,14 +44,14 @@ Examples: ```toml # Parse and generate SQL for one dialect. polyglot-sql = { - version = "0.13.5", + version = "0.13.6", default-features = false, features = ["generate", "dialect-clickhouse"], } # Cross-dialect transpilation. polyglot-sql = { - version = "0.13.5", + version = "0.13.6", default-features = false, features = ["transpile", "dialect-clickhouse", "dialect-postgresql"], } diff --git a/crates/polyglot-sql/src/validation.rs b/crates/polyglot-sql/src/validation.rs index 4ba0b2a2..7b067be5 100644 --- a/crates/polyglot-sql/src/validation.rs +++ b/crates/polyglot-sql/src/validation.rs @@ -4560,14 +4560,15 @@ pub fn validate_parsed_with_schema( if options.check_types { // Give the type checker star-sourced column types for every query. // Ordered CTE/source star expansion is the cheap lineage path; full - // qualification is only needed for stars it cannot resolve, such as - // stars over derived tables. Open/partial schemas remain conservative. - if has_projection_star(&statement) { + // qualification is only needed for unresolved stars that another scope + // consumes, such as a star over a derived table inside a subquery. + // Open/partial schemas remain conservative. + if has_projection_star(&statement, false) { crate::lineage::expand_cte_stars( &mut statement, Some(&resolver_schema as &dyn crate::schema::Schema), ); - if has_projection_star(&statement) { + if has_projection_star(&statement, true) { if let Ok(qualified) = crate::optimizer::qualify_schema_aware_expression( statement.clone(), &resolver_schema, @@ -4604,9 +4605,20 @@ pub fn validate_parsed_with_schema( ValidationResult::with_errors(all_errors) } -fn has_projection_star(statement: &Expression) -> bool { +/// Whether any SELECT projects a star. With `consumed_only`, the root SELECT's +/// own projection is ignored: its star feeds no expression in the statement, so +/// only stars read by an outer scope or a set operation affect type checks. +fn has_projection_star(statement: &Expression, consumed_only: bool) -> bool { + let root = match statement { + Expression::Select(select) if consumed_only => { + Some(select.as_ref() as *const crate::expressions::Select) + } + _ => None, + }; statement.dfs().any(|node| { - matches!(node, Expression::Select(select) if select.expressions.iter().any(|projection| { + matches!(node, Expression::Select(select) + if root != Some(select.as_ref() as *const crate::expressions::Select) + && select.expressions.iter().any(|projection| { let mut projection = projection; loop { match projection { diff --git a/crates/polyglot-sql/src/validation/tests.rs b/crates/polyglot-sql/src/validation/tests.rs index 13a198f5..ac16cffb 100644 --- a/crates/polyglot-sql/src/validation/tests.rs +++ b/crates/polyglot-sql/src/validation/tests.rs @@ -1136,6 +1136,8 @@ fn star_sourced_types_are_checked_without_set_operations() { "WITH a AS (SELECT * FROM orders) SELECT 1 FROM a JOIN orders AS o ON a.s = o.i", "WITH a AS (SELECT * FROM orders), b AS (SELECT * FROM a) SELECT i FROM b WHERE s = i", "SELECT 1 FROM (SELECT * FROM orders) AS a JOIN orders AS o ON a.s = o.i", + "SELECT * FROM (SELECT o.s = p.i AS x FROM orders AS o JOIN orders AS p ON TRUE) AS a", + "SELECT * FROM (SELECT * FROM orders) AS a WHERE a.s = a.i", ] { let result = validate_with_schema( sql, diff --git a/examples/rust/Cargo.lock b/examples/rust/Cargo.lock index c70b2093..973b2c3c 100644 --- a/examples/rust/Cargo.lock +++ b/examples/rust/Cargo.lock @@ -71,7 +71,7 @@ dependencies = [ [[package]] name = "polyglot-sql" -version = "0.13.5" +version = "0.13.6" dependencies = [ "polyglot-sql-ast-derive", "polyglot-sql-function-catalogs", @@ -85,7 +85,7 @@ dependencies = [ [[package]] name = "polyglot-sql-ast-derive" -version = "0.13.5" +version = "0.13.6" dependencies = [ "proc-macro2", "quote", @@ -101,7 +101,7 @@ dependencies = [ [[package]] name = "polyglot-sql-function-catalogs" -version = "0.13.5" +version = "0.13.6" [[package]] name = "proc-macro2" diff --git a/examples/rust/Cargo.toml b/examples/rust/Cargo.toml index c90ba3b2..1764682a 100644 --- a/examples/rust/Cargo.toml +++ b/examples/rust/Cargo.toml @@ -5,4 +5,4 @@ edition = "2021" publish = false [dependencies] -polyglot-sql = { version = "0.13.5", path = "../../crates/polyglot-sql" } +polyglot-sql = { version = "0.13.6", path = "../../crates/polyglot-sql" } diff --git a/packages/documentation/package.json b/packages/documentation/package.json index e9acc43d..e33858c3 100644 --- a/packages/documentation/package.json +++ b/packages/documentation/package.json @@ -1,6 +1,6 @@ { "name": "@polyglot-sql/documentation", - "version": "0.13.5", + "version": "0.13.6", "private": true, "type": "module", "scripts": { diff --git a/packages/go/README.md b/packages/go/README.md index 7d093f0c..79887ea7 100644 --- a/packages/go/README.md +++ b/packages/go/README.md @@ -21,7 +21,7 @@ go get github.com/tobilg/polyglot/packages/go ``` Go module releases use nested tags that match the root Polyglot release, for -example `packages/go/v0.13.5`. +example `packages/go/v0.13.6`. ## Native Library Setup diff --git a/packages/go/types.go b/packages/go/types.go index ee9117e8..fe1eddc2 100644 --- a/packages/go/types.go +++ b/packages/go/types.go @@ -2,7 +2,7 @@ package polyglot import "encoding/json" -const sdkVersion = "0.13.5" +const sdkVersion = "0.13.6" func Version() string { return sdkVersion diff --git a/packages/playground/package.json b/packages/playground/package.json index 4f53b638..db70d002 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -1,6 +1,6 @@ { "name": "@polyglot-sql/playground", - "version": "0.13.5", + "version": "0.13.6", "private": true, "type": "module", "scripts": { diff --git a/packages/python-docs/package.json b/packages/python-docs/package.json index 0365ccae..f544f4bc 100644 --- a/packages/python-docs/package.json +++ b/packages/python-docs/package.json @@ -1,6 +1,6 @@ { "name": "@polyglot-sql/python-docs", - "version": "0.13.5", + "version": "0.13.6", "private": true, "type": "module", "scripts": { diff --git a/packages/sdk/package.json b/packages/sdk/package.json index cb1ee5f5..4f47c171 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@polyglot-sql/sdk", - "version": "0.13.5", + "version": "0.13.6", "description": "SQL dialect translator powered by WebAssembly", "type": "module", "main": "./dist/index.cjs",