From 4d8f22f22d31f950477e8b6b51587bb92271ba1a Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Thu, 12 Nov 2026 05:56:01 +0000 Subject: [PATCH 1/3] fix(deps): pin SQLQuack 0.6.0 All six direct sqlquack-* pins (11 locked packages) move from e1a583eb (0.5.1) to 8d28aa4c (0.6.0), so SQLBuild can link one SQLQuack copy. Work in progress: SQLQuack 0.6.0 changes the formatter's layout, and the format expectations are not updated yet. --- Cargo.lock | 44 ++++++++++++++++++++++---------------------- Cargo.toml | 12 ++++++------ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6eff6ae..146ceef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -612,8 +612,8 @@ dependencies = [ [[package]] name = "sqlquack-derive" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "proc-macro2", "quote", @@ -622,8 +622,8 @@ dependencies = [ [[package]] name = "sqlquack-fingerprint" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "sha2", "sqlquack-parse", @@ -632,8 +632,8 @@ dependencies = [ [[package]] name = "sqlquack-format" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "serde_json", "sqlquack-parse", @@ -642,8 +642,8 @@ dependencies = [ [[package]] name = "sqlquack-lint" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "rayon", "rustc-hash", @@ -655,8 +655,8 @@ dependencies = [ [[package]] name = "sqlquack-parse" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "sqlquack-syntax", "sqlquack-syntax-bigquery", @@ -668,8 +668,8 @@ dependencies = [ [[package]] name = "sqlquack-syntax" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "serde", "serde_json", @@ -681,8 +681,8 @@ dependencies = [ [[package]] name = "sqlquack-syntax-bigquery" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "sqlquack-syntax", "stacker", @@ -690,8 +690,8 @@ dependencies = [ [[package]] name = "sqlquack-syntax-databricks" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "sqlquack-syntax", "stacker", @@ -699,8 +699,8 @@ dependencies = [ [[package]] name = "sqlquack-syntax-postgres" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "sqlquack-syntax", "stacker", @@ -708,8 +708,8 @@ dependencies = [ [[package]] name = "sqlquack-syntax-snowflake" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "serde", "serde_json", @@ -721,8 +721,8 @@ dependencies = [ [[package]] name = "sqlquack-syntax-sqlserver" -version = "0.5.1" -source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=e1a583eb6d4180ff4121ef82b3f08b2982edca66#e1a583eb6d4180ff4121ef82b3f08b2982edca66" +version = "0.6.0" +source = "git+https://github.com/sqlstack-io/sqlquack.git?rev=8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a#8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" dependencies = [ "sqlquack-syntax", "stacker", diff --git a/Cargo.toml b/Cargo.toml index c3658cd..bd2ce81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,12 +30,12 @@ sha2 = "0.10" similar = "2" sqlclean = { path = "crates/sqlclean" } # SQLQuack's formatter and lint engine, and the tokens and trees they read, which replace Polyglot. -sqlquack-fingerprint = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlite", "sqlserver"] } -sqlquack-format = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlserver"] } -sqlquack-lint = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlite"] } -sqlquack-parse = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" } -sqlquack-syntax = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" } -sqlquack-syntax-sqlserver = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "e1a583eb6d4180ff4121ef82b3f08b2982edca66" } +sqlquack-fingerprint = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlite", "sqlserver"] } +sqlquack-format = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlserver"] } +sqlquack-lint = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a", features = ["bigquery", "databricks", "duckdb", "postgres", "snowflake", "sqlite"] } +sqlquack-parse = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" } +sqlquack-syntax = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" } +sqlquack-syntax-sqlserver = { git = "https://github.com/sqlstack-io/sqlquack.git", rev = "8d28aa4c4b6c3d8c5345ddef3d620fa24e26741a" } [workspace.lints.rust] unsafe_code = "forbid" From 7d9969187c429f4dfd1bce535bee69e8b3aec308 Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Thu, 12 Nov 2026 06:08:02 +0000 Subject: [PATCH 2/3] feat(format): lay out clauses, parenthesised groups and windows as SQLQuack 0.6.0 does SQLQuack 0.6.0 changes three layout rules, and SQLClean's formatter is SQLQuack's: - A clause with a single short item stays on its header line (ORDER BY a DESC, GROUP BY customer_id, JOIN b ON b.id = a.id). - A parenthesised group that spans lines gets its own lines instead of hugging the call's parenthesis (ARRAY(\n (\n SELECT ...)). - A window specification too wide for one line is broken into PARTITION BY, ORDER BY and frame lines. Parse errors now name what was expected ("Expected an expression after BY") instead of the unexpected token. The format corpus records the old layout as previously_formatted, and one SQL Server departure is dropped because SQLQuack now matches SQLClean's recorded layout. --- .../tests/fixtures/format_corpus.json | 151 ++++++++++++------ .../tests/fixtures/sqlquack_departures.json | 13 +- .../src/sql_lint/tests/test_layout_rules.rs | 2 +- .../sql_lint/tests/test_values_formatter.rs | 2 +- 4 files changed, 103 insertions(+), 65 deletions(-) diff --git a/crates/sqlclean/src/sql_lint/tests/fixtures/format_corpus.json b/crates/sqlclean/src/sql_lint/tests/fixtures/format_corpus.json index b45dd71..e9701cb 100644 --- a/crates/sqlclean/src/sql_lint/tests/fixtures/format_corpus.json +++ b/crates/sqlclean/src/sql_lint/tests/fixtures/format_corpus.json @@ -77,7 +77,8 @@ { "dialect": "bigquery", "sql": "SELECT x, 1 AS y GROUP BY 1 ORDER BY 1", - "formatted": "SELECT\n x,\n 1 AS y\nGROUP BY\n 1\nORDER BY\n 1" + "formatted": "SELECT\n x,\n 1 AS y\nGROUP BY 1\nORDER BY 1", + "previously_formatted": "SELECT\n x,\n 1 AS y\nGROUP BY\n 1\nORDER BY\n 1" }, { "dialect": "bigquery", @@ -262,7 +263,8 @@ { "dialect": "bigquery", "sql": "SELECT y + 1 FROM x GROUP BY y + 1 ORDER BY 1", - "formatted": "SELECT y + 1\nFROM x\nGROUP BY\n y + 1\nORDER BY\n 1" + "formatted": "SELECT y + 1\nFROM x\nGROUP BY y + 1\nORDER BY 1", + "previously_formatted": "SELECT y + 1\nFROM x\nGROUP BY\n y + 1\nORDER BY\n 1" }, { "dialect": "bigquery", @@ -287,12 +289,14 @@ { "dialect": "bigquery", "sql": "SELECT ARRAY((SELECT AS STRUCT 1 AS a, 2 AS b))", - "formatted": "SELECT\n ARRAY((\n SELECT AS STRUCT\n 1 AS a,\n 2 AS b\n ))" + "formatted": "SELECT\n ARRAY(\n (\n SELECT AS STRUCT\n 1 AS a,\n 2 AS b\n )\n )", + "previously_formatted": "SELECT\n ARRAY((\n SELECT AS STRUCT\n 1 AS a,\n 2 AS b\n ))" }, { "dialect": "bigquery", "sql": "SELECT ARRAY((SELECT AS STRUCT 1 AS a, 2 AS b) LIMIT 10)", - "formatted": "SELECT\n ARRAY((\n SELECT AS STRUCT\n 1 AS a,\n 2 AS b\n ) LIMIT 10)" + "formatted": "SELECT\n ARRAY(\n (\n SELECT AS STRUCT\n 1 AS a,\n 2 AS b\n ) LIMIT 10\n )", + "previously_formatted": "SELECT\n ARRAY((\n SELECT AS STRUCT\n 1 AS a,\n 2 AS b\n ) LIMIT 10)" }, { "dialect": "bigquery", @@ -434,14 +438,14 @@ { "dialect": "bigquery", "sql": "SELECT y + 1 z FROM x GROUP BY y + 1 ORDER BY z", - "formatted": "SELECT y + 1 z\nFROM x\nGROUP BY\n y + 1\nORDER BY\n z", - "previously_formatted": "SELECT\n y + 1 AS z\nFROM x\nGROUP BY\n y + 1\nORDER BY\n z" + "formatted": "SELECT y + 1 z\nFROM x\nGROUP BY y + 1\nORDER BY z", + "previously_formatted": "SELECT y + 1 z\nFROM x\nGROUP BY\n y + 1\nORDER BY\n z" }, { "dialect": "bigquery", "sql": "SELECT y + 1 z FROM x GROUP BY y + 1", - "formatted": "SELECT y + 1 z\nFROM x\nGROUP BY\n y + 1", - "previously_formatted": "SELECT\n y + 1 AS z\nFROM x\nGROUP BY\n y + 1" + "formatted": "SELECT y + 1 z\nFROM x\nGROUP BY y + 1", + "previously_formatted": "SELECT y + 1 z\nFROM x\nGROUP BY\n y + 1" }, { "dialect": "bigquery", @@ -498,7 +502,8 @@ { "dialect": "bigquery", "sql": "SELECT * FROM GAP_FILL(TABLE device_data, ts_column => 'time', bucket_width => INTERVAL '1' MINUTE, value_columns => [('signal', 'locf')]) ORDER BY time", - "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'locf')]\n)\nORDER BY\n time" + "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'locf')]\n)\nORDER BY time", + "previously_formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'locf')]\n)\nORDER BY\n time" }, { "dialect": "bigquery", @@ -508,27 +513,32 @@ { "dialect": "bigquery", "sql": "SELECT * FROM GAP_FILL(TABLE device_data, ts_column => 'time', bucket_width => INTERVAL '1' MINUTE, value_columns => [('signal', 'linear')], ignore_null_values => FALSE) ORDER BY time", - "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'linear')],\n ignore_null_values => FALSE\n)\nORDER BY\n time" + "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'linear')],\n ignore_null_values => FALSE\n)\nORDER BY time", + "previously_formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'linear')],\n ignore_null_values => FALSE\n)\nORDER BY\n time" }, { "dialect": "bigquery", "sql": "SELECT * FROM GAP_FILL(TABLE device_data, ts_column => 'time', bucket_width => INTERVAL '1' MINUTE) ORDER BY time", - "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE\n)\nORDER BY\n time" + "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE\n)\nORDER BY time", + "previously_formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE\n)\nORDER BY\n time" }, { "dialect": "bigquery", "sql": "SELECT * FROM GAP_FILL(TABLE device_data, ts_column => 'time', bucket_width => INTERVAL '1' MINUTE, value_columns => [('signal', 'null')], origin => CAST('2023-11-01 09:30:01' AS DATETIME)) ORDER BY time", - "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'null')],\n origin => CAST('2023-11-01 09:30:01' AS DATETIME)\n)\nORDER BY\n time" + "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'null')],\n origin => CAST('2023-11-01 09:30:01' AS DATETIME)\n)\nORDER BY time", + "previously_formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'null')],\n origin => CAST('2023-11-01 09:30:01' AS DATETIME)\n)\nORDER BY\n time" }, { "dialect": "bigquery", "sql": "SELECT * FROM GAP_FILL(TABLE device_data, ts_column => 'time', bucket_width => INTERVAL '1' MINUTE, value_columns => [('signal', 'locf')]) ORDER BY time", - "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'locf')]\n)\nORDER BY\n time" + "formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'locf')]\n)\nORDER BY time", + "previously_formatted": "SELECT *\nFROM GAP_FILL(\n TABLE device_data,\n ts_column => 'time',\n bucket_width => INTERVAL '1' MINUTE,\n value_columns => [('signal', 'locf')]\n)\nORDER BY\n time" }, { "dialect": "bigquery", "sql": "SELECT * FROM ML.PREDICT(MODEL mydataset.mymodel, (SELECT label, column1, column2 FROM mydataset.mytable))", - "formatted": "SELECT *\nFROM ML.PREDICT(MODEL mydataset.mymodel, (\n SELECT\n label,\n column1,\n column2\n FROM mydataset.mytable\n))" + "formatted": "SELECT *\nFROM ML.PREDICT(\n MODEL mydataset.mymodel,\n (\n SELECT\n label,\n column1,\n column2\n FROM mydataset.mytable\n )\n)", + "previously_formatted": "SELECT *\nFROM ML.PREDICT(MODEL mydataset.mymodel, (\n SELECT\n label,\n column1,\n column2\n FROM mydataset.mytable\n))" }, { "dialect": "bigquery", @@ -548,7 +558,8 @@ { "dialect": "bigquery", "sql": "SELECT * FROM ML.PREDICT(MODEL `my_project`.my_dataset.my_model, (SELECT * FROM input_data))", - "formatted": "SELECT *\nFROM ML.PREDICT(MODEL `my_project`.my_dataset.my_model, (\n SELECT *\n FROM input_data\n))" + "formatted": "SELECT *\nFROM ML.PREDICT(\n MODEL `my_project`.my_dataset.my_model,\n (\n SELECT *\n FROM input_data\n )\n)", + "previously_formatted": "SELECT *\nFROM ML.PREDICT(MODEL `my_project`.my_dataset.my_model, (\n SELECT *\n FROM input_data\n))" }, { "dialect": "bigquery", @@ -563,7 +574,8 @@ { "dialect": "bigquery", "sql": "SELECT * FROM ML.FEATURES_AT_TIME((SELECT 1), num_rows => 1)", - "formatted": "SELECT *\nFROM ML.FEATURES_AT_TIME((\n SELECT 1\n), num_rows => 1)" + "formatted": "SELECT *\nFROM ML.FEATURES_AT_TIME(\n (\n SELECT 1\n ),\n num_rows => 1\n)", + "previously_formatted": "SELECT *\nFROM ML.FEATURES_AT_TIME((\n SELECT 1\n), num_rows => 1)" }, { "dialect": "bigquery", @@ -608,7 +620,8 @@ { "dialect": "bigquery", "sql": "SELECT * FROM ML.FORECAST(MODEL `mydataset.mymodel`, (SELECT * FROM mydataset.query_table), STRUCT())", - "formatted": "SELECT *\nFROM ML.FORECAST(MODEL `mydataset.mymodel`, (\n SELECT *\n FROM mydataset.query_table\n), STRUCT())" + "formatted": "SELECT *\nFROM ML.FORECAST(\n MODEL `mydataset.mymodel`,\n (\n SELECT *\n FROM mydataset.query_table\n ),\n STRUCT()\n)", + "previously_formatted": "SELECT *\nFROM ML.FORECAST(MODEL `mydataset.mymodel`, (\n SELECT *\n FROM mydataset.query_table\n), STRUCT())" }, { "dialect": "bigquery", @@ -688,7 +701,8 @@ { "dialect": "bigquery", "sql": "SELECT JSON_OBJECT(['a', 'b'], [STRUCT(10 AS id, 'Red' AS color), STRUCT(20 AS id, 'Blue' AS color)]) AS json_data", - "formatted": "SELECT\n JSON_OBJECT(['a', 'b'], [\n STRUCT(10 AS id, 'Red' AS color),\n STRUCT(20 AS id, 'Blue' AS color)\n ]) AS json_data" + "formatted": "SELECT\n JSON_OBJECT(\n ['a', 'b'],\n [\n STRUCT(10 AS id, 'Red' AS color),\n STRUCT(20 AS id, 'Blue' AS color)\n ]\n ) AS json_data", + "previously_formatted": "SELECT\n JSON_OBJECT(['a', 'b'], [\n STRUCT(10 AS id, 'Red' AS color),\n STRUCT(20 AS id, 'Blue' AS color)\n ]) AS json_data" }, { "dialect": "bigquery", @@ -698,7 +712,8 @@ { "dialect": "bigquery", "sql": "SELECT MOD((SELECT 1), 2)", - "formatted": "SELECT\n MOD((\n SELECT 1\n ), 2)" + "formatted": "SELECT\n MOD(\n (\n SELECT 1\n ),\n 2\n )", + "previously_formatted": "SELECT\n MOD((\n SELECT 1\n ), 2)" }, { "dialect": "bigquery", @@ -758,7 +773,8 @@ { "dialect": "bigquery", "sql": "SELECT a, GROUP_CONCAT(b) FROM table GROUP BY a", - "formatted": "SELECT\n a,\n GROUP_CONCAT(b)\nFROM table\nGROUP BY\n a" + "formatted": "SELECT\n a,\n GROUP_CONCAT(b)\nFROM table\nGROUP BY a", + "previously_formatted": "SELECT\n a,\n GROUP_CONCAT(b)\nFROM table\nGROUP BY\n a" }, { "dialect": "bigquery", @@ -913,7 +929,8 @@ { "dialect": "databricks", "sql": "SELECT col1 FROM t CLUSTER BY col1", - "formatted": "SELECT col1\nFROM t\nCLUSTER BY\n col1" + "formatted": "SELECT col1\nFROM t\nCLUSTER BY col1", + "previously_formatted": "SELECT col1\nFROM t\nCLUSTER BY\n col1" }, { "dialect": "databricks", @@ -1023,7 +1040,8 @@ { "dialect": "databricks", "sql": "SELECT test, LISTAGG(email, '') AS Email FROM organizations GROUP BY test", - "formatted": "SELECT\n test,\n LISTAGG(email, '') AS Email\nFROM organizations\nGROUP BY\n test" + "formatted": "SELECT\n test,\n LISTAGG(email, '') AS Email\nFROM organizations\nGROUP BY test", + "previously_formatted": "SELECT\n test,\n LISTAGG(email, '') AS Email\nFROM organizations\nGROUP BY\n test" }, { "dialect": "databricks", @@ -1268,7 +1286,8 @@ { "dialect": "duckdb", "sql": "SELECT * FROM t1 AS a AT (VERSION => 3) JOIN t2 AS b AT (TIMESTAMP => NOW() - INTERVAL '1' WEEK) ON a.id = b.id", - "formatted": "SELECT *\nFROM t1 AS a AT (VERSION => 3)\nJOIN t2 AS b AT (TIMESTAMP => NOW() - INTERVAL '1' WEEK)\n ON a.id = b.id" + "formatted": "SELECT *\nFROM t1 AS a AT (VERSION => 3)\nJOIN t2 AS b AT (TIMESTAMP => NOW() - INTERVAL '1' WEEK) ON a.id = b.id", + "previously_formatted": "SELECT *\nFROM t1 AS a AT (VERSION => 3)\nJOIN t2 AS b AT (TIMESTAMP => NOW() - INTERVAL '1' WEEK)\n ON a.id = b.id" }, { "dialect": "duckdb", @@ -1343,7 +1362,8 @@ { "dialect": "duckdb", "sql": "SELECT * FROM foo ASOF LEFT JOIN bar ON a = b", - "formatted": "SELECT *\nFROM foo\nASOF LEFT JOIN bar\n ON a = b" + "formatted": "SELECT *\nFROM foo\nASOF LEFT JOIN bar ON a = b", + "previously_formatted": "SELECT *\nFROM foo\nASOF LEFT JOIN bar\n ON a = b" }, { "dialect": "duckdb", @@ -1438,7 +1458,8 @@ { "dialect": "duckdb", "sql": "SELECT a, LOGICAL_OR(b) FROM foo GROUP BY a", - "formatted": "SELECT\n a,\n LOGICAL_OR(b)\nFROM foo\nGROUP BY\n a" + "formatted": "SELECT\n a,\n LOGICAL_OR(b)\nFROM foo\nGROUP BY a", + "previously_formatted": "SELECT\n a,\n LOGICAL_OR(b)\nFROM foo\nGROUP BY\n a" }, { "dialect": "duckdb", @@ -1653,12 +1674,14 @@ { "dialect": "duckdb", "sql": "SELECT i FROM RANGE(5) AS _(i) ORDER BY i ASC", - "formatted": "SELECT i\nFROM RANGE(5) AS _(i)\nORDER BY\n i ASC" + "formatted": "SELECT i\nFROM RANGE(5) AS _(i)\nORDER BY i ASC", + "previously_formatted": "SELECT i\nFROM RANGE(5) AS _(i)\nORDER BY\n i ASC" }, { "dialect": "duckdb", "sql": "SELECT i FROM GENERATE_SERIES(12) AS _(i) ORDER BY i ASC", - "formatted": "SELECT i\nFROM GENERATE_SERIES(12) AS _(i)\nORDER BY\n i ASC" + "formatted": "SELECT i\nFROM GENERATE_SERIES(12) AS _(i)\nORDER BY i ASC", + "previously_formatted": "SELECT i\nFROM GENERATE_SERIES(12) AS _(i)\nORDER BY\n i ASC" }, { "dialect": "duckdb", @@ -2027,7 +2050,8 @@ { "dialect": "duckdb", "sql": "\n SELECT\n l_returnflag,\n l_linestatus,\n sum_qty: sum(l_quantity),\n sum_base_price: sum(l_extendedprice),\n sum_disc_price: sum(l_extendedprice * (1-l_discount)),\n sum_charge: sum(l_extendedprice * (1-l_discount) * (1+l_tax)),\n avg_qty: avg(l_quantity),\n avg_price: avg(l_extendedprice),\n avg_disc: avg(l_discount),\n count_order: count(*)\n ", - "formatted": "SELECT\n l_returnflag,\n l_linestatus,\n sum_qty:sum(l_quantity),\n sum_base_price:sum(l_extendedprice),\n sum_disc_price:sum(l_extendedprice\n * (\n 1 - l_discount\n )),\n sum_charge:sum(l_extendedprice\n * (\n 1 - l_discount\n )\n * (\n 1 + l_tax\n )),\n avg_qty:avg(l_quantity),\n avg_price:avg(l_extendedprice),\n avg_disc:avg(l_discount),\n count_order:count(*)" + "formatted": "SELECT\n l_returnflag,\n l_linestatus,\n sum_qty:sum(l_quantity),\n sum_base_price:sum(l_extendedprice),\n sum_disc_price:sum(\n l_extendedprice\n * (\n 1 - l_discount\n )\n ),\n sum_charge:sum(\n l_extendedprice\n * (\n 1 - l_discount\n )\n * (\n 1 + l_tax\n )\n ),\n avg_qty:avg(l_quantity),\n avg_price:avg(l_extendedprice),\n avg_disc:avg(l_discount),\n count_order:count(*)", + "previously_formatted": "SELECT\n l_returnflag,\n l_linestatus,\n sum_qty:sum(l_quantity),\n sum_base_price:sum(l_extendedprice),\n sum_disc_price:sum(l_extendedprice\n * (\n 1 - l_discount\n )),\n sum_charge:sum(l_extendedprice\n * (\n 1 - l_discount\n )\n * (\n 1 + l_tax\n )),\n avg_qty:avg(l_quantity),\n avg_price:avg(l_extendedprice),\n avg_disc:avg(l_discount),\n count_order:count(*)" }, { "dialect": "duckdb", @@ -2307,7 +2331,8 @@ { "dialect": "postgres", "sql": "SELECT SUM(x) OVER (PARTITION BY y ORDER BY interval ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - SUM(x) OVER (PARTITION BY y ORDER BY interval ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total", - "formatted": "SELECT SUM(x) OVER (PARTITION BY y ORDER BY interval ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - SUM(x) OVER (PARTITION BY y ORDER BY interval ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total" + "formatted": "SELECT\n SUM(x) OVER (\n PARTITION BY y\n ORDER BY interval\n ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n )\n - SUM(x) OVER (\n PARTITION BY y\n ORDER BY interval\n ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW\n ) AS total", + "previously_formatted": "SELECT SUM(x) OVER (PARTITION BY y ORDER BY interval ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - SUM(x) OVER (PARTITION BY y ORDER BY interval ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total" }, { "dialect": "postgres", @@ -2402,7 +2427,8 @@ { "dialect": "postgres", "sql": "SELECT c.oid, n.nspname, c.relname FROM pg_catalog.pg_class AS c LEFT JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace WHERE c.relname OPERATOR(pg_catalog.~) '^(courses)$' COLLATE pg_catalog.default AND pg_catalog.PG_TABLE_IS_VISIBLE(c.oid) ORDER BY 2, 3", - "formatted": "SELECT\n c.oid,\n n.nspname,\n c.relname\nFROM pg_catalog.pg_class AS c\nLEFT JOIN pg_catalog.pg_namespace AS n\n ON n.oid = c.relnamespace\nWHERE\n c.relname OPERATOR(pg_catalog.~) '^(courses)$' COLLATE pg_catalog.default AND pg_catalog.PG_TABLE_IS_VISIBLE(c.oid)\nORDER BY\n 2,\n 3" + "formatted": "SELECT\n c.oid,\n n.nspname,\n c.relname\nFROM pg_catalog.pg_class AS c\nLEFT JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace\nWHERE\n c.relname OPERATOR(pg_catalog.~) '^(courses)$' COLLATE pg_catalog.default AND pg_catalog.PG_TABLE_IS_VISIBLE(c.oid)\nORDER BY\n 2,\n 3", + "previously_formatted": "SELECT\n c.oid,\n n.nspname,\n c.relname\nFROM pg_catalog.pg_class AS c\nLEFT JOIN pg_catalog.pg_namespace AS n\n ON n.oid = c.relnamespace\nWHERE\n c.relname OPERATOR(pg_catalog.~) '^(courses)$' COLLATE pg_catalog.default AND pg_catalog.PG_TABLE_IS_VISIBLE(c.oid)\nORDER BY\n 2,\n 3" }, { "dialect": "postgres", @@ -2507,8 +2533,8 @@ { "dialect": "postgres", "sql": "SELECT m.name FROM manufacturers AS m LEFT JOIN LATERAL GET_PRODUCT_NAMES(m.id) pname ON TRUE WHERE pname IS NULL", - "formatted": "SELECT m.name\nFROM manufacturers AS m\nLEFT JOIN LATERAL GET_PRODUCT_NAMES(m.id) pname\n ON TRUE\nWHERE pname IS NULL", - "previously_formatted": "SELECT\n m.name\nFROM manufacturers AS m\nLEFT JOIN LATERAL GET_PRODUCT_NAMES(m.id) AS pname\n ON TRUE\nWHERE\n pname IS NULL" + "formatted": "SELECT m.name\nFROM manufacturers AS m\nLEFT JOIN LATERAL GET_PRODUCT_NAMES(m.id) pname ON TRUE\nWHERE pname IS NULL", + "previously_formatted": "SELECT m.name\nFROM manufacturers AS m\nLEFT JOIN LATERAL GET_PRODUCT_NAMES(m.id) pname\n ON TRUE\nWHERE pname IS NULL" }, { "dialect": "postgres", @@ -2569,7 +2595,8 @@ { "dialect": "postgres", "sql": "SELECT 1 FROM ((VALUES (1)) AS vals(id) LEFT OUTER JOIN tbl ON vals.id = tbl.id)", - "formatted": "SELECT 1\nFROM ((VALUES (1)) AS vals(id)\nLEFT OUTER JOIN tbl\n ON vals.id = tbl.id)" + "formatted": "SELECT 1\nFROM (\n (VALUES (1)) AS vals(id)\n LEFT OUTER JOIN tbl ON vals.id = tbl.id\n)", + "previously_formatted": "SELECT 1\nFROM ((VALUES (1)) AS vals(id)\nLEFT OUTER JOIN tbl\n ON vals.id = tbl.id)" }, { "dialect": "postgres", @@ -2670,7 +2697,8 @@ { "dialect": "postgres", "sql": "SELECT TRIM(ARRAY_TO_STRING(ARRAY(SELECT val FROM UNNEST(ARRAY['a', 'b']) WITH ORDINALITY AS u(val, rn)), ' '))", - "formatted": "SELECT\n TRIM(ARRAY_TO_STRING(\n ARRAY(\n SELECT val\n FROM UNNEST(ARRAY['a', 'b']) WITH ORDINALITY AS u(val, rn)\n ),\n ' '\n ))" + "formatted": "SELECT\n TRIM(\n ARRAY_TO_STRING(\n ARRAY(\n SELECT val\n FROM UNNEST(ARRAY['a', 'b']) WITH ORDINALITY AS u(val, rn)\n ),\n ' '\n )\n )", + "previously_formatted": "SELECT\n TRIM(ARRAY_TO_STRING(\n ARRAY(\n SELECT val\n FROM UNNEST(ARRAY['a', 'b']) WITH ORDINALITY AS u(val, rn)\n ),\n ' '\n ))" }, { "dialect": "postgres", @@ -3962,27 +3990,32 @@ { "dialect": "snowflake", "sql": "SELECT * FROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN ('2023_Q1', '2023_Q2', '2023_Q3', '2023_Q4', '2024_Q1') DEFAULT ON NULL (0)) ORDER BY empid", - "formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN ('2023_Q1', '2023_Q2', '2023_Q3', '2023_Q4', '2024_Q1') DEFAULT ON NULL (0))\nORDER BY\n empid" + "formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN ('2023_Q1', '2023_Q2', '2023_Q3', '2023_Q4', '2024_Q1') DEFAULT ON NULL (0))\nORDER BY empid", + "previously_formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN ('2023_Q1', '2023_Q2', '2023_Q3', '2023_Q4', '2024_Q1') DEFAULT ON NULL (0))\nORDER BY\n empid" }, { "dialect": "snowflake", "sql": "SELECT * FROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (SELECT DISTINCT quarter FROM ad_campaign_types_by_quarter WHERE television = TRUE ORDER BY quarter)) ORDER BY empid", - "formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (SELECT DISTINCT\n quarter\nFROM ad_campaign_types_by_quarter\nWHERE television = TRUE\nORDER BY\n quarter))\nORDER BY\n empid" + "formatted": "SELECT *\nFROM quarterly_sales PIVOT(\n SUM(amount) FOR quarter IN (\n SELECT DISTINCT\n quarter\n FROM ad_campaign_types_by_quarter\n WHERE television = TRUE\n ORDER BY quarter\n )\n)\nORDER BY empid", + "previously_formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (SELECT DISTINCT\n quarter\nFROM ad_campaign_types_by_quarter\nWHERE television = TRUE\nORDER BY\n quarter))\nORDER BY\n empid" }, { "dialect": "snowflake", "sql": "SELECT * FROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY ORDER BY quarter)) ORDER BY empid", - "formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY ORDER BY quarter))\nORDER BY\n empid" + "formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY ORDER BY quarter))\nORDER BY empid", + "previously_formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY ORDER BY quarter))\nORDER BY\n empid" }, { "dialect": "snowflake", "sql": "SELECT * FROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY)) ORDER BY empid", - "formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY))\nORDER BY\n empid" + "formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY))\nORDER BY empid", + "previously_formatted": "SELECT *\nFROM quarterly_sales PIVOT(SUM(amount) FOR quarter IN (ANY))\nORDER BY\n empid" }, { "dialect": "snowflake", "sql": "SELECT * FROM DATA AS DATA_L ASOF JOIN DATA AS DATA_R MATCH_CONDITION (DATA_L.VAL > DATA_R.VAL) ON DATA_L.ID = DATA_R.ID", - "formatted": "SELECT *\nFROM DATA AS DATA_L\nASOF JOIN DATA AS DATA_R MATCH_CONDITION (DATA_L.VAL > DATA_R.VAL)\n ON DATA_L.ID = DATA_R.ID" + "formatted": "SELECT *\nFROM DATA AS DATA_L\nASOF JOIN DATA AS DATA_R MATCH_CONDITION (DATA_L.VAL > DATA_R.VAL) ON DATA_L.ID = DATA_R.ID", + "previously_formatted": "SELECT *\nFROM DATA AS DATA_L\nASOF JOIN DATA AS DATA_R MATCH_CONDITION (DATA_L.VAL > DATA_R.VAL)\n ON DATA_L.ID = DATA_R.ID" }, { "dialect": "snowflake", @@ -4025,7 +4058,8 @@ { "dialect": "snowflake", "sql": "SELECT * FROM t1 INNER JOIN t2 USING (t1.col)", - "formatted": "SELECT *\nFROM t1\nINNER JOIN t2\n USING (t1.col)" + "formatted": "SELECT *\nFROM t1\nINNER JOIN t2 USING (t1.col)", + "previously_formatted": "SELECT *\nFROM t1\nINNER JOIN t2\n USING (t1.col)" }, { "dialect": "snowflake", @@ -4537,7 +4571,8 @@ { "dialect": "snowflake", "sql": "SELECT * FROM (SELECT * FROM t1 JOIN t2 ON t1.a = t2.c) TABLESAMPLE BERNOULLI (1)", - "formatted": "SELECT *\nFROM (\n SELECT *\n FROM t1\n JOIN t2\n ON t1.a = t2.c\n) TABLESAMPLE BERNOULLI (1)" + "formatted": "SELECT *\nFROM (\n SELECT *\n FROM t1\n JOIN t2 ON t1.a = t2.c\n) TABLESAMPLE BERNOULLI (1)", + "previously_formatted": "SELECT *\nFROM (\n SELECT *\n FROM t1\n JOIN t2\n ON t1.a = t2.c\n) TABLESAMPLE BERNOULLI (1)" }, { "dialect": "snowflake", @@ -4658,8 +4693,8 @@ { "dialect": "snowflake", "sql": "\n SELECT oldt.* , newt.*\n FROM my_table BEFORE(STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS oldt\n FULL OUTER JOIN my_table AT(STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS newt\n ON oldt.id = newt.id\n WHERE oldt.id IS NULL OR newt.id IS NULL;\n ", - "formatted": "SELECT\n oldt.*,\n newt.*\nFROM my_table BEFORE (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS oldt\nFULL OUTER JOIN my_table AT (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS newt\n ON oldt.id = newt.id\nWHERE\n oldt.id IS NULL\n OR newt.id IS NULL;", - "previously_formatted": "SELECT\n oldt.*,\n newt.*\nFROM my_table BEFORE (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS oldt\nFULL OUTER JOIN my_table AT (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS newt\n ON oldt.id = newt.id\nWHERE\n oldt.id IS NULL\n OR newt.id IS NULL" + "formatted": "SELECT\n oldt.*,\n newt.*\nFROM my_table BEFORE (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS oldt\nFULL OUTER JOIN my_table AT (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS newt ON oldt.id = newt.id\nWHERE\n oldt.id IS NULL\n OR newt.id IS NULL;", + "previously_formatted": "SELECT\n oldt.*,\n newt.*\nFROM my_table BEFORE (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS oldt\nFULL OUTER JOIN my_table AT (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726') AS newt\n ON oldt.id = newt.id\nWHERE\n oldt.id IS NULL\n OR newt.id IS NULL;" }, { "dialect": "snowflake", @@ -4694,7 +4729,8 @@ { "dialect": "snowflake", "sql": "SELECT * FROM (TABLE('t1') CROSS JOIN TABLE('t2'))", - "formatted": "SELECT *\nFROM (TABLE('t1')\nCROSS JOIN TABLE('t2'))" + "formatted": "SELECT *\nFROM (\n TABLE('t1')\n CROSS JOIN TABLE('t2')\n)", + "previously_formatted": "SELECT *\nFROM (TABLE('t1')\nCROSS JOIN TABLE('t2'))" }, { "dialect": "snowflake", @@ -4724,7 +4760,8 @@ { "dialect": "snowflake", "sql": "SELECT value FROM TABLE(FLATTEN(input => SELECT PARSE_JSON('[1, 2]')))", - "formatted": "SELECT value\nFROM TABLE(FLATTEN(input => SELECT\n PARSE_JSON('[1, 2]')))" + "formatted": "SELECT value\nFROM TABLE(\n FLATTEN(\n input => SELECT\n PARSE_JSON('[1, 2]')\n )\n)", + "previously_formatted": "SELECT value\nFROM TABLE(FLATTEN(input => SELECT\n PARSE_JSON('[1, 2]')))" }, { "dialect": "snowflake", @@ -4889,7 +4926,8 @@ { "dialect": "snowflake", "sql": "SELECT * FROM TABLE(model_trained_with_labeled_data!DETECT_ANOMALIES(INPUT_DATA => TABLE(view_with_data_to_analyze), TIMESTAMP_COLNAME => 'date', TARGET_COLNAME => 'sales', CONFIG_OBJECT => OBJECT_CONSTRUCT('prediction_interval', 0.99)))", - "formatted": "SELECT *\nFROM TABLE(model_trained_with_labeled_data!DETECT_ANOMALIES(\n INPUT_DATA => TABLE(view_with_data_to_analyze),\n TIMESTAMP_COLNAME => 'date',\n TARGET_COLNAME => 'sales',\n CONFIG_OBJECT => OBJECT_CONSTRUCT('prediction_interval', 0.99)\n))" + "formatted": "SELECT *\nFROM TABLE(\n model_trained_with_labeled_data!DETECT_ANOMALIES(\n INPUT_DATA => TABLE(view_with_data_to_analyze),\n TIMESTAMP_COLNAME => 'date',\n TARGET_COLNAME => 'sales',\n CONFIG_OBJECT => OBJECT_CONSTRUCT('prediction_interval', 0.99)\n )\n)", + "previously_formatted": "SELECT *\nFROM TABLE(model_trained_with_labeled_data!DETECT_ANOMALIES(\n INPUT_DATA => TABLE(view_with_data_to_analyze),\n TIMESTAMP_COLNAME => 'date',\n TARGET_COLNAME => 'sales',\n CONFIG_OBJECT => OBJECT_CONSTRUCT('prediction_interval', 0.99)\n))" }, { "dialect": "snowflake", @@ -4919,17 +4957,20 @@ { "dialect": "snowflake", "sql": "SELECT * FROM a CROSS DIRECTED JOIN b USING (id)", - "formatted": "SELECT *\nFROM a\nCROSS DIRECTED JOIN b\n USING (id)" + "formatted": "SELECT *\nFROM a\nCROSS DIRECTED JOIN b USING (id)", + "previously_formatted": "SELECT *\nFROM a\nCROSS DIRECTED JOIN b\n USING (id)" }, { "dialect": "snowflake", "sql": "SELECT * FROM a INNER DIRECTED JOIN b USING (id)", - "formatted": "SELECT *\nFROM a\nINNER DIRECTED JOIN b\n USING (id)" + "formatted": "SELECT *\nFROM a\nINNER DIRECTED JOIN b USING (id)", + "previously_formatted": "SELECT *\nFROM a\nINNER DIRECTED JOIN b\n USING (id)" }, { "dialect": "snowflake", "sql": "SELECT * FROM a NATURAL INNER DIRECTED JOIN b USING (id)", - "formatted": "SELECT *\nFROM a\nNATURAL INNER DIRECTED JOIN b\n USING (id)" + "formatted": "SELECT *\nFROM a\nNATURAL INNER DIRECTED JOIN b USING (id)", + "previously_formatted": "SELECT *\nFROM a\nNATURAL INNER DIRECTED JOIN b\n USING (id)" }, { "dialect": "snowflake", @@ -5109,7 +5150,8 @@ { "dialect": "tsql", "sql": "SELECT * FROM taxi ORDER BY 1 OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY", - "formatted": "SELECT *\nFROM taxi\nORDER BY\n 1\nOFFSET 0 ROWS\nFETCH NEXT 3 ROWS ONLY" + "formatted": "SELECT *\nFROM taxi\nORDER BY 1\nOFFSET 0 ROWS\nFETCH NEXT 3 ROWS ONLY", + "previously_formatted": "SELECT *\nFROM taxi\nORDER BY\n 1\nOFFSET 0 ROWS\nFETCH NEXT 3 ROWS ONLY" }, { "dialect": "tsql", @@ -5139,7 +5181,8 @@ { "dialect": "tsql", "sql": "SELECT x FROM @MyTableVar AS m JOIN Employee ON m.EmployeeID = Employee.EmployeeID", - "formatted": "SELECT x\nFROM @MyTableVar AS m\nJOIN Employee\n ON m.EmployeeID = Employee.EmployeeID" + "formatted": "SELECT x\nFROM @MyTableVar AS m\nJOIN Employee ON m.EmployeeID = Employee.EmployeeID", + "previously_formatted": "SELECT x\nFROM @MyTableVar AS m\nJOIN Employee\n ON m.EmployeeID = Employee.EmployeeID" }, { "dialect": "tsql", @@ -5164,7 +5207,8 @@ { "dialect": "tsql", "sql": "SELECT (SELECT TOP 5 a, b FROM t ORDER BY b DESC FOR JSON PATH) AS j FROM x", - "formatted": "SELECT\n (\n SELECT TOP 5\n a,\n b\n FROM t\n ORDER BY\n b DESC\n FOR JSON\n PATH\n ) AS j\nFROM x" + "formatted": "SELECT\n (\n SELECT TOP 5\n a,\n b\n FROM t\n ORDER BY b DESC\n FOR JSON\n PATH\n ) AS j\nFROM x", + "previously_formatted": "SELECT\n (\n SELECT TOP 5\n a,\n b\n FROM t\n ORDER BY\n b DESC\n FOR JSON\n PATH\n ) AS j\nFROM x" }, { "dialect": "tsql", @@ -5274,7 +5318,8 @@ { "dialect": "tsql", "sql": "SELECT x FROM a INNER LOOP JOIN b ON b.id = a.id", - "formatted": "SELECT x\nFROM a\nINNER LOOP JOIN b\n ON b.id = a.id" + "formatted": "SELECT x\nFROM a\nINNER LOOP JOIN b ON b.id = a.id", + "previously_formatted": "SELECT x\nFROM a\nINNER LOOP JOIN b\n ON b.id = a.id" }, { "dialect": "tsql", diff --git a/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json b/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json index 666687c..530593c 100644 --- a/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json +++ b/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json @@ -212,15 +212,8 @@ { "dialect": "tsql", "sql": "WITH t1 AS (SELECT 1 AS a), t2 AS (SELECT 1 AS a) SELECT COUNT(*) FROM (SELECT TOP 10 a FROM t1 UNION ALL SELECT TOP 10 a FROM t2 ORDER BY a DESC) AS t", - "formatted": "WITH t1 AS (\n SELECT 1 AS a\n),\n\nt2 AS (\n SELECT 1 AS a\n)\n\nSELECT COUNT(*)\nFROM (\n SELECT TOP 10 a\n FROM t1\n UNION ALL\n SELECT TOP 10 a\n FROM t2\n ORDER BY\n a DESC\n) AS t", - "reason": "A set operation's ORDER BY sits at the depth of its set operation with its items on the next line; SQLClean outdented it to the enclosing parenthesis and kept the items on its line", - "receipt": null - }, - { - "dialect": "tsql", - "sql": "WITH t1 AS (SELECT 1 AS a), t2 AS (SELECT 1 AS a) SELECT TOP 10 a FROM t1 UNION ALL SELECT TOP 10 a FROM t2 ORDER BY a DESC", - "formatted": "WITH t1 AS (\n SELECT 1 AS a\n),\n\nt2 AS (\n SELECT 1 AS a\n)\n\nSELECT TOP 10 a\nFROM t1\nUNION ALL\nSELECT TOP 10 a\nFROM t2\nORDER BY\n a DESC", - "reason": "A set operation's ORDER BY puts its items on the next line, as in every other dialect and SQL Server's own `ORDER BY\\n 1`; SQLClean kept them on the ORDER BY line", + "formatted": "WITH t1 AS (\n SELECT 1 AS a\n),\n\nt2 AS (\n SELECT 1 AS a\n)\n\nSELECT COUNT(*)\nFROM (\n SELECT TOP 10 a\n FROM t1\n UNION ALL\n SELECT TOP 10 a\n FROM t2\n ORDER BY a DESC\n) AS t", + "reason": "A set operation's ORDER BY sits at the depth of its set operation; SQLClean outdented it to the enclosing parenthesis", "receipt": null }, { @@ -324,7 +317,7 @@ { "dialect": "bigquery", "sql": "SELECT STRUCT((SELECT 'foo')).*", - "formatted": "SELECT\n STRUCT ((\n SELECT 'foo'\n )).*", + "formatted": "SELECT\n STRUCT (\n (\n SELECT 'foo'\n )\n ).*", "reason": "SQLClean's Polyglot printer put a space before `.*`; SQLQuack keeps the field access touching its operand", "receipt": null }, diff --git a/crates/sqlclean/src/sql_lint/tests/test_layout_rules.rs b/crates/sqlclean/src/sql_lint/tests/test_layout_rules.rs index 361bd46..0263215 100644 --- a/crates/sqlclean/src/sql_lint/tests/test_layout_rules.rs +++ b/crates/sqlclean/src/sql_lint/tests/test_layout_rules.rs @@ -175,7 +175,7 @@ fn given_clause_layout_rules_when_formatting_then_each_rule_applies_idempotently dialect: "snowflake", sql: "SELECT customer_id, LISTAGG(DISTINCT LOWER(product_category_name), ', ') WITHIN GROUP (ORDER BY product_category_name) AS categories FROM orders GROUP BY customer_id", line_width: 80, - expected_sql: "SELECT\n customer_id,\n LISTAGG(\n DISTINCT LOWER(product_category_name),\n ', '\n ) WITHIN GROUP (ORDER BY product_category_name) AS categories\nFROM orders\nGROUP BY\n customer_id", + expected_sql: "SELECT\n customer_id,\n LISTAGG(\n DISTINCT LOWER(product_category_name),\n ', '\n ) WITHIN GROUP (ORDER BY product_category_name) AS categories\nFROM orders\nGROUP BY customer_id", }, test_types::LayoutRuleTestCase { description: "a window that continues on later lines breaks at its clauses", diff --git a/crates/sqlclean/src/sql_lint/tests/test_values_formatter.rs b/crates/sqlclean/src/sql_lint/tests/test_values_formatter.rs index 6963aad..8a04b85 100644 --- a/crates/sqlclean/src/sql_lint/tests/test_values_formatter.rs +++ b/crates/sqlclean/src/sql_lint/tests/test_values_formatter.rs @@ -22,7 +22,7 @@ fn given_mixed_values_relations_when_formatting_then_each_authored_form_is_prese test_types::FormatTestCase { description: "mixed values relations inside joined subquery preserve authored forms", sql: "SELECT base.id FROM items AS base JOIN (SELECT * FROM (VALUES (1)) AS first_values(id) UNION ALL SELECT * FROM VALUES (2)) AS mixed ON base.id = mixed.id", - expected_sql: "SELECT base.id\nFROM items AS base\nJOIN (\n SELECT *\n FROM (VALUES (1)) AS first_values(id)\n UNION ALL\n SELECT *\n FROM VALUES (2)\n) AS mixed\n ON base.id = mixed.id", + expected_sql: "SELECT base.id\nFROM items AS base\nJOIN (\n SELECT *\n FROM (VALUES (1)) AS first_values(id)\n UNION ALL\n SELECT *\n FROM VALUES (2)\n) AS mixed ON base.id = mixed.id", expected_changed: true, }, test_types::FormatTestCase { From d9ab6d4531668705f88c4ad0652ac2147fc50e4a Mon Sep 17 00:00:00 2001 From: Kevin Longe <273747162+kvlonge@users.noreply.github.com> Date: Thu, 12 Nov 2026 06:11:44 +0000 Subject: [PATCH 3/3] test(format): describe the STRUCT field-access departure's parenthesis layout --- .../src/sql_lint/tests/fixtures/sqlquack_departures.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json b/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json index 530593c..1389144 100644 --- a/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json +++ b/crates/sqlclean/src/sql_lint/tests/fixtures/sqlquack_departures.json @@ -318,7 +318,7 @@ "dialect": "bigquery", "sql": "SELECT STRUCT((SELECT 'foo')).*", "formatted": "SELECT\n STRUCT (\n (\n SELECT 'foo'\n )\n ).*", - "reason": "SQLClean's Polyglot printer put a space before `.*`; SQLQuack keeps the field access touching its operand", + "reason": "SQLClean's Polyglot printer put a space before `.*` and hugged the inner parenthesis; SQLQuack keeps the field access touching its operand and puts the multi-line parenthesised group on its own lines", "receipt": null }, {