From 0d5f2d330aecaf807108a23cdd5ff7be1a333d33 Mon Sep 17 00:00:00 2001 From: Karl Gutwin Date: Tue, 1 Jul 2025 18:07:34 -0400 Subject: [PATCH 1/2] test: integration, compile all dialects and diff --- prqlc/prqlc/tests/integration/queries.rs | 70 ++- ...ion__queries__compileall__aggregation.snap | 20 + ...n__queries__compileall__append_select.snap | 6 + ...es__compileall__append_select_compute.snap | 41 ++ ...all__append_select_multiple_with_null.snap | 6 + ...tion__queries__compileall__arithmetic.snap | 397 ++++++++++++++++++ ...ntegration__queries__compileall__cast.snap | 30 ++ ...__queries__compileall__constants_only.snap | 28 ++ ...ration__queries__compileall__distinct.snap | 6 + ...ion__queries__compileall__distinct_on.snap | 113 +++++ ...on__queries__compileall__genre_counts.snap | 6 + ...ation__queries__compileall__group_all.snap | 88 ++++ ...tion__queries__compileall__group_sort.snap | 32 ++ ...ileall__group_sort_derive_select_join.snap | 6 + ..._group_sort_filter_derive_select_join.snap | 6 + ...es__compileall__group_sort_limit_take.snap | 6 + ...__queries__compileall__invoice_totals.snap | 6 + ...gration__queries__compileall__loop_01.snap | 6 + ...ion__queries__compileall__math_module.snap | 109 +++++ ...ation__queries__compileall__pipelines.snap | 135 ++++++ ...ration__queries__compileall__read_csv.snap | 56 +++ ...__queries__compileall__set_ops_remove.snap | 56 +++ ...ntegration__queries__compileall__sort.snap | 6 + ...egration__queries__compileall__sort_2.snap | 75 ++++ ...egration__queries__compileall__sort_3.snap | 139 ++++++ ...egration__queries__compileall__switch.snap | 31 ++ ...ntegration__queries__compileall__take.snap | 19 + ...ion__queries__compileall__text_module.snap | 202 +++++++++ ...egration__queries__compileall__window.snap | 6 + 29 files changed, 1696 insertions(+), 11 deletions(-) create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__aggregation.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_compute.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_multiple_with_null.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__arithmetic.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__cast.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__constants_only.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct_on.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__genre_counts.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_all.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_derive_select_join.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_filter_derive_select_join.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_limit_take.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__invoice_totals.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__loop_01.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__math_module.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__pipelines.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__read_csv.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__set_ops_remove.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_2.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_3.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__switch.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__take.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__text_module.snap create mode 100644 prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__window.snap diff --git a/prqlc/prqlc/tests/integration/queries.rs b/prqlc/prqlc/tests/integration/queries.rs index e4319f6f6861..0446bf4ae0d1 100644 --- a/prqlc/prqlc/tests/integration/queries.rs +++ b/prqlc/prqlc/tests/integration/queries.rs @@ -5,6 +5,7 @@ use std::{env, fs}; use insta::assert_debug_snapshot; use insta::{assert_snapshot, with_settings}; use prqlc::sql::Dialect; +use prqlc::sql::SupportLevel; use prqlc::{Options, Target}; use test_each_file::test_each_path; @@ -50,6 +51,64 @@ mod compile { } } +fn should_run_query(dialect: Dialect, prql: &str) -> bool { + let dialect_str = dialect.to_string().to_lowercase(); + + match dialect.support_level() { + SupportLevel::Supported => !prql.contains(&format!("{dialect_str}:skip")), + SupportLevel::Unsupported => prql.contains(&format!("{dialect_str}:test")), + SupportLevel::Nascent => false, + } +} + +mod compileall { + use super::*; + use similar::TextDiff; + use strum::IntoEnumIterator; + + test_each_path! { in "./prqlc/prqlc/tests/integration/queries" => run } + + fn run(prql_path: &Path) { + let test_name = prql_path.file_stem().unwrap().to_str().unwrap(); + let prql = fs::read_to_string(prql_path).unwrap(); + if prql.contains("generic:skip") { + return; + } + + // first compile with the generic dialect + let target = Target::Sql(Some(Dialect::Generic)); + let options = Options::default().no_signature().with_target(target); + + let generic_sql = prqlc::compile(&prql, &options).unwrap(); + + // next compile with each dialect + let mut diffsnap = "".to_owned(); + for dialect in Dialect::iter() { + if !should_run_query(dialect, &prql) { + continue; + } + + let dialect_target = Target::Sql(Some(dialect)); + let dialect_options = Options::default() + .no_signature() + .with_target(dialect_target); + + let dialect_sql = prqlc::compile(&prql, &dialect_options).unwrap(); + + let diff = TextDiff::from_lines(&generic_sql, &dialect_sql); + diffsnap = format!( + "{diffsnap}\n{}", + diff.unified_diff() + .context_radius(10) + .header("generic", &dialect.to_string()) + ); + } + with_settings!({ input_file => prql_path }, { + assert_snapshot!(test_name, diffsnap, &prql) + }); + } +} + mod fmt { use super::*; @@ -96,23 +155,12 @@ mod debug_lineage { mod results { use itertools::Itertools; - use prqlc::sql::SupportLevel; use super::*; use crate::dbs::{batch_to_csv, runners}; test_each_path! { in "./prqlc/prqlc/tests/integration/queries" => run } - fn should_run_query(dialect: Dialect, prql: &str) -> bool { - let dialect_str = dialect.to_string().to_lowercase(); - - match dialect.support_level() { - SupportLevel::Supported => !prql.contains(&format!("{dialect_str}:skip")), - SupportLevel::Unsupported => prql.contains(&format!("{dialect_str}:test")), - SupportLevel::Nascent => false, - } - } - fn run(prql_path: &Path) { let test_name = prql_path.file_stem().unwrap().to_str().unwrap(); let prql = fs::read_to_string(prql_path).unwrap(); diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__aggregation.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__aggregation.snap new file mode 100644 index 000000000000..f417f0349efa --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__aggregation.snap @@ -0,0 +1,20 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mysql:skip\n# clickhouse:skip\n# glaredb:skip (the string_agg function is not supported)\nfrom tracks\nfilter genre_id == 100\nderive empty_name = name == ''\naggregate {sum track_id, concat_array name, all empty_name, any empty_name}\n" +input_file: prqlc/prqlc/tests/integration/queries/aggregation.prql +--- +--- generic ++++ sqlite +@@ -1,9 +1,9 @@ + SELECT + COALESCE(SUM(track_id), 0), +- COALESCE(STRING_AGG(name, ''), ''), +- COALESCE(BOOL_AND(name = ''), TRUE), +- COALESCE(BOOL_OR(name = ''), FALSE) ++ COALESCE(GROUP_CONCAT(name, ''), ''), ++ COALESCE(MIN(name = '') > 0, TRUE), ++ COALESCE(MAX(name = '') > 0, FALSE) + FROM + tracks + WHERE + genre_id = 100 diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select.snap new file mode 100644 index 000000000000..0b1641152e5b --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "from invoices\nselect { customer_id, invoice_id, billing_country }\ntake 10..15\nappend (\n from invoices\n select { customer_id, invoice_id, billing_country }\n take 40..45\n)\nselect { billing_country, invoice_id }\n" +input_file: prqlc/prqlc/tests/integration/queries/append_select.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_compute.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_compute.snap new file mode 100644 index 000000000000..194425947a50 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_compute.snap @@ -0,0 +1,41 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "from invoices\nselect { customer_id, invoice_id, total }\ntake 5\nappend (\n from invoice_items\n select { invoice_line_id, invoice_id, unit_price }\n take 5\n)\nselect { a = customer_id * 2, b = math.round 1 (invoice_id * total) }\n" +input_file: prqlc/prqlc/tests/integration/queries/append_select_compute.prql +--- +--- generic ++++ glaredb +@@ -23,13 +23,13 @@ + ) AS table_2 + UNION + ALL + SELECT + * + FROM + table_0 + ) + SELECT + customer_id * 2 AS a, +- ROUND(invoice_id * total, 1) AS b ++ ROUND((invoice_id * total)::numeric, 1) AS b + FROM + table_1 + + +--- generic ++++ postgres +@@ -23,13 +23,13 @@ + ) AS table_2 + UNION + ALL + SELECT + * + FROM + table_0 + ) + SELECT + customer_id * 2 AS a, +- ROUND(invoice_id * total, 1) AS b ++ ROUND((invoice_id * total)::numeric, 1) AS b + FROM + table_1 diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_multiple_with_null.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_multiple_with_null.snap new file mode 100644 index 000000000000..74d86c42ada5 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__append_select_multiple_with_null.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "from invoices\nselect { customer_id, invoice_id, billing_country }\ntake 5\nappend (\n from employees\n select { employee_id, employee_id, country }\n take 5\n)\nappend (\n from invoice_items\n select { invoice_line_id, invoice_id, null }\n take 5\n)\nselect { billing_country, invoice_id }\n" +input_file: prqlc/prqlc/tests/integration/queries/append_select_multiple_with_null.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__arithmetic.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__arithmetic.snap new file mode 100644 index 000000000000..fcbac48cfdc9 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__arithmetic.snap @@ -0,0 +1,397 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom [\n { id = 1, x_int = 13, x_float = 13.0, k_int = 5, k_float = 5.0 },\n { id = 2, x_int = -13, x_float = -13.0, k_int = 5, k_float = 5.0 },\n { id = 3, x_int = 13, x_float = 13.0, k_int = -5, k_float = -5.0 },\n { id = 4, x_int = -13, x_float = -13.0, k_int = -5, k_float = -5.0 },\n]\nselect {\n id,\n\n x_int / k_int,\n x_int / k_float,\n x_float / k_int,\n x_float / k_float,\n\n q_ii = x_int // k_int,\n q_if = x_int // k_float,\n q_fi = x_float // k_int,\n q_ff = x_float // k_float,\n\n r_ii = x_int % k_int,\n r_if = x_int % k_float,\n r_fi = x_float % k_int,\n r_ff = x_float % k_float,\n\n (q_ii * k_int + r_ii | math.round 0),\n (q_if * k_float + r_if | math.round 0),\n (q_fi * k_int + r_fi | math.round 0),\n (q_ff * k_float + r_ff | math.round 0),\n}\nsort id\n" +input_file: prqlc/prqlc/tests/integration/queries/arithmetic.prql +--- +--- generic ++++ clickhouse +@@ -25,42 +25,36 @@ + ALL + SELECT + 4 AS id, + -13 AS x_int, + -13.0 AS x_float, + -5 AS k_int, + -5.0 AS k_float + ) + SELECT + id, +- x_int / k_int, +- x_int / k_float, +- x_float / k_int, +- x_float / k_float, +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) AS q_ii, +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) AS q_if, +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) AS q_fi, +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) AS q_ff, ++ (x_int / k_int), ++ (x_int / k_float), ++ (x_float / k_int), ++ (x_float / k_float), ++ (x_int DIV k_int) AS q_ii, ++ (x_int DIV k_float) AS q_if, ++ (x_float DIV k_int) AS q_fi, ++ (x_float DIV k_float) AS q_ff, + x_int % k_int AS r_ii, + x_int % k_float AS r_if, + x_float % k_int AS r_fi, + x_float % k_float AS r_ff, +- ROUND( +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, +- 0 +- ), +- ROUND( +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) * k_float + x_int % k_float, +- 0 +- ), ++ ROUND((x_int DIV k_int) * k_int + x_int % k_int, 0), + ROUND( +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) * k_int + x_float % k_int, ++ (x_int DIV k_float) * k_float + x_int % k_float, + 0 + ), ++ ROUND((x_float DIV k_int) * k_int + x_float % k_int, 0), + ROUND( +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) * k_float + x_float % k_float, ++ (x_float DIV k_float) * k_float + x_float % k_float, + 0 + ) + FROM + table_0 + ORDER BY + id + +--- generic ++++ duckdb +@@ -25,42 +25,39 @@ + ALL + SELECT + 4 AS id, + -13 AS x_int, + -13.0 AS x_float, + -5 AS k_int, + -5.0 AS k_float + ) + SELECT + id, +- x_int / k_int, +- x_int / k_float, +- x_float / k_int, +- x_float / k_float, +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) AS q_ii, +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) AS q_if, +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) AS q_fi, +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) AS q_ff, ++ (x_int / k_int), ++ (x_int / k_float), ++ (x_float / k_int), ++ (x_float / k_float), ++ TRUNC(x_int / k_int) AS q_ii, ++ TRUNC(x_int / k_float) AS q_if, ++ TRUNC(x_float / k_int) AS q_fi, ++ TRUNC(x_float / k_float) AS q_ff, + x_int % k_int AS r_ii, + x_int % k_float AS r_if, + x_float % k_int AS r_fi, + x_float % k_float AS r_ff, +- ROUND( +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, +- 0 +- ), ++ ROUND(TRUNC(x_int / k_int) * k_int + x_int % k_int, 0), + ROUND( +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) * k_float + x_int % k_float, ++ TRUNC(x_int / k_float) * k_float + x_int % k_float, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) * k_int + x_float % k_int, ++ TRUNC(x_float / k_int) * k_int + x_float % k_int, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) * k_float + x_float % k_float, ++ TRUNC(x_float / k_float) * k_float + x_float % k_float, + 0 + ) + FROM + table_0 + ORDER BY + id + + +--- generic ++++ glaredb +@@ -25,42 +25,46 @@ + ALL + SELECT + 4 AS id, + -13 AS x_int, + -13.0 AS x_float, + -5 AS k_int, + -5.0 AS k_float + ) + SELECT + id, +- x_int / k_int, +- x_int / k_float, +- x_float / k_int, +- x_float / k_float, +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) AS q_ii, +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) AS q_if, +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) AS q_fi, +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) AS q_ff, ++ (x_int * 1.0 / k_int), ++ (x_int * 1.0 / k_float), ++ (x_float * 1.0 / k_int), ++ (x_float * 1.0 / k_float), ++ TRUNC(x_int / k_int) AS q_ii, ++ TRUNC(x_int / k_float) AS q_if, ++ TRUNC(x_float / k_int) AS q_fi, ++ TRUNC(x_float / k_float) AS q_ff, + x_int % k_int AS r_ii, + x_int % k_float AS r_if, + x_float % k_int AS r_fi, + x_float % k_float AS r_ff, + ROUND( +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, ++ (TRUNC(x_int / k_int) * k_int + x_int % k_int)::numeric, + 0 + ), + ROUND( +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) * k_float + x_int % k_float, ++ ( ++ TRUNC(x_int / k_float) * k_float + x_int % k_float ++ )::numeric, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) * k_int + x_float % k_int, ++ (TRUNC(x_float / k_int) * k_int + x_float % k_int)::numeric, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) * k_float + x_float % k_float, ++ ( ++ TRUNC(x_float / k_float) * k_float + x_float % k_float ++ )::numeric, + 0 + ) + FROM + table_0 + ORDER BY + id + +--- generic ++++ mssql +@@ -25,24 +25,24 @@ + ALL + SELECT + 4 AS id, + -13 AS x_int, + -13.0 AS x_float, + -5 AS k_int, + -5.0 AS k_float + ) + SELECT + id, +- x_int / k_int, +- x_int / k_float, +- x_float / k_int, +- x_float / k_float, ++ (x_int * 1.0 / k_int), ++ (x_int * 1.0 / k_float), ++ (x_float * 1.0 / k_int), ++ (x_float * 1.0 / k_float), + FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) AS q_ii, + FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) AS q_if, + FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) AS q_fi, + FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) AS q_ff, + x_int % k_int AS r_ii, + x_int % k_float AS r_if, + x_float % k_int AS r_fi, + x_float % k_float AS r_ff, + ROUND( + FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, + +--- generic ++++ mysql +@@ -25,42 +25,42 @@ + ALL + SELECT + 4 AS id, + -13 AS x_int, + -13.0 AS x_float, + -5 AS k_int, + -5.0 AS k_float + ) + SELECT + id, +- x_int / k_int, +- x_int / k_float, +- x_float / k_int, +- x_float / k_float, +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) AS q_ii, +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) AS q_if, +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) AS q_fi, +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) AS q_ff, +- x_int % k_int AS r_ii, +- x_int % k_float AS r_if, +- x_float % k_int AS r_fi, +- x_float % k_float AS r_ff, ++ (x_int / k_int), ++ (x_int / k_float), ++ (x_float / k_int), ++ (x_float / k_float), ++ (x_int DIV k_int) AS q_ii, ++ (x_int DIV k_float) AS q_if, ++ (x_float DIV k_int) AS q_fi, ++ (x_float DIV k_float) AS q_ff, ++ ROUND(MOD(x_int, k_int)) AS r_ii, ++ ROUND(MOD(x_int, k_float)) AS r_if, ++ ROUND(MOD(x_float, k_int)) AS r_fi, ++ ROUND(MOD(x_float, k_float)) AS r_ff, + ROUND( +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, ++ (x_int DIV k_int) * k_int + ROUND(MOD(x_int, k_int)), + 0 + ), + ROUND( +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) * k_float + x_int % k_float, ++ (x_int DIV k_float) * k_float + ROUND(MOD(x_int, k_float)), + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) * k_int + x_float % k_int, ++ (x_float DIV k_int) * k_int + ROUND(MOD(x_float, k_int)), + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) * k_float + x_float % k_float, ++ (x_float DIV k_float) * k_float + ROUND(MOD(x_float, k_float)), + 0 + ) + FROM + table_0 + ORDER BY + id + +--- generic ++++ postgres +@@ -25,42 +25,46 @@ + ALL + SELECT + 4 AS id, + -13 AS x_int, + -13.0 AS x_float, + -5 AS k_int, + -5.0 AS k_float + ) + SELECT + id, +- x_int / k_int, +- x_int / k_float, +- x_float / k_int, +- x_float / k_float, +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) AS q_ii, +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) AS q_if, +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) AS q_fi, +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) AS q_ff, ++ (x_int * 1.0 / k_int), ++ (x_int * 1.0 / k_float), ++ (x_float * 1.0 / k_int), ++ (x_float * 1.0 / k_float), ++ TRUNC(x_int / k_int) AS q_ii, ++ TRUNC(x_int / k_float) AS q_if, ++ TRUNC(x_float / k_int) AS q_fi, ++ TRUNC(x_float / k_float) AS q_ff, + x_int % k_int AS r_ii, + x_int % k_float AS r_if, + x_float % k_int AS r_fi, + x_float % k_float AS r_ff, + ROUND( +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, ++ (TRUNC(x_int / k_int) * k_int + x_int % k_int)::numeric, + 0 + ), + ROUND( +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) * k_float + x_int % k_float, ++ ( ++ TRUNC(x_int / k_float) * k_float + x_int % k_float ++ )::numeric, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) * k_int + x_float % k_int, ++ (TRUNC(x_float / k_int) * k_int + x_float % k_int)::numeric, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) * k_float + x_float % k_float, ++ ( ++ TRUNC(x_float / k_float) * k_float + x_float % k_float ++ )::numeric, + 0 + ) + FROM + table_0 + ORDER BY + id + +--- generic ++++ sqlite +@@ -25,42 +25,42 @@ + ALL + SELECT + 4 AS id, + -13 AS x_int, + -13.0 AS x_float, + -5 AS k_int, + -5.0 AS k_float + ) + SELECT + id, +- x_int / k_int, +- x_int / k_float, +- x_float / k_int, +- x_float / k_float, +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) AS q_ii, +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) AS q_if, +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) AS q_fi, +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) AS q_ff, ++ (x_int * 1.0 / k_int), ++ (x_int * 1.0 / k_float), ++ (x_float * 1.0 / k_int), ++ (x_float * 1.0 / k_float), ++ ROUND(ABS(x_int / k_int) - 0.5) * SIGN(x_int) * SIGN(k_int) AS q_ii, ++ ROUND(ABS(x_int / k_float) - 0.5) * SIGN(x_int) * SIGN(k_float) AS q_if, ++ ROUND(ABS(x_float / k_int) - 0.5) * SIGN(x_float) * SIGN(k_int) AS q_fi, ++ ROUND(ABS(x_float / k_float) - 0.5) * SIGN(x_float) * SIGN(k_float) AS q_ff, + x_int % k_int AS r_ii, + x_int % k_float AS r_if, + x_float % k_int AS r_fi, + x_float % k_float AS r_ff, + ROUND( +- FLOOR(ABS(x_int / k_int)) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, ++ ROUND(ABS(x_int / k_int) - 0.5) * SIGN(x_int) * SIGN(k_int) * k_int + x_int % k_int, + 0 + ), + ROUND( +- FLOOR(ABS(x_int / k_float)) * SIGN(x_int) * SIGN(k_float) * k_float + x_int % k_float, ++ ROUND(ABS(x_int / k_float) - 0.5) * SIGN(x_int) * SIGN(k_float) * k_float + x_int % k_float, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_int)) * SIGN(x_float) * SIGN(k_int) * k_int + x_float % k_int, ++ ROUND(ABS(x_float / k_int) - 0.5) * SIGN(x_float) * SIGN(k_int) * k_int + x_float % k_int, + 0 + ), + ROUND( +- FLOOR(ABS(x_float / k_float)) * SIGN(x_float) * SIGN(k_float) * k_float + x_float % k_float, ++ ROUND(ABS(x_float / k_float) - 0.5) * SIGN(x_float) * SIGN(k_float) * k_float + x_float % k_float, + 0 + ) + FROM + table_0 + ORDER BY + id diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__cast.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__cast.snap new file mode 100644 index 000000000000..902e7d317d93 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__cast.snap @@ -0,0 +1,30 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom tracks\nsort {-bytes}\nselect {\n name,\n bin = ((album_id | as REAL) * 99)\n}\ntake 20\n" +input_file: prqlc/prqlc/tests/integration/queries/cast.prql +--- +--- generic ++++ mssql +@@ -1,19 +1,19 @@ + WITH table_0 AS ( + SELECT + name, + CAST(album_id AS REAL) * 99 AS bin, + bytes + FROM + tracks + ORDER BY +- bytes DESC +- LIMIT +- 20 ++ bytes DESC OFFSET 0 ROWS ++ FETCH FIRST ++ 20 ROWS ONLY + ) + SELECT + name, + bin + FROM + table_0 + ORDER BY + bytes DESC diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__constants_only.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__constants_only.snap new file mode 100644 index 000000000000..67af006e177c --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__constants_only.snap @@ -0,0 +1,28 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "from genres\ntake 10\nfilter true\ntake 20\nfilter true\nselect d = 10\n" +input_file: prqlc/prqlc/tests/integration/queries/constants_only.prql +--- +--- generic ++++ postgres +@@ -1,20 +1,18 @@ + WITH table_1 AS ( + SELECT +- NULL + FROM + genres + LIMIT + 10 + ), table_0 AS ( + SELECT +- NULL + FROM + table_1 + WHERE + true + LIMIT + 20 + ) + SELECT + 10 AS d + FROM diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct.snap new file mode 100644 index 000000000000..5bf6834c33b5 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom tracks\nselect {album_id, genre_id}\ngroup tracks.* (take 1)\nsort tracks.*\n" +input_file: prqlc/prqlc/tests/integration/queries/distinct.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct_on.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct_on.snap new file mode 100644 index 000000000000..e4821e3c2726 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__distinct_on.snap @@ -0,0 +1,113 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom tracks\nselect {genre_id, media_type_id, album_id}\ngroup {genre_id, media_type_id} (sort {-album_id} | take 1)\nsort {-genre_id, media_type_id}\n" +input_file: prqlc/prqlc/tests/integration/queries/distinct_on.prql +--- +--- generic ++++ clickhouse +@@ -1,25 +1,21 @@ + WITH table_0 AS ( + SELECT +- genre_id, ++ DISTINCT ON (genre_id, media_type_id) genre_id, + media_type_id, +- album_id, +- ROW_NUMBER() OVER ( +- PARTITION BY genre_id, +- media_type_id +- ORDER BY +- album_id DESC +- ) AS _expr_0 ++ album_id + FROM + tracks ++ ORDER BY ++ genre_id, ++ media_type_id, ++ album_id DESC + ) + SELECT + genre_id, + media_type_id, + album_id + FROM + table_0 +-WHERE +- _expr_0 <= 1 + ORDER BY + genre_id DESC, + media_type_id + +--- generic ++++ duckdb +@@ -1,25 +1,21 @@ + WITH table_0 AS ( + SELECT +- genre_id, ++ DISTINCT ON (genre_id, media_type_id) genre_id, + media_type_id, +- album_id, +- ROW_NUMBER() OVER ( +- PARTITION BY genre_id, +- media_type_id +- ORDER BY +- album_id DESC +- ) AS _expr_0 ++ album_id + FROM + tracks ++ ORDER BY ++ genre_id, ++ media_type_id, ++ album_id DESC + ) + SELECT + genre_id, + media_type_id, + album_id + FROM + table_0 +-WHERE +- _expr_0 <= 1 + ORDER BY + genre_id DESC, + media_type_id + + + + + +--- generic ++++ postgres +@@ -1,25 +1,21 @@ + WITH table_0 AS ( + SELECT +- genre_id, ++ DISTINCT ON (genre_id, media_type_id) genre_id, + media_type_id, +- album_id, +- ROW_NUMBER() OVER ( +- PARTITION BY genre_id, +- media_type_id +- ORDER BY +- album_id DESC +- ) AS _expr_0 ++ album_id + FROM + tracks ++ ORDER BY ++ genre_id, ++ media_type_id, ++ album_id DESC + ) + SELECT + genre_id, + media_type_id, + album_id + FROM + table_0 +-WHERE +- _expr_0 <= 1 + ORDER BY + genre_id DESC, + media_type_id diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__genre_counts.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__genre_counts.snap new file mode 100644 index 000000000000..56090e5e1070 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__genre_counts.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# clickhouse:skip (ClickHouse prefers aliases to column names https://github.com/PRQL/prql/issues/2827)\n# mssql:test\nlet genre_count = (\n from genres\n aggregate {a = count name}\n)\n\nfrom genre_count\nfilter a > 0\nselect a = -a\n" +input_file: prqlc/prqlc/tests/integration/queries/genre_counts.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_all.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_all.snap new file mode 100644 index 000000000000..c12a3166b1fb --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_all.snap @@ -0,0 +1,88 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom a=albums\ntake 10\njoin tracks (==album_id)\ngroup {a.album_id, a.title} (aggregate price = (sum tracks.unit_price | math.round 2))\nsort album_id\n" +input_file: prqlc/prqlc/tests/integration/queries/group_all.prql +--- +--- generic ++++ glaredb +@@ -3,19 +3,22 @@ + album_id, + title + FROM + albums AS a + LIMIT + 10 + ) + SELECT + table_0.album_id, + table_0.title, +- ROUND(COALESCE(SUM(tracks.unit_price), 0), 2) AS price ++ ROUND( ++ (COALESCE(SUM(tracks.unit_price), 0))::numeric, ++ 2 ++ ) AS price + FROM + table_0 + INNER JOIN tracks ON table_0.album_id = tracks.album_id + GROUP BY + table_0.album_id, + table_0.title + ORDER BY + table_0.album_id + +--- generic ++++ mssql +@@ -1,18 +1,23 @@ + WITH table_0 AS ( + SELECT + album_id, + title + FROM + albums AS a +- LIMIT +- 10 ++ ORDER BY ++ ( ++ SELECT ++ NULL ++ ) OFFSET 0 ROWS ++ FETCH FIRST ++ 10 ROWS ONLY + ) + SELECT + table_0.album_id, + table_0.title, + ROUND(COALESCE(SUM(tracks.unit_price), 0), 2) AS price + FROM + table_0 + INNER JOIN tracks ON table_0.album_id = tracks.album_id + GROUP BY + table_0.album_id, + + +--- generic ++++ postgres +@@ -3,19 +3,22 @@ + album_id, + title + FROM + albums AS a + LIMIT + 10 + ) + SELECT + table_0.album_id, + table_0.title, +- ROUND(COALESCE(SUM(tracks.unit_price), 0), 2) AS price ++ ROUND( ++ (COALESCE(SUM(tracks.unit_price), 0))::numeric, ++ 2 ++ ) AS price + FROM + table_0 + INNER JOIN tracks ON table_0.album_id = tracks.album_id + GROUP BY + table_0.album_id, + table_0.title + ORDER BY + table_0.album_id diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort.snap new file mode 100644 index 000000000000..3c16dd9ddd15 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort.snap @@ -0,0 +1,32 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom tracks\nderive d = album_id + 1\ngroup d (\n aggregate {\n n1 = (track_id | sum),\n }\n)\nsort d\ntake 10\nselect { d1 = d, n1 }\n" +input_file: prqlc/prqlc/tests/integration/queries/group_sort.prql +--- +--- generic ++++ mssql +@@ -8,21 +8,21 @@ + album_id + 1 + ), + table_1 AS ( + SELECT + _expr_0 AS d1, + n1, + _expr_0 + FROM + table_0 + ORDER BY +- _expr_0 +- LIMIT +- 10 ++ _expr_0 OFFSET 0 ROWS ++ FETCH FIRST ++ 10 ROWS ONLY + ) + SELECT + d1, + n1 + FROM + table_1 + ORDER BY + d1 diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_derive_select_join.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_derive_select_join.snap new file mode 100644 index 000000000000..6c9f77da8d6a --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_derive_select_join.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "s\"SELECT album_id,title,artist_id FROM albums\"\ngroup {artist_id} (aggregate { album_title_count = count this.`title`})\nsort {this.artist_id, this.album_title_count}\nderive {new_album_count = this.album_title_count}\nselect {this.artist_id, this.new_album_count}\njoin side:left ( s\"SELECT artist_id,name as artist_name FROM artists\" ) (this.artist_id == that.artist_id)\n" +input_file: prqlc/prqlc/tests/integration/queries/group_sort_derive_select_join.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_filter_derive_select_join.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_filter_derive_select_join.snap new file mode 100644 index 000000000000..f2e049489a94 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_filter_derive_select_join.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "s\"SELECT album_id,title,artist_id FROM albums\"\ngroup {artist_id} (aggregate { album_title_count = count this.`title`})\nsort {this.artist_id, this.album_title_count}\nfilter (this.album_title_count) > 10\nderive {new_album_count = this.album_title_count}\nselect {this.artist_id, this.new_album_count}\njoin side:left ( s\"SELECT artist_id,name as artist_name FROM artists\" ) (this.artist_id == that.artist_id)\n" +input_file: prqlc/prqlc/tests/integration/queries/group_sort_filter_derive_select_join.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_limit_take.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_limit_take.snap new file mode 100644 index 000000000000..5ba2ae896dc6 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__group_sort_limit_take.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# Compute the 3 longest songs for each genre and sort by genre\n# mssql:test\nfrom tracks\nselect {genre_id,milliseconds}\ngroup {genre_id} (\n sort {-milliseconds}\n take 3\n)\njoin genres (==genre_id)\nselect {name, milliseconds}\nsort {+name,-milliseconds}\n" +input_file: prqlc/prqlc/tests/integration/queries/group_sort_limit_take.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__invoice_totals.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__invoice_totals.snap new file mode 100644 index 000000000000..bc517c10d1ee --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__invoice_totals.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# clickhouse:skip (clickhouse doesn't have lag function)\n\n#! Calculate a number of metrics about the sales of tracks in each city.\nfrom i=invoices\njoin ii=invoice_items (==invoice_id)\nderive {\n city = i.billing_city,\n street = i.billing_address,\n}\ngroup {city, street} (\n derive total = ii.unit_price * ii.quantity\n aggregate {\n num_orders = count_distinct i.invoice_id,\n num_tracks = sum ii.quantity,\n total_price = sum total,\n }\n)\ngroup {city} (\n sort street\n window expanding:true (\n derive {running_total_num_tracks = sum num_tracks}\n )\n)\nsort {city, street}\nderive {num_tracks_last_week = lag 7 num_tracks}\nselect {\n city,\n street,\n num_orders,\n num_tracks,\n running_total_num_tracks,\n num_tracks_last_week\n}\ntake 20\n" +input_file: prqlc/prqlc/tests/integration/queries/invoice_totals.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__loop_01.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__loop_01.snap new file mode 100644 index 000000000000..6ab6682d743c --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__loop_01.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# clickhouse:skip (DB::Exception: Syntax error)\n# glaredb:skip (DataFusion does not support recursive CTEs https://github.com/apache/arrow-datafusion/issues/462)\nfrom [{n = 1}]\nselect n = n - 2\nloop (filter n < 4 | select n = n + 1)\nselect n = n * 2\nsort n\n" +input_file: prqlc/prqlc/tests/integration/queries/loop_01.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__math_module.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__math_module.snap new file mode 100644 index 000000000000..c6ecc427418c --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__math_module.snap @@ -0,0 +1,109 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\n# sqlite:skip (see https://github.com/rusqlite/rusqlite/issues/1211)\nfrom invoices\ntake 5\nselect {\n total_original = (total | math.round 2),\n total_x = (math.pi - total | math.round 2 | math.abs),\n total_floor = (math.floor total),\n total_ceil = (math.ceil total),\n total_log10 = (math.log10 total | math.round 3),\n total_log2 = (math.log 2 total | math.round 3),\n total_sqrt = (math.sqrt total | math.round 3),\n total_ln = (math.ln total | math.exp | math.round 2),\n total_cos = (math.cos total | math.acos | math.round 2),\n total_sin = (math.sin total | math.asin | math.round 2),\n total_tan = (math.tan total | math.atan | math.round 2),\n total_deg = (total | math.degrees | math.radians | math.round 2),\n total_square = (total | math.pow 2 | math.round 2),\n total_square_op = ((total ** 2) | math.round 2),\n}\n" +input_file: prqlc/prqlc/tests/integration/queries/math_module.prql +--- +--- generic ++++ glaredb +@@ -1,19 +1,19 @@ + SELECT +- ROUND(total, 2) AS total_original, +- ABS(ROUND(PI() - total, 2)) AS total_x, ++ ROUND((total)::numeric, 2) AS total_original, ++ ABS(ROUND((PI() - total)::numeric, 2)) AS total_x, + FLOOR(total) AS total_floor, + CEIL(total) AS total_ceil, +- ROUND(LOG10(total), 3) AS total_log10, +- ROUND(LOG10(total) / LOG10(2), 3) AS total_log2, +- ROUND(SQRT(total), 3) AS total_sqrt, +- ROUND(EXP(LN(total)), 2) AS total_ln, +- ROUND(ACOS(COS(total)), 2) AS total_cos, +- ROUND(ASIN(SIN(total)), 2) AS total_sin, +- ROUND(ATAN(TAN(total)), 2) AS total_tan, +- ROUND(RADIANS(DEGREES(total)), 2) AS total_deg, +- ROUND(POW(total, 2), 2) AS total_square, +- ROUND(POW(total, 2), 2) AS total_square_op ++ ROUND((LOG10(total))::numeric, 3) AS total_log10, ++ ROUND((LOG10(total) / LOG10(2))::numeric, 3) AS total_log2, ++ ROUND((SQRT(total))::numeric, 3) AS total_sqrt, ++ ROUND((EXP(LN(total)))::numeric, 2) AS total_ln, ++ ROUND((ACOS(COS(total)))::numeric, 2) AS total_cos, ++ ROUND((ASIN(SIN(total)))::numeric, 2) AS total_sin, ++ ROUND((ATAN(TAN(total)))::numeric, 2) AS total_tan, ++ ROUND((RADIANS(DEGREES(total)))::numeric, 2) AS total_deg, ++ ROUND((POW(total, 2))::numeric, 2) AS total_square, ++ ROUND((POW(total, 2))::numeric, 2) AS total_square_op + FROM + invoices + LIMIT + 5 + +--- generic ++++ mssql +@@ -1,19 +1,24 @@ + SELECT + ROUND(total, 2) AS total_original, + ABS(ROUND(PI() - total, 2)) AS total_x, + FLOOR(total) AS total_floor, +- CEIL(total) AS total_ceil, ++ CEILING(total) AS total_ceil, + ROUND(LOG10(total), 3) AS total_log10, + ROUND(LOG10(total) / LOG10(2), 3) AS total_log2, + ROUND(SQRT(total), 3) AS total_sqrt, +- ROUND(EXP(LN(total)), 2) AS total_ln, ++ ROUND(EXP(LOG(total)), 2) AS total_ln, + ROUND(ACOS(COS(total)), 2) AS total_cos, + ROUND(ASIN(SIN(total)), 2) AS total_sin, + ROUND(ATAN(TAN(total)), 2) AS total_tan, + ROUND(RADIANS(DEGREES(total)), 2) AS total_deg, +- ROUND(POW(total, 2), 2) AS total_square, +- ROUND(POW(total, 2), 2) AS total_square_op ++ ROUND(POWER(total, 2), 2) AS total_square, ++ ROUND(POWER(total, 2), 2) AS total_square_op + FROM + invoices +-LIMIT +- 5 ++ORDER BY ++ ( ++ SELECT ++ NULL ++ ) OFFSET 0 ROWS ++FETCH FIRST ++ 5 ROWS ONLY + + +--- generic ++++ postgres +@@ -1,19 +1,19 @@ + SELECT +- ROUND(total, 2) AS total_original, +- ABS(ROUND(PI() - total, 2)) AS total_x, ++ ROUND((total)::numeric, 2) AS total_original, ++ ABS(ROUND((PI() - total)::numeric, 2)) AS total_x, + FLOOR(total) AS total_floor, + CEIL(total) AS total_ceil, +- ROUND(LOG10(total), 3) AS total_log10, +- ROUND(LOG10(total) / LOG10(2), 3) AS total_log2, +- ROUND(SQRT(total), 3) AS total_sqrt, +- ROUND(EXP(LN(total)), 2) AS total_ln, +- ROUND(ACOS(COS(total)), 2) AS total_cos, +- ROUND(ASIN(SIN(total)), 2) AS total_sin, +- ROUND(ATAN(TAN(total)), 2) AS total_tan, +- ROUND(RADIANS(DEGREES(total)), 2) AS total_deg, +- ROUND(POW(total, 2), 2) AS total_square, +- ROUND(POW(total, 2), 2) AS total_square_op ++ ROUND((LOG10(total))::numeric, 3) AS total_log10, ++ ROUND((LOG10(total) / LOG10(2))::numeric, 3) AS total_log2, ++ ROUND((SQRT(total))::numeric, 3) AS total_sqrt, ++ ROUND((EXP(LN(total)))::numeric, 2) AS total_ln, ++ ROUND((ACOS(COS(total)))::numeric, 2) AS total_cos, ++ ROUND((ASIN(SIN(total)))::numeric, 2) AS total_sin, ++ ROUND((ATAN(TAN(total)))::numeric, 2) AS total_tan, ++ ROUND((RADIANS(DEGREES(total)))::numeric, 2) AS total_deg, ++ ROUND((POW(total, 2))::numeric, 2) AS total_square, ++ ROUND((POW(total, 2))::numeric, 2) AS total_square_op + FROM + invoices + LIMIT + 5 diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__pipelines.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__pipelines.snap new file mode 100644 index 000000000000..3c81172f0ef4 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__pipelines.snap @@ -0,0 +1,135 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# sqlite:skip (Only works on Sqlite implementations which have the extension\n# installed\n# https://stackoverflow.com/questions/24037982/how-to-use-regexp-in-sqlite)\n\nfrom tracks\n\nfilter (name ~= \"Love\")\nfilter ((milliseconds / 1000 / 60) | in 3..4)\nsort track_id\ntake 1..15\nselect {name, composer}\n" +input_file: prqlc/prqlc/tests/integration/queries/pipelines.prql +--- +--- generic ++++ clickhouse +@@ -1,20 +1,20 @@ + WITH table_0 AS ( + SELECT + name, + composer, + track_id + FROM + tracks + WHERE +- REGEXP(name, 'Love') +- AND milliseconds / 1000 / 60 BETWEEN 3 AND 4 ++ match(name, 'Love') ++ AND ((milliseconds / 1000) / 60) BETWEEN 3 AND 4 + ORDER BY + track_id + LIMIT + 15 + ) + SELECT + name, + composer + FROM + table_0 + +--- generic ++++ duckdb +@@ -1,20 +1,20 @@ + WITH table_0 AS ( + SELECT + name, + composer, + track_id + FROM + tracks + WHERE +- REGEXP(name, 'Love') +- AND milliseconds / 1000 / 60 BETWEEN 3 AND 4 ++ REGEXP_MATCHES(name, 'Love') ++ AND ((milliseconds / 1000) / 60) BETWEEN 3 AND 4 + ORDER BY + track_id + LIMIT + 15 + ) + SELECT + name, + composer + FROM + table_0 + + +--- generic ++++ glaredb +@@ -1,20 +1,20 @@ + WITH table_0 AS ( + SELECT + name, + composer, + track_id + FROM + tracks + WHERE +- REGEXP(name, 'Love') +- AND milliseconds / 1000 / 60 BETWEEN 3 AND 4 ++ name ~ 'Love' ++ AND ((milliseconds * 1.0 / 1000) * 1.0 / 60) BETWEEN 3 AND 4 + ORDER BY + track_id + LIMIT + 15 + ) + SELECT + name, + composer + FROM + table_0 + +--- generic ++++ mysql +@@ -1,20 +1,20 @@ + WITH table_0 AS ( + SELECT + name, + composer, + track_id + FROM + tracks + WHERE +- REGEXP(name, 'Love') +- AND milliseconds / 1000 / 60 BETWEEN 3 AND 4 ++ REGEXP_LIKE(name, 'Love', 'c') ++ AND ((milliseconds / 1000) / 60) BETWEEN 3 AND 4 + ORDER BY + track_id + LIMIT + 15 + ) + SELECT + name, + composer + FROM + table_0 + +--- generic ++++ postgres +@@ -1,20 +1,20 @@ + WITH table_0 AS ( + SELECT + name, + composer, + track_id + FROM + tracks + WHERE +- REGEXP(name, 'Love') +- AND milliseconds / 1000 / 60 BETWEEN 3 AND 4 ++ name ~ 'Love' ++ AND ((milliseconds * 1.0 / 1000) * 1.0 / 60) BETWEEN 3 AND 4 + ORDER BY + track_id + LIMIT + 15 + ) + SELECT + name, + composer + FROM + table_0 diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__read_csv.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__read_csv.snap new file mode 100644 index 000000000000..8fb05d5f393e --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__read_csv.snap @@ -0,0 +1,56 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# sqlite:skip\n# postgres:skip\n# mysql:skip\nfrom (read_csv \"data_file_root/media_types.csv\")\nsort media_type_id\n" +input_file: prqlc/prqlc/tests/integration/queries/read_csv.prql +--- +--- generic ++++ clickhouse +@@ -1,12 +1,12 @@ + WITH table_0 AS ( + SELECT + * + FROM +- read_csv('data_file_root/media_types.csv') ++ file('data_file_root/media_types.csv', 'CSV') + ) + SELECT + * + FROM + table_0 + ORDER BY + media_type_id + +--- generic ++++ duckdb +@@ -1,12 +1,12 @@ + WITH table_0 AS ( + SELECT + * + FROM +- read_csv('data_file_root/media_types.csv') ++ read_csv_auto('data_file_root/media_types.csv') + ) + SELECT + * + FROM + table_0 + ORDER BY + media_type_id + + +--- generic ++++ glaredb +@@ -1,12 +1,12 @@ + WITH table_0 AS ( + SELECT + * + FROM +- read_csv('data_file_root/media_types.csv') ++ csv_scan('data_file_root/media_types.csv') + ) + SELECT + * + FROM + table_0 + ORDER BY + media_type_id diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__set_ops_remove.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__set_ops_remove.snap new file mode 100644 index 000000000000..c4c39a88ff33 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__set_ops_remove.snap @@ -0,0 +1,56 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nlet distinct = rel -> (from t = _param.rel | group {t.*} (take 1))\n\nfrom_text format:json '{ \"columns\": [\"a\"], \"data\": [[1], [2], [2], [3]] }'\ndistinct\nremove (from_text format:json '{ \"columns\": [\"a\"], \"data\": [[1], [2]] }')\nsort a\n" +input_file: prqlc/prqlc/tests/integration/queries/set_ops_remove.prql +--- +--- generic ++++ mssql +@@ -21,21 +21,20 @@ + ALL + SELECT + 2 AS a + ), + table_2 AS ( + SELECT + a + FROM + table_0 + EXCEPT +- DISTINCT + SELECT + * + FROM + table_1 + ) + SELECT + a + FROM + table_2 + ORDER BY + + + +--- generic ++++ sqlite +@@ -21,21 +21,20 @@ + ALL + SELECT + 2 AS a + ), + table_2 AS ( + SELECT + a + FROM + table_0 + EXCEPT +- DISTINCT + SELECT + * + FROM + table_1 + ) + SELECT + a + FROM + table_2 + ORDER BY diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort.snap new file mode 100644 index 000000000000..d08fbb8dd9c2 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom e=employees\nfilter first_name != \"Mitchell\"\nsort {first_name, last_name}\n\n# joining may use HashMerge, which can undo ORDER BY\njoin manager=employees side:left (e.reports_to == manager.employee_id)\n\nselect {e.first_name, e.last_name, manager.first_name}\n" +input_file: prqlc/prqlc/tests/integration/queries/sort.prql +--- + diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_2.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_2.snap new file mode 100644 index 000000000000..844b2b3adce3 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_2.snap @@ -0,0 +1,75 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "from albums\nselect { AA=album_id, artist_id }\nsort AA\nfilter AA >= 25\njoin artists (==artist_id)\n" +input_file: prqlc/prqlc/tests/integration/queries/sort_2.prql +--- +--- generic ++++ clickhouse +@@ -1,25 +1,25 @@ + WITH table_1 AS ( + SELECT +- album_id AS "AA", ++ album_id AS `AA`, + artist_id + FROM + albums + ), + table_0 AS ( + SELECT +- "AA", ++ `AA`, + artist_id + FROM + table_1 + WHERE +- "AA" >= 25 ++ `AA` >= 25 + ) + SELECT +- table_0."AA", ++ table_0.`AA`, + table_0.artist_id, + artists.* + FROM + table_0 + INNER JOIN artists ON table_0.artist_id = artists.artist_id + ORDER BY +- table_0."AA" ++ table_0.`AA` + + + + +--- generic ++++ mysql +@@ -1,25 +1,25 @@ + WITH table_1 AS ( + SELECT +- album_id AS "AA", ++ album_id AS `AA`, + artist_id + FROM + albums + ), + table_0 AS ( + SELECT +- "AA", ++ `AA`, + artist_id + FROM + table_1 + WHERE +- "AA" >= 25 ++ `AA` >= 25 + ) + SELECT +- table_0."AA", ++ table_0.`AA`, + table_0.artist_id, + artists.* + FROM + table_0 + INNER JOIN artists ON table_0.artist_id = artists.artist_id + ORDER BY +- table_0."AA" ++ table_0.`AA` diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_3.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_3.snap new file mode 100644 index 000000000000..6f00fa61ea58 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__sort_3.snap @@ -0,0 +1,139 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "from [{track_id=0, album_id=1, genre_id=2}]\nselect { AA=track_id, album_id, genre_id }\nsort AA\njoin side:left [{album_id=1, album_title=\"Songs\"}] (==album_id)\nselect { AA, AT = album_title ?? \"unknown\", genre_id }\nfilter AA < 25\njoin side:left [{genre_id=1, genre_title=\"Rock\"}] (==genre_id)\nselect { AA, AT, GT = genre_title ?? \"unknown\" }\n" +input_file: prqlc/prqlc/tests/integration/queries/sort_3.prql +--- +--- generic ++++ clickhouse +@@ -1,52 +1,52 @@ + WITH table_0 AS ( + SELECT + 0 AS track_id, + 1 AS album_id, + 2 AS genre_id + ), + table_5 AS ( + SELECT +- track_id AS "AA", ++ track_id AS `AA`, + genre_id, + album_id + FROM + table_0 + ), + table_1 AS ( + SELECT + 1 AS album_id, + 'Songs' AS album_title + ), + table_4 AS ( + SELECT +- table_5."AA", +- COALESCE(table_1.album_title, 'unknown') AS "AT", ++ table_5.`AA`, ++ COALESCE(table_1.album_title, 'unknown') AS `AT`, + table_5.genre_id + FROM + table_5 + LEFT OUTER JOIN table_1 ON table_5.album_id = table_1.album_id + ), + table_3 AS ( + SELECT +- "AA", +- "AT", ++ `AA`, ++ `AT`, + genre_id + FROM + table_4 + WHERE +- "AA" < 25 ++ `AA` < 25 + ), + table_2 AS ( + SELECT + 1 AS genre_id, + 'Rock' AS genre_title + ) + SELECT +- table_3."AA", +- table_3."AT", +- COALESCE(table_2.genre_title, 'unknown') AS "GT" ++ table_3.`AA`, ++ table_3.`AT`, ++ COALESCE(table_2.genre_title, 'unknown') AS `GT` + FROM + table_3 + LEFT OUTER JOIN table_2 ON table_3.genre_id = table_2.genre_id + ORDER BY +- table_3."AA" ++ table_3.`AA` + + + + +--- generic ++++ mysql +@@ -1,52 +1,52 @@ + WITH table_0 AS ( + SELECT + 0 AS track_id, + 1 AS album_id, + 2 AS genre_id + ), + table_5 AS ( + SELECT +- track_id AS "AA", ++ track_id AS `AA`, + genre_id, + album_id + FROM + table_0 + ), + table_1 AS ( + SELECT + 1 AS album_id, + 'Songs' AS album_title + ), + table_4 AS ( + SELECT +- table_5."AA", +- COALESCE(table_1.album_title, 'unknown') AS "AT", ++ table_5.`AA`, ++ COALESCE(table_1.album_title, 'unknown') AS `AT`, + table_5.genre_id + FROM + table_5 + LEFT OUTER JOIN table_1 ON table_5.album_id = table_1.album_id + ), + table_3 AS ( + SELECT +- "AA", +- "AT", ++ `AA`, ++ `AT`, + genre_id + FROM + table_4 + WHERE +- "AA" < 25 ++ `AA` < 25 + ), + table_2 AS ( + SELECT + 1 AS genre_id, + 'Rock' AS genre_title + ) + SELECT +- table_3."AA", +- table_3."AT", +- COALESCE(table_2.genre_title, 'unknown') AS "GT" ++ table_3.`AA`, ++ table_3.`AT`, ++ COALESCE(table_2.genre_title, 'unknown') AS `GT` + FROM + table_3 + LEFT OUTER JOIN table_2 ON table_3.genre_id = table_2.genre_id + ORDER BY +- table_3."AA" ++ table_3.`AA` diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__switch.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__switch.snap new file mode 100644 index 000000000000..1eb4672e1cbb --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__switch.snap @@ -0,0 +1,31 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# glaredb:skip (May be a bag of String type conversion for Postgres Client)\n# mssql:test\nfrom tracks\nsort milliseconds\nselect display = case [\n composer != null => composer,\n genre_id < 17 => 'no composer',\n true => f'unknown composer'\n]\ntake 10\n" +input_file: prqlc/prqlc/tests/integration/queries/switch.prql +--- +--- generic ++++ mssql +@@ -2,20 +2,20 @@ + SELECT + CASE + WHEN composer IS NOT NULL THEN composer + WHEN genre_id < 17 THEN 'no composer' + ELSE 'unknown composer' + END AS display, + milliseconds + FROM + tracks + ORDER BY +- milliseconds +- LIMIT +- 10 ++ milliseconds OFFSET 0 ROWS ++ FETCH FIRST ++ 10 ROWS ONLY + ) + SELECT + display + FROM + table_0 + ORDER BY + milliseconds diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__take.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__take.snap new file mode 100644 index 000000000000..cd091395cf97 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__take.snap @@ -0,0 +1,19 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\nfrom tracks\nsort {+track_id}\ntake 3..5\n" +input_file: prqlc/prqlc/tests/integration/queries/take.prql +--- +--- generic ++++ mssql +@@ -1,8 +1,8 @@ + SELECT + * + FROM + tracks + ORDER BY +- track_id +-LIMIT +- 3 OFFSET 2 ++ track_id OFFSET 2 ROWS ++FETCH FIRST ++ 3 ROWS ONLY diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__text_module.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__text_module.snap new file mode 100644 index 000000000000..75c717ea6564 --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__text_module.snap @@ -0,0 +1,202 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# mssql:test\n# glaredb:skip — TODO: started raising an error on 2024-05-20; see `window.prql`\n# for more details\nfrom albums\nselect {\n title,\n title_and_spaces = f\" {title} \",\n low = (title | text.lower),\n up = (title | text.upper),\n ltrimmed = (title | text.ltrim),\n rtrimmed = (title | text.rtrim),\n trimmed = (title | text.trim),\n len = (title | text.length),\n subs = (title | text.extract 2 5),\n replace = (title | text.replace \"al\" \"PIKA\"),\n}\nsort {title}\nfilter (title | text.starts_with \"Black\") || (title | text.contains \"Sabbath\") || (title | text.ends_with \"os\")\n" +input_file: prqlc/prqlc/tests/integration/queries/text_module.prql +--- +--- generic ++++ clickhouse +@@ -2,33 +2,33 @@ + SELECT + title, + CONCAT(' ', title, ' ') AS title_and_spaces, + LOWER(title) AS low, + UPPER(title) AS up, + LTRIM(title) AS ltrimmed, + RTRIM(title) AS rtrimmed, + TRIM(title) AS trimmed, + CHAR_LENGTH(title) AS len, + SUBSTRING(title, 2, 5) AS subs, +- REPLACE(title, 'al', 'PIKA') AS "replace" ++ REPLACE(title, 'al', 'PIKA') AS `replace` + FROM + albums + ) + SELECT + title, + title_and_spaces, + low, + up, + ltrimmed, + rtrimmed, + trimmed, + len, + subs, +- "replace" ++ `replace` + FROM + table_0 + WHERE + title LIKE CONCAT('Black', '%') + OR title LIKE CONCAT('%', 'Sabbath', '%') + OR title LIKE CONCAT('%', 'os') + ORDER BY + title + +--- generic ++++ duckdb +@@ -1,20 +1,20 @@ + WITH table_0 AS ( + SELECT + title, + CONCAT(' ', title, ' ') AS title_and_spaces, + LOWER(title) AS low, + UPPER(title) AS up, + LTRIM(title) AS ltrimmed, + RTRIM(title) AS rtrimmed, + TRIM(title) AS trimmed, +- CHAR_LENGTH(title) AS len, ++ LENGTH(title) AS len, + SUBSTRING(title, 2, 5) AS subs, + REPLACE(title, 'al', 'PIKA') AS "replace" + FROM + albums + ) + SELECT + title, + title_and_spaces, + low, + up, + + +--- generic ++++ mssql +@@ -1,20 +1,20 @@ + WITH table_0 AS ( + SELECT + title, + CONCAT(' ', title, ' ') AS title_and_spaces, + LOWER(title) AS low, + UPPER(title) AS up, + LTRIM(title) AS ltrimmed, + RTRIM(title) AS rtrimmed, + TRIM(title) AS trimmed, +- CHAR_LENGTH(title) AS len, ++ LEN(title) AS len, + SUBSTRING(title, 2, 5) AS subs, + REPLACE(title, 'al', 'PIKA') AS "replace" + FROM + albums + ) + SELECT + title, + title_and_spaces, + low, + up, + +--- generic ++++ mysql +@@ -2,33 +2,33 @@ + SELECT + title, + CONCAT(' ', title, ' ') AS title_and_spaces, + LOWER(title) AS low, + UPPER(title) AS up, + LTRIM(title) AS ltrimmed, + RTRIM(title) AS rtrimmed, + TRIM(title) AS trimmed, + CHAR_LENGTH(title) AS len, + SUBSTRING(title, 2, 5) AS subs, +- REPLACE(title, 'al', 'PIKA') AS "replace" ++ REPLACE(title, 'al', 'PIKA') AS `replace` + FROM + albums + ) + SELECT + title, + title_and_spaces, + low, + up, + ltrimmed, + rtrimmed, + trimmed, + len, + subs, +- "replace" ++ `replace` + FROM + table_0 + WHERE + title LIKE CONCAT('Black', '%') + OR title LIKE CONCAT('%', 'Sabbath', '%') + OR title LIKE CONCAT('%', 'os') + ORDER BY + title + +--- generic ++++ postgres +@@ -1,21 +1,21 @@ + WITH table_0 AS ( + SELECT + title, + CONCAT(' ', title, ' ') AS title_and_spaces, + LOWER(title) AS low, + UPPER(title) AS up, + LTRIM(title) AS ltrimmed, + RTRIM(title) AS rtrimmed, + TRIM(title) AS trimmed, + CHAR_LENGTH(title) AS len, +- SUBSTRING(title, 2, 5) AS subs, ++ SUBSTR(title, 2, 5) AS subs, + REPLACE(title, 'al', 'PIKA') AS "replace" + FROM + albums + ) + SELECT + title, + title_and_spaces, + low, + up, + ltrimmed, + +--- generic ++++ sqlite +@@ -1,34 +1,34 @@ + WITH table_0 AS ( + SELECT + title, +- CONCAT(' ', title, ' ') AS title_and_spaces, ++ ' ' || title || ' ' AS title_and_spaces, + LOWER(title) AS low, + UPPER(title) AS up, + LTRIM(title) AS ltrimmed, + RTRIM(title) AS rtrimmed, + TRIM(title) AS trimmed, +- CHAR_LENGTH(title) AS len, ++ LENGTH(title) AS len, + SUBSTRING(title, 2, 5) AS subs, + REPLACE(title, 'al', 'PIKA') AS "replace" + FROM + albums + ) + SELECT + title, + title_and_spaces, + low, + up, + ltrimmed, + rtrimmed, + trimmed, + len, + subs, + "replace" + FROM + table_0 + WHERE +- title LIKE CONCAT('Black', '%') +- OR title LIKE CONCAT('%', 'Sabbath', '%') +- OR title LIKE CONCAT('%', 'os') ++ title LIKE 'Black' || '%' ++ OR title LIKE '%' || 'Sabbath' || '%' ++ OR title LIKE '%' || 'os' + ORDER BY + title diff --git a/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__window.snap b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__window.snap new file mode 100644 index 000000000000..b591efd8269f --- /dev/null +++ b/prqlc/prqlc/tests/integration/snapshots/integration__queries__compileall__window.snap @@ -0,0 +1,6 @@ +--- +source: prqlc/prqlc/tests/integration/queries.rs +expression: "# clickhouse:skip problems with DISTINCT ON\n# glaredb:skip — TODO: started raising an error on 2024-05-20, from https://github.com/PRQL/prql/actions/runs/9154902656/job/25198160283:\n # ERROR: This feature is not implemented: Unsupported ast node in sqltorel:\n # Substring { expr: Identifier(Ident { value: \"title\", quote_style: None }),\n # substring_from: Some(Value(Number(\"2\", false))), substring_for:\n # Some(Value(Number(\"5\", false))), special: true }\nfrom tracks\ngroup genre_id (\n sort milliseconds\n derive {\n num = row_number this,\n total = count this,\n last_val = last track_id,\n }\n take 10\n)\nsort {genre_id, milliseconds}\nselect {track_id, genre_id, num, total, last_val}\nfilter genre_id >= 22\n" +input_file: prqlc/prqlc/tests/integration/queries/window.prql +--- + From 0ffdf671145d8e0ff1de15393e00e5e41bb8ec7e Mon Sep 17 00:00:00 2001 From: Karl Gutwin Date: Tue, 1 Jul 2025 18:26:14 -0400 Subject: [PATCH 2/2] extend test timeouts for compileall --- .config/nextest.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.config/nextest.toml b/.config/nextest.toml index 29c36020c482..d64e469013cf 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -3,6 +3,11 @@ fail-fast = false failure-output = "final" slow-timeout = {period = "500ms", terminate-after = 4} +[[profile.default.overrides]] +# compileall does many passes over the same query, so it takes a bit longer +filter = 'package(prqlc) & test(queries::compileall::)' +slow-timeout = {period = "10s", terminate-after = 2} + [[profile.default.overrides]] filter = 'package(prqlc) & test(queries::results::)' slow-timeout = {period = "10s", terminate-after = 4}