From f92089d3cccae653c33a658bcb27a261ded93fea Mon Sep 17 00:00:00 2001 From: ila Date: Wed, 11 Nov 2026 15:03:04 +0100 Subject: [PATCH] WIP: separate TPC-DS handwritten benchmarks and validation --- benchmark/configs/utility/as_tpcds_sf30.json | 12 + benchmark/microbench/approx_sum_stability.sql | 8 +- benchmark/tpcds/as_queries/q01.sql | 23 + benchmark/tpcds/as_queries/q03.sql | 14 + benchmark/tpcds/as_queries/q04.sql | 120 +++++ benchmark/tpcds/as_queries/q06.sql | 26 ++ benchmark/tpcds/as_queries/q07.sql | 24 + benchmark/tpcds/as_queries/q09.sql | 8 + benchmark/tpcds/as_queries/q10.sql | 66 +++ benchmark/tpcds/as_queries/q11.sql | 80 ++++ benchmark/tpcds/as_queries/q13.sql | 43 ++ benchmark/tpcds/as_queries/q15.sql | 28 ++ benchmark/tpcds/as_queries/q16.sql | 24 + benchmark/tpcds/as_queries/q17.sql | 48 ++ benchmark/tpcds/as_queries/q18.sql | 50 ++ benchmark/tpcds/as_queries/q19.sql | 31 ++ benchmark/tpcds/as_queries/q23.sql | 83 ++++ benchmark/tpcds/as_queries/q24.sql | 53 +++ benchmark/tpcds/as_queries/q25.sql | 42 ++ benchmark/tpcds/as_queries/q26.sql | 24 + benchmark/tpcds/as_queries/q27.sql | 61 +++ benchmark/tpcds/as_queries/q28.sql | 45 ++ benchmark/tpcds/as_queries/q29.sql | 42 ++ benchmark/tpcds/as_queries/q30.sql | 49 ++ benchmark/tpcds/as_queries/q31.sql | 69 +++ benchmark/tpcds/as_queries/q32.sql | 22 + benchmark/tpcds/as_queries/q33.sql | 64 +++ benchmark/tpcds/as_queries/q34.sql | 42 ++ benchmark/tpcds/as_queries/q35.sql | 61 +++ benchmark/tpcds/as_queries/q40.sql | 27 ++ benchmark/tpcds/as_queries/q42.sql | 15 + benchmark/tpcds/as_queries/q43.sql | 13 + benchmark/tpcds/as_queries/q45.sql | 42 ++ benchmark/tpcds/as_queries/q46.sql | 48 ++ benchmark/tpcds/as_queries/q48.sql | 40 ++ benchmark/tpcds/as_queries/q50.sql | 68 +++ benchmark/tpcds/as_queries/q52.sql | 15 + benchmark/tpcds/as_queries/q55.sql | 14 + benchmark/tpcds/as_queries/q56.sql | 71 +++ benchmark/tpcds/as_queries/q58.sql | 68 +++ benchmark/tpcds/as_queries/q59.sql | 85 ++++ benchmark/tpcds/as_queries/q60.sql | 65 +++ benchmark/tpcds/as_queries/q61.sql | 44 ++ benchmark/tpcds/as_queries/q62.sql | 46 ++ benchmark/tpcds/as_queries/q64.sql | 124 +++++ benchmark/tpcds/as_queries/q65.sql | 23 + benchmark/tpcds/as_queries/q66.sql | 221 +++++++++ benchmark/tpcds/as_queries/q68.sql | 45 ++ benchmark/tpcds/as_queries/q69.sql | 52 +++ benchmark/tpcds/as_queries/q72.sql | 40 ++ benchmark/tpcds/as_queries/q73.sql | 42 ++ benchmark/tpcds/as_queries/q74.sql | 64 +++ benchmark/tpcds/as_queries/q77.sql | 91 ++++ benchmark/tpcds/as_queries/q78.sql | 75 +++ benchmark/tpcds/as_queries/q79.sql | 39 ++ benchmark/tpcds/as_queries/q80.sql | 85 ++++ benchmark/tpcds/as_queries/q81.sql | 55 +++ benchmark/tpcds/as_queries/q83.sql | 68 +++ benchmark/tpcds/as_queries/q85.sql | 60 +++ benchmark/tpcds/as_queries/q88.sql | 139 ++++++ benchmark/tpcds/as_queries/q90.sql | 26 ++ benchmark/tpcds/as_queries/q91.sql | 31 ++ benchmark/tpcds/as_queries/q92.sql | 22 + benchmark/tpcds/as_queries/q93.sql | 20 + benchmark/tpcds/as_queries/q94.sql | 24 + benchmark/tpcds/as_queries/q95.sql | 30 ++ benchmark/tpcds/as_queries/q96.sql | 15 + benchmark/tpcds/as_queries/q99.sql | 45 ++ benchmark/tpcds/as_tpcds_benchmark.cpp | 426 +++++++++++++++++- benchmark/tpcds/q17_fixture.sql | 22 + benchmark/tpcds/reference_queries/q01.sql | 30 ++ benchmark/tpcds/reference_queries/q03.sql | 30 ++ benchmark/tpcds/reference_queries/q04.sql | 135 ++++++ benchmark/tpcds/reference_queries/q06.sql | 36 ++ benchmark/tpcds/reference_queries/q07.sql | 38 ++ benchmark/tpcds/reference_queries/q09.sql | 17 + benchmark/tpcds/reference_queries/q10.sql | 59 +++ benchmark/tpcds/reference_queries/q11.sql | 93 ++++ benchmark/tpcds/reference_queries/q13.sql | 55 +++ benchmark/tpcds/reference_queries/q15.sql | 39 ++ benchmark/tpcds/reference_queries/q16.sql | 10 + benchmark/tpcds/reference_queries/q17.sql | 67 +++ benchmark/tpcds/reference_queries/q18.sql | 68 +++ benchmark/tpcds/reference_queries/q19.sql | 41 ++ benchmark/tpcds/reference_queries/q23.sql | 96 ++++ benchmark/tpcds/reference_queries/q24.sql | 58 +++ benchmark/tpcds/reference_queries/q25.sql | 54 +++ benchmark/tpcds/reference_queries/q26.sql | 38 ++ benchmark/tpcds/reference_queries/q27.sql | 25 + benchmark/tpcds/reference_queries/q28.sql | 9 + benchmark/tpcds/reference_queries/q29.sql | 55 +++ benchmark/tpcds/reference_queries/q30.sql | 68 +++ benchmark/tpcds/reference_queries/q31.sql | 85 ++++ benchmark/tpcds/reference_queries/q32.sql | 14 + benchmark/tpcds/reference_queries/q33.sql | 90 ++++ benchmark/tpcds/reference_queries/q34.sql | 51 +++ benchmark/tpcds/reference_queries/q35.sql | 111 +++++ benchmark/tpcds/reference_queries/q40.sql | 16 + benchmark/tpcds/reference_queries/q42.sql | 31 ++ benchmark/tpcds/reference_queries/q43.sql | 39 ++ benchmark/tpcds/reference_queries/q45.sql | 53 +++ benchmark/tpcds/reference_queries/q46.sql | 61 +++ benchmark/tpcds/reference_queries/q48.sql | 50 ++ benchmark/tpcds/reference_queries/q50.sql | 65 +++ benchmark/tpcds/reference_queries/q52.sql | 31 ++ benchmark/tpcds/reference_queries/q55.sql | 28 ++ benchmark/tpcds/reference_queries/q56.sql | 98 ++++ benchmark/tpcds/reference_queries/q58.sql | 93 ++++ benchmark/tpcds/reference_queries/q59.sql | 94 ++++ benchmark/tpcds/reference_queries/q60.sql | 92 ++++ benchmark/tpcds/reference_queries/q61.sql | 49 ++ benchmark/tpcds/reference_queries/q62.sql | 43 ++ benchmark/tpcds/reference_queries/q64.sql | 133 ++++++ benchmark/tpcds/reference_queries/q65.sql | 17 + benchmark/tpcds/reference_queries/q66.sql | 227 ++++++++++ benchmark/tpcds/reference_queries/q68.sql | 56 +++ benchmark/tpcds/reference_queries/q69.sql | 49 ++ benchmark/tpcds/reference_queries/q72.sql | 20 + benchmark/tpcds/reference_queries/q73.sql | 50 ++ benchmark/tpcds/reference_queries/q74.sql | 74 +++ benchmark/tpcds/reference_queries/q77.sql | 114 +++++ benchmark/tpcds/reference_queries/q78.sql | 80 ++++ benchmark/tpcds/reference_queries/q79.sql | 53 +++ benchmark/tpcds/reference_queries/q80.sql | 58 +++ benchmark/tpcds/reference_queries/q81.sql | 77 ++++ benchmark/tpcds/reference_queries/q83.sql | 93 ++++ benchmark/tpcds/reference_queries/q85.sql | 68 +++ benchmark/tpcds/reference_queries/q88.sql | 25 + benchmark/tpcds/reference_queries/q90.sql | 30 ++ benchmark/tpcds/reference_queries/q91.sql | 44 ++ benchmark/tpcds/reference_queries/q92.sql | 14 + benchmark/tpcds/reference_queries/q93.sql | 12 + benchmark/tpcds/reference_queries/q94.sql | 10 + benchmark/tpcds/reference_queries/q95.sql | 10 + benchmark/tpcds/reference_queries/q96.sql | 24 + benchmark/tpcds/reference_queries/q99.sql | 42 ++ benchmark/tpcds/run.py | 67 ++- docs/benchmark/microbenchmarks.md | 18 + docs/benchmark/tpcds.md | 62 ++- 139 files changed, 7592 insertions(+), 57 deletions(-) create mode 100644 benchmark/configs/utility/as_tpcds_sf30.json create mode 100644 benchmark/tpcds/as_queries/q01.sql create mode 100644 benchmark/tpcds/as_queries/q03.sql create mode 100644 benchmark/tpcds/as_queries/q04.sql create mode 100644 benchmark/tpcds/as_queries/q06.sql create mode 100644 benchmark/tpcds/as_queries/q07.sql create mode 100644 benchmark/tpcds/as_queries/q09.sql create mode 100644 benchmark/tpcds/as_queries/q10.sql create mode 100644 benchmark/tpcds/as_queries/q11.sql create mode 100644 benchmark/tpcds/as_queries/q13.sql create mode 100644 benchmark/tpcds/as_queries/q15.sql create mode 100644 benchmark/tpcds/as_queries/q16.sql create mode 100644 benchmark/tpcds/as_queries/q17.sql create mode 100644 benchmark/tpcds/as_queries/q18.sql create mode 100644 benchmark/tpcds/as_queries/q19.sql create mode 100644 benchmark/tpcds/as_queries/q23.sql create mode 100644 benchmark/tpcds/as_queries/q24.sql create mode 100644 benchmark/tpcds/as_queries/q25.sql create mode 100644 benchmark/tpcds/as_queries/q26.sql create mode 100644 benchmark/tpcds/as_queries/q27.sql create mode 100644 benchmark/tpcds/as_queries/q28.sql create mode 100644 benchmark/tpcds/as_queries/q29.sql create mode 100644 benchmark/tpcds/as_queries/q30.sql create mode 100644 benchmark/tpcds/as_queries/q31.sql create mode 100644 benchmark/tpcds/as_queries/q32.sql create mode 100644 benchmark/tpcds/as_queries/q33.sql create mode 100644 benchmark/tpcds/as_queries/q34.sql create mode 100644 benchmark/tpcds/as_queries/q35.sql create mode 100644 benchmark/tpcds/as_queries/q40.sql create mode 100644 benchmark/tpcds/as_queries/q42.sql create mode 100644 benchmark/tpcds/as_queries/q43.sql create mode 100644 benchmark/tpcds/as_queries/q45.sql create mode 100644 benchmark/tpcds/as_queries/q46.sql create mode 100644 benchmark/tpcds/as_queries/q48.sql create mode 100644 benchmark/tpcds/as_queries/q50.sql create mode 100644 benchmark/tpcds/as_queries/q52.sql create mode 100644 benchmark/tpcds/as_queries/q55.sql create mode 100644 benchmark/tpcds/as_queries/q56.sql create mode 100644 benchmark/tpcds/as_queries/q58.sql create mode 100644 benchmark/tpcds/as_queries/q59.sql create mode 100644 benchmark/tpcds/as_queries/q60.sql create mode 100644 benchmark/tpcds/as_queries/q61.sql create mode 100644 benchmark/tpcds/as_queries/q62.sql create mode 100644 benchmark/tpcds/as_queries/q64.sql create mode 100644 benchmark/tpcds/as_queries/q65.sql create mode 100644 benchmark/tpcds/as_queries/q66.sql create mode 100644 benchmark/tpcds/as_queries/q68.sql create mode 100644 benchmark/tpcds/as_queries/q69.sql create mode 100644 benchmark/tpcds/as_queries/q72.sql create mode 100644 benchmark/tpcds/as_queries/q73.sql create mode 100644 benchmark/tpcds/as_queries/q74.sql create mode 100644 benchmark/tpcds/as_queries/q77.sql create mode 100644 benchmark/tpcds/as_queries/q78.sql create mode 100644 benchmark/tpcds/as_queries/q79.sql create mode 100644 benchmark/tpcds/as_queries/q80.sql create mode 100644 benchmark/tpcds/as_queries/q81.sql create mode 100644 benchmark/tpcds/as_queries/q83.sql create mode 100644 benchmark/tpcds/as_queries/q85.sql create mode 100644 benchmark/tpcds/as_queries/q88.sql create mode 100644 benchmark/tpcds/as_queries/q90.sql create mode 100644 benchmark/tpcds/as_queries/q91.sql create mode 100644 benchmark/tpcds/as_queries/q92.sql create mode 100644 benchmark/tpcds/as_queries/q93.sql create mode 100644 benchmark/tpcds/as_queries/q94.sql create mode 100644 benchmark/tpcds/as_queries/q95.sql create mode 100644 benchmark/tpcds/as_queries/q96.sql create mode 100644 benchmark/tpcds/as_queries/q99.sql create mode 100644 benchmark/tpcds/q17_fixture.sql create mode 100644 benchmark/tpcds/reference_queries/q01.sql create mode 100644 benchmark/tpcds/reference_queries/q03.sql create mode 100644 benchmark/tpcds/reference_queries/q04.sql create mode 100644 benchmark/tpcds/reference_queries/q06.sql create mode 100644 benchmark/tpcds/reference_queries/q07.sql create mode 100644 benchmark/tpcds/reference_queries/q09.sql create mode 100644 benchmark/tpcds/reference_queries/q10.sql create mode 100644 benchmark/tpcds/reference_queries/q11.sql create mode 100644 benchmark/tpcds/reference_queries/q13.sql create mode 100644 benchmark/tpcds/reference_queries/q15.sql create mode 100644 benchmark/tpcds/reference_queries/q16.sql create mode 100644 benchmark/tpcds/reference_queries/q17.sql create mode 100644 benchmark/tpcds/reference_queries/q18.sql create mode 100644 benchmark/tpcds/reference_queries/q19.sql create mode 100644 benchmark/tpcds/reference_queries/q23.sql create mode 100644 benchmark/tpcds/reference_queries/q24.sql create mode 100644 benchmark/tpcds/reference_queries/q25.sql create mode 100644 benchmark/tpcds/reference_queries/q26.sql create mode 100644 benchmark/tpcds/reference_queries/q27.sql create mode 100644 benchmark/tpcds/reference_queries/q28.sql create mode 100644 benchmark/tpcds/reference_queries/q29.sql create mode 100644 benchmark/tpcds/reference_queries/q30.sql create mode 100644 benchmark/tpcds/reference_queries/q31.sql create mode 100644 benchmark/tpcds/reference_queries/q32.sql create mode 100644 benchmark/tpcds/reference_queries/q33.sql create mode 100644 benchmark/tpcds/reference_queries/q34.sql create mode 100644 benchmark/tpcds/reference_queries/q35.sql create mode 100644 benchmark/tpcds/reference_queries/q40.sql create mode 100644 benchmark/tpcds/reference_queries/q42.sql create mode 100644 benchmark/tpcds/reference_queries/q43.sql create mode 100644 benchmark/tpcds/reference_queries/q45.sql create mode 100644 benchmark/tpcds/reference_queries/q46.sql create mode 100644 benchmark/tpcds/reference_queries/q48.sql create mode 100644 benchmark/tpcds/reference_queries/q50.sql create mode 100644 benchmark/tpcds/reference_queries/q52.sql create mode 100644 benchmark/tpcds/reference_queries/q55.sql create mode 100644 benchmark/tpcds/reference_queries/q56.sql create mode 100644 benchmark/tpcds/reference_queries/q58.sql create mode 100644 benchmark/tpcds/reference_queries/q59.sql create mode 100644 benchmark/tpcds/reference_queries/q60.sql create mode 100644 benchmark/tpcds/reference_queries/q61.sql create mode 100644 benchmark/tpcds/reference_queries/q62.sql create mode 100644 benchmark/tpcds/reference_queries/q64.sql create mode 100644 benchmark/tpcds/reference_queries/q65.sql create mode 100644 benchmark/tpcds/reference_queries/q66.sql create mode 100644 benchmark/tpcds/reference_queries/q68.sql create mode 100644 benchmark/tpcds/reference_queries/q69.sql create mode 100644 benchmark/tpcds/reference_queries/q72.sql create mode 100644 benchmark/tpcds/reference_queries/q73.sql create mode 100644 benchmark/tpcds/reference_queries/q74.sql create mode 100644 benchmark/tpcds/reference_queries/q77.sql create mode 100644 benchmark/tpcds/reference_queries/q78.sql create mode 100644 benchmark/tpcds/reference_queries/q79.sql create mode 100644 benchmark/tpcds/reference_queries/q80.sql create mode 100644 benchmark/tpcds/reference_queries/q81.sql create mode 100644 benchmark/tpcds/reference_queries/q83.sql create mode 100644 benchmark/tpcds/reference_queries/q85.sql create mode 100644 benchmark/tpcds/reference_queries/q88.sql create mode 100644 benchmark/tpcds/reference_queries/q90.sql create mode 100644 benchmark/tpcds/reference_queries/q91.sql create mode 100644 benchmark/tpcds/reference_queries/q92.sql create mode 100644 benchmark/tpcds/reference_queries/q93.sql create mode 100644 benchmark/tpcds/reference_queries/q94.sql create mode 100644 benchmark/tpcds/reference_queries/q95.sql create mode 100644 benchmark/tpcds/reference_queries/q96.sql create mode 100644 benchmark/tpcds/reference_queries/q99.sql diff --git a/benchmark/configs/utility/as_tpcds_sf30.json b/benchmark/configs/utility/as_tpcds_sf30.json new file mode 100644 index 00000000..ba422483 --- /dev/null +++ b/benchmark/configs/utility/as_tpcds_sf30.json @@ -0,0 +1,12 @@ +{ + "sf": 30, + "db": "benchmark/results/tpcds_sf30/data.db", + "queries_dir": "benchmark/results/tpcds_sf30/queries", + "out_dir": "benchmark/results/tpcds_sf30", + "schema": "benchmark/tpcds/schema.sql", + "threads": 16, + "memory_limit": "30GB", + "repetitions": 5, + "timeout_seconds": 3600, + "extension_directory": "benchmark/results/tpcds_extensions" +} diff --git a/benchmark/microbench/approx_sum_stability.sql b/benchmark/microbench/approx_sum_stability.sql index 2ce1c88b..c4caa6a6 100644 --- a/benchmark/microbench/approx_sum_stability.sql +++ b/benchmark/microbench/approx_sum_stability.sql @@ -34,18 +34,18 @@ WITH bit_positions AS (SELECT unnest(range(64)) as bit_pos), FROM accuracy_test, bit_positions GROUP BY dist, bit_pos), exact_lists AS (SELECT dist, list(exact_sum ORDER BY bit_pos) as exact_counters FROM exact_sums GROUP BY dist), - approx_sums AS (SELECT dist, as_sum(priv_hash(hash(rowid)), val) as approx_counters + approx_sums AS (SELECT dist, list_transform(as_sum(priv_hash(hash(rowid)), val), lambda x: x / 2.0) as approx_counters FROM accuracy_test GROUP BY dist), per_counter_stats AS ( SELECT e.dist, e.exact_counters, a.approx_counters, - [POWER(e.exact_counters[x+1] - a.approx_counters[x+1] / 2, 2) FOR x IN range(64)] as sq_diffs, + [POWER(e.exact_counters[x+1] - a.approx_counters[x+1], 2) FOR x IN range(64)] as sq_diffs, [CASE WHEN e.exact_counters[x+1] = 0 THEN NULL - ELSE 100.0 * (a.approx_counters[x+1] / 2 - e.exact_counters[x+1]) / e.exact_counters[x+1] + ELSE 100.0 * (a.approx_counters[x+1] - e.exact_counters[x+1]) / e.exact_counters[x+1] END FOR x IN range(64)] as pct_diffs FROM exact_lists e JOIN approx_sums a ON e.dist = a.dist) SELECT dist, cast(sqrt(list_avg(sq_diffs)) as bigint) as rmse, - ROUND(list_avg(list_transform(pct_diffs, x -> abs(x))), 4) as pct_err, + ROUND(list_avg(list_transform(pct_diffs, lambda x: abs(x))), 4) as pct_err, ROUND(POWER(rmse, 2) / NULLIF(list_var_samp(approx_counters), 0), 4) as z_squared, cast(list_var_samp(exact_counters) as float) as var_exact, cast(list_var_samp(approx_counters) as float) as var_approx, diff --git a/benchmark/tpcds/as_queries/q01.sql b/benchmark/tpcds/as_queries/q01.sql new file mode 100644 index 00000000..1621b57e --- /dev/null +++ b/benchmark/tpcds/as_queries/q01.sql @@ -0,0 +1,23 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- The CTE exports customer totals unchanged; its correlated AVG is stochastic across customers. +WITH customer_total_return AS (SELECT sr_customer_sk AS ctr_customer_sk, + sr_store_sk AS ctr_store_sk, + sum(sr_return_amt) AS ctr_total_return + FROM store_returns, + date_dim + WHERE sr_returned_date_sk = d_date_sk + AND d_year = 2000 + GROUP BY sr_customer_sk, + sr_store_sk) +SELECT c_customer_id +FROM customer_total_return ctr1, + store, + customer +WHERE priv_filter_gt(CAST(CAST(ctr1.ctr_total_return AS DOUBLE) * 0.8333333333333334 AS FLOAT), (SELECT priv_div(as_sum(priv_hash(hash(ctr2.ctr_customer_sk)), ctr_total_return), as_count(priv_hash(hash(ctr2.ctr_customer_sk)), ctr_total_return)) + FROM customer_total_return ctr2 + WHERE ctr1.ctr_store_sk = ctr2.ctr_store_sk)) + AND s_store_sk = ctr1.ctr_store_sk + AND s_state = 'TN' + AND ctr1.ctr_customer_sk = c_customer_sk +ORDER BY c_customer_id +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q03.sql b/benchmark/tpcds/as_queries/q03.sql new file mode 100644 index 00000000..156d7171 --- /dev/null +++ b/benchmark/tpcds/as_queries/q03.sql @@ -0,0 +1,14 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH asa_states AS (SELECT dt.d_year AS d_year, item.i_brand_id AS brand_id, item.i_brand AS brand, as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_sales_price AS DOUBLE)) AS sum_agg FROM date_dim dt, + store_sales, + item +WHERE dt.d_date_sk = store_sales.ss_sold_date_sk + AND store_sales.ss_item_sk = item.i_item_sk + AND item.i_manufact_id = 128 + AND dt.d_moy=11 +GROUP BY dt.d_year, + item.i_brand, + item.i_brand_id +), +asa_ranked AS (SELECT * FROM asa_states ORDER BY d_year, priv_mean(sum_agg) DESC, brand_id LIMIT 100) +SELECT d_year, brand_id, brand, CAST(as_noised(sum_agg) AS DECIMAL(38,2)) AS sum_agg FROM asa_ranked ORDER BY d_year, sum_agg DESC, brand_id; diff --git a/benchmark/tpcds/as_queries/q04.sql b/benchmark/tpcds/as_queries/q04.sql new file mode 100644 index 00000000..b499a2b7 --- /dev/null +++ b/benchmark/tpcds/as_queries/q04.sql @@ -0,0 +1,120 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Keep year_total scalar inside its CTE; outer customer/year joins retain ordinary PAC scalar semantics. +WITH year_total AS (SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + as_noised_sum(priv_hash(hash(c_customer_sk)), ((ss_ext_list_price-ss_ext_wholesale_cost-ss_ext_discount_amt)+ss_ext_sales_price)/2) year_total, + 's' sale_type + FROM customer, + store_sales, + date_dim + WHERE c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year + UNION ALL SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + as_noised_sum(priv_hash(hash(c_customer_sk)), (((cs_ext_list_price-cs_ext_wholesale_cost-cs_ext_discount_amt)+cs_ext_sales_price)/2)) year_total, + 'c' sale_type + FROM customer, + catalog_sales, + date_dim + WHERE c_customer_sk = cs_bill_customer_sk + AND cs_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year + UNION ALL SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + as_noised_sum(priv_hash(hash(c_customer_sk)), (((ws_ext_list_price-ws_ext_wholesale_cost-ws_ext_discount_amt)+ws_ext_sales_price)/2)) year_total, + 'w' sale_type + FROM customer, + web_sales, + date_dim + WHERE c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year) +SELECT t_s_secyear.customer_id, + t_s_secyear.customer_first_name, + t_s_secyear.customer_last_name, + t_s_secyear.customer_preferred_cust_flag +FROM year_total t_s_firstyear, + year_total t_s_secyear, + year_total t_c_firstyear, + year_total t_c_secyear, + year_total t_w_firstyear, + year_total t_w_secyear +WHERE t_s_secyear.customer_id = t_s_firstyear.customer_id + AND t_s_firstyear.customer_id = t_c_secyear.customer_id + AND t_s_firstyear.customer_id = t_c_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_secyear.customer_id + AND t_s_firstyear.sale_type = 's' + AND t_c_firstyear.sale_type = 'c' + AND t_w_firstyear.sale_type = 'w' + AND t_s_secyear.sale_type = 's' + AND t_c_secyear.sale_type = 'c' + AND t_w_secyear.sale_type = 'w' + AND t_s_firstyear.dyear = 2001 + AND t_s_secyear.dyear = 2001+1 + AND t_c_firstyear.dyear = 2001 + AND t_c_secyear.dyear = 2001+1 + AND t_w_firstyear.dyear = 2001 + AND t_w_secyear.dyear = 2001+1 + AND t_s_firstyear.year_total > 0 + AND t_c_firstyear.year_total > 0 + AND t_w_firstyear.year_total > 0 + AND CASE + WHEN t_c_firstyear.year_total > 0 THEN t_c_secyear.year_total / t_c_firstyear.year_total + ELSE NULL + END > CASE + WHEN t_s_firstyear.year_total > 0 THEN t_s_secyear.year_total / t_s_firstyear.year_total + ELSE NULL + END + AND CASE + WHEN t_c_firstyear.year_total > 0 THEN t_c_secyear.year_total / t_c_firstyear.year_total + ELSE NULL + END > CASE + WHEN t_w_firstyear.year_total > 0 THEN t_w_secyear.year_total / t_w_firstyear.year_total + ELSE NULL + END +ORDER BY t_s_secyear.customer_id NULLS FIRST, + t_s_secyear.customer_first_name NULLS FIRST, + t_s_secyear.customer_last_name NULLS FIRST, + t_s_secyear.customer_preferred_cust_flag NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q06.sql b/benchmark/tpcds/as_queries/q06.sql new file mode 100644 index 00000000..849ef217 --- /dev/null +++ b/benchmark/tpcds/as_queries/q06.sql @@ -0,0 +1,26 @@ +-- PAC COUNT with scalar HAVING, as in the compiled plan. +SELECT a.ca_state state, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt +FROM customer_address a , + customer c , + store_sales s , + date_dim d , + item i +WHERE a.ca_address_sk = c.c_current_addr_sk + AND c.c_customer_sk = s.ss_customer_sk + AND s.ss_sold_date_sk = d.d_date_sk + AND s.ss_item_sk = i.i_item_sk + AND d.d_month_seq = + (SELECT DISTINCT (d_month_seq) + FROM date_dim + WHERE d_year = 2001 + AND d_moy = 1 ) + AND i.i_current_price > 1.2 * + (SELECT avg(j.i_current_price) + FROM item j + WHERE j.i_category = i.i_category) +GROUP BY a.ca_state +HAVING as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) >= 10 +ORDER BY cnt NULLS FIRST, + a.ca_state NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q07.sql b/benchmark/tpcds/as_queries/q07.sql new file mode 100644 index 00000000..959198df --- /dev/null +++ b/benchmark/tpcds/as_queries/q07.sql @@ -0,0 +1,24 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT i_item_id, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE)) agg1, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_list_price) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_list_price) AS DOUBLE)) agg2, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_coupon_amt) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_coupon_amt) AS DOUBLE)) agg3, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_sales_price) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_sales_price) AS DOUBLE)) agg4 +FROM store_sales, + customer_demographics, + date_dim, + item, + promotion +WHERE ss_sold_date_sk = d_date_sk + AND ss_item_sk = i_item_sk + AND ss_cdemo_sk = cd_demo_sk + AND ss_promo_sk = p_promo_sk + AND cd_gender = 'M' + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND (p_channel_email = 'N' + OR p_channel_event = 'N') + AND d_year = 2000 +GROUP BY i_item_id +ORDER BY i_item_id +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q09.sql b/benchmark/tpcds/as_queries/q09.sql new file mode 100644 index 00000000..352ff3cb --- /dev/null +++ b/benchmark/tpcds/as_queries/q09.sql @@ -0,0 +1,8 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Evaluate CASE lane-wise over counter lists and finalize once; all fifteen scalar subqueries remain. +SELECT CAST(as_noised(list_transform(list_zip((SELECT as_count(priv_hash(hash(ss_customer_sk)),1::BIGINT) FROM store_sales WHERE ss_quantity BETWEEN 1 AND 20), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_discount_amt AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_ext_discount_amt)) FROM store_sales WHERE ss_quantity BETWEEN 1 AND 20), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_net_paid AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_net_paid)) FROM store_sales WHERE ss_quantity BETWEEN 1 AND 20)), lambda x: CASE WHEN x[1] > 74129 THEN x[2] ELSE x[3] END)) AS DOUBLE) AS bucket1, +CAST(as_noised(list_transform(list_zip((SELECT as_count(priv_hash(hash(ss_customer_sk)),1::BIGINT) FROM store_sales WHERE ss_quantity BETWEEN 21 AND 40), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_discount_amt AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_ext_discount_amt)) FROM store_sales WHERE ss_quantity BETWEEN 21 AND 40), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_net_paid AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_net_paid)) FROM store_sales WHERE ss_quantity BETWEEN 21 AND 40)), lambda x: CASE WHEN x[1] > 122840 THEN x[2] ELSE x[3] END)) AS DOUBLE) AS bucket2, +CAST(as_noised(list_transform(list_zip((SELECT as_count(priv_hash(hash(ss_customer_sk)),1::BIGINT) FROM store_sales WHERE ss_quantity BETWEEN 41 AND 60), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_discount_amt AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_ext_discount_amt)) FROM store_sales WHERE ss_quantity BETWEEN 41 AND 60), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_net_paid AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_net_paid)) FROM store_sales WHERE ss_quantity BETWEEN 41 AND 60)), lambda x: CASE WHEN x[1] > 56580 THEN x[2] ELSE x[3] END)) AS DOUBLE) AS bucket3, +CAST(as_noised(list_transform(list_zip((SELECT as_count(priv_hash(hash(ss_customer_sk)),1::BIGINT) FROM store_sales WHERE ss_quantity BETWEEN 61 AND 80), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_discount_amt AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_ext_discount_amt)) FROM store_sales WHERE ss_quantity BETWEEN 61 AND 80), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_net_paid AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_net_paid)) FROM store_sales WHERE ss_quantity BETWEEN 61 AND 80)), lambda x: CASE WHEN x[1] > 10097 THEN x[2] ELSE x[3] END)) AS DOUBLE) AS bucket4, +CAST(as_noised(list_transform(list_zip((SELECT as_count(priv_hash(hash(ss_customer_sk)),1::BIGINT) FROM store_sales WHERE ss_quantity BETWEEN 81 AND 100), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_discount_amt AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_ext_discount_amt)) FROM store_sales WHERE ss_quantity BETWEEN 81 AND 100), (SELECT priv_div(as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_net_paid AS DOUBLE)),as_count(priv_hash(hash(ss_customer_sk)),ss_net_paid)) FROM store_sales WHERE ss_quantity BETWEEN 81 AND 100)), lambda x: CASE WHEN x[1] > 165306 THEN x[2] ELSE x[3] END)) AS DOUBLE) AS bucket5 +FROM reason WHERE r_reason_sk=1; diff --git a/benchmark/tpcds/as_queries/q10.sql b/benchmark/tpcds/as_queries/q10.sql new file mode 100644 index 00000000..df71aa6a --- /dev/null +++ b/benchmark/tpcds/as_queries/q10.sql @@ -0,0 +1,66 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT cd_gender, + cd_marital_status, + cd_education_status, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt1, + cd_purchase_estimate, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt2, + cd_credit_rating, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt3, + cd_dep_count, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt4, + cd_dep_employed_count, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt5, + cd_dep_college_count, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt6 +FROM customer c, + customer_address ca, + customer_demographics +WHERE c.c_current_addr_sk = ca.ca_address_sk + AND ca_county IN ('Rush County', + 'Toole County', + 'Jefferson County', + 'Dona Ana County', + 'La Porte County') + AND cd_demo_sk = c.c_current_cdemo_sk + AND EXISTS + (SELECT * + FROM store_sales, + date_dim + WHERE c.c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_moy BETWEEN 1 AND 1+3) + AND (EXISTS + (SELECT * + FROM web_sales, + date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_moy BETWEEN 1 AND 1+3) + OR EXISTS + (SELECT * + FROM catalog_sales, + date_dim + WHERE c.c_customer_sk = cs_ship_customer_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_moy BETWEEN 1 AND 1+3)) +GROUP BY cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating, + cd_dep_count, + cd_dep_employed_count, + cd_dep_college_count +ORDER BY cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating, + cd_dep_count, + cd_dep_employed_count, + cd_dep_college_count +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q11.sql b/benchmark/tpcds/as_queries/q11.sql new file mode 100644 index 00000000..c7067279 --- /dev/null +++ b/benchmark/tpcds/as_queries/q11.sql @@ -0,0 +1,80 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH year_total AS (SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_ext_list_price-ss_ext_discount_amt) year_total, + 's' sale_type + FROM customer, + store_sales, + date_dim + WHERE c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year + UNION ALL SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + as_noised_sum(priv_hash(hash(c_customer_sk)), ws_ext_list_price-ws_ext_discount_amt) year_total, + 'w' sale_type + FROM customer, + web_sales, + date_dim + WHERE c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year) +SELECT t_s_secyear.customer_id, + t_s_secyear.customer_first_name, + t_s_secyear.customer_last_name, + t_s_secyear.customer_preferred_cust_flag +FROM year_total t_s_firstyear, + year_total t_s_secyear, + year_total t_w_firstyear, + year_total t_w_secyear +WHERE t_s_secyear.customer_id = t_s_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_secyear.customer_id + AND t_s_firstyear.customer_id = t_w_firstyear.customer_id + AND t_s_firstyear.sale_type = 's' + AND t_w_firstyear.sale_type = 'w' + AND t_s_secyear.sale_type = 's' + AND t_w_secyear.sale_type = 'w' + AND t_s_firstyear.dyear = 2001 + AND t_s_secyear.dyear = 2001+1 + AND t_w_firstyear.dyear = 2001 + AND t_w_secyear.dyear = 2001+1 + AND t_s_firstyear.year_total > 0 + AND t_w_firstyear.year_total > 0 + AND CASE + WHEN t_w_firstyear.year_total > 0 THEN (t_w_secyear.year_total*1.0000) / t_w_firstyear.year_total + ELSE 0.0 + END > CASE + WHEN t_s_firstyear.year_total > 0 THEN (t_s_secyear.year_total*1.0000) / t_s_firstyear.year_total + ELSE 0.0 + END +ORDER BY t_s_secyear.customer_id NULLS FIRST, + t_s_secyear.customer_first_name NULLS FIRST, + t_s_secyear.customer_last_name NULLS FIRST, + t_s_secyear.customer_preferred_cust_flag NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q13.sql b/benchmark/tpcds/as_queries/q13.sql new file mode 100644 index 00000000..d666e013 --- /dev/null +++ b/benchmark/tpcds/as_queries/q13.sql @@ -0,0 +1,43 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. + +SELECT (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE)) avg1, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS DOUBLE)) avg2, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_wholesale_cost) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_ext_wholesale_cost) AS DOUBLE)) avg3, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_wholesale_cost) +FROM store_sales , + store , + customer_demographics , + household_demographics , + customer_address , + date_dim +WHERE s_store_sk = ss_store_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2001 and((ss_hdemo_sk=hd_demo_sk + AND cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'M' + AND cd_education_status = 'Advanced Degree' + AND ss_sales_price BETWEEN 100.00 AND 150.00 + AND hd_dep_count = 3) + OR (ss_hdemo_sk=hd_demo_sk + AND cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND ss_sales_price BETWEEN 50.00 AND 100.00 + AND hd_dep_count = 1 ) + OR (ss_hdemo_sk=hd_demo_sk + AND cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'W' + AND cd_education_status = '2 yr Degree' + AND ss_sales_price BETWEEN 150.00 AND 200.00 + AND hd_dep_count = 1)) and((ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('TX', 'OH', 'TX') + AND ss_net_profit BETWEEN 100 AND 200) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('OR', 'NM', 'KY') + AND ss_net_profit BETWEEN 150 AND 300) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('VA', 'TX', 'MS') + AND ss_net_profit BETWEEN 50 AND 250)) ; diff --git a/benchmark/tpcds/as_queries/q15.sql b/benchmark/tpcds/as_queries/q15.sql new file mode 100644 index 00000000..7d7198f6 --- /dev/null +++ b/benchmark/tpcds/as_queries/q15.sql @@ -0,0 +1,28 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT ca_zip, + as_noised_sum(priv_hash(hash(c_customer_sk)), cs_sales_price) +FROM catalog_sales, + customer, + customer_address, + date_dim +WHERE cs_bill_customer_sk = c_customer_sk + AND c_current_addr_sk = ca_address_sk + AND (SUBSTRING(ca_zip, 1, 5) IN ('85669', + '86197', + '88274', + '83405', + '86475', + '85392', + '85460', + '80348', + '81792') + OR ca_state IN ('CA', + 'WA', + 'GA') + OR cs_sales_price > 500) + AND cs_sold_date_sk = d_date_sk + AND d_qoy = 2 + AND d_year = 2001 +GROUP BY ca_zip +ORDER BY ca_zip NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q16.sql b/benchmark/tpcds/as_queries/q16.sql new file mode 100644 index 00000000..757dcb1f --- /dev/null +++ b/benchmark/tpcds/as_queries/q16.sql @@ -0,0 +1,24 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- COUNT(DISTINCT) unions masks per order before counting; SUMs retain their own source scan. +WITH asa_input AS NOT MATERIALIZED (SELECT cs_order_number, cs_ext_ship_cost, cs_net_profit, priv_hash(hash(cs1.cs_bill_customer_sk)) AS membership FROM catalog_sales cs1, + date_dim, + customer_address, + call_center +WHERE d_date BETWEEN '2002-02-01' AND cast('2002-04-02' AS date) + AND cs1.cs_ship_date_sk = d_date_sk + AND cs1.cs_ship_addr_sk = ca_address_sk + AND ca_state = 'GA' + AND cs1.cs_call_center_sk = cc_call_center_sk + AND cc_county = 'Williamson County' + AND EXISTS + (SELECT * + FROM catalog_sales cs2 + WHERE cs1.cs_order_number = cs2.cs_order_number + AND cs1.cs_warehouse_sk <> cs2.cs_warehouse_sk) + AND NOT EXISTS + (SELECT * + FROM catalog_returns cr1 + WHERE cs1.cs_order_number = cr1.cr_order_number) +), +asa_distinct AS NOT MATERIALIZED (SELECT cs_order_number, bit_or(membership) FILTER (WHERE cs_order_number IS NOT NULL) AS membership FROM asa_input GROUP BY cs_order_number) +SELECT d.n AS "order count", s.shipping AS "total shipping cost", s.profit AS "total net profit" FROM (SELECT as_noised_count(membership, 1::BIGINT) AS n FROM asa_distinct) d CROSS JOIN (SELECT as_noised_sum(membership, cs_ext_ship_cost) AS shipping, as_noised_sum(membership, cs_net_profit) AS profit FROM asa_input) s ORDER BY "order count" LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q17.sql b/benchmark/tpcds/as_queries/q17.sql new file mode 100644 index 00000000..ea247a6d --- /dev/null +++ b/benchmark/tpcds/as_queries/q17.sql @@ -0,0 +1,48 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT i_item_id, + i_item_desc, + s_state, + as_noised_count(priv_hash(hash(ss_customer_sk)), ss_quantity) AS store_sales_quantitycount, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE)) AS store_sales_quantityave, + as_noised_stddev_samp(priv_hash(hash(ss_customer_sk)), ss_quantity) AS store_sales_quantitystdev, + as_noised_stddev_samp(priv_hash(hash(ss_customer_sk)), ss_quantity)/(CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), ss_quantity) AS DOUBLE)) AS store_sales_quantitycov, + as_noised_count(priv_hash(hash(ss_customer_sk)), sr_return_quantity) AS store_returns_quantitycount, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), sr_return_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), sr_return_quantity) AS DOUBLE)) AS store_returns_quantityave, + as_noised_stddev_samp(priv_hash(hash(ss_customer_sk)), sr_return_quantity) AS store_returns_quantitystdev, + as_noised_stddev_samp(priv_hash(hash(ss_customer_sk)), sr_return_quantity)/(CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), sr_return_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), sr_return_quantity) AS DOUBLE)) AS store_returns_quantitycov, + as_noised_count(priv_hash(hash(ss_customer_sk)), cs_quantity) AS catalog_sales_quantitycount, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), cs_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), cs_quantity) AS DOUBLE)) AS catalog_sales_quantityave, + as_noised_stddev_samp(priv_hash(hash(ss_customer_sk)), cs_quantity) AS catalog_sales_quantitystdev, + as_noised_stddev_samp(priv_hash(hash(ss_customer_sk)), cs_quantity)/(CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), cs_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), cs_quantity) AS DOUBLE)) AS catalog_sales_quantitycov +FROM store_sales, + store_returns, + catalog_sales, + date_dim d1, + date_dim d2, + date_dim d3, + store, + item +WHERE d1.d_quarter_name = '2001Q1' + AND d1.d_date_sk = ss_sold_date_sk + AND i_item_sk = ss_item_sk + AND s_store_sk = ss_store_sk + AND ss_customer_sk = sr_customer_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND sr_returned_date_sk = d2.d_date_sk + AND d2.d_quarter_name IN ('2001Q1', + '2001Q2', + '2001Q3') + AND sr_customer_sk = cs_bill_customer_sk + AND sr_item_sk = cs_item_sk + AND cs_sold_date_sk = d3.d_date_sk + AND d3.d_quarter_name IN ('2001Q1', + '2001Q2', + '2001Q3') +GROUP BY i_item_id, + i_item_desc, + s_state +ORDER BY i_item_id NULLS FIRST, + i_item_desc NULLS FIRST, + s_state NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q18.sql b/benchmark/tpcds/as_queries/q18.sql new file mode 100644 index 00000000..c04011b9 --- /dev/null +++ b/benchmark/tpcds/as_queries/q18.sql @@ -0,0 +1,50 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT i_item_id, + ca_country, + ca_state, + ca_county, + (CAST(as_noised_sum(priv_hash(hash(c_customer_sk)), cast(cs_quantity AS decimal(12, 2))) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c_customer_sk)), cast(cs_quantity AS decimal(12, 2))) AS DOUBLE)) agg1, + (CAST(as_noised_sum(priv_hash(hash(c_customer_sk)), cast(cs_list_price AS decimal(12, 2))) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c_customer_sk)), cast(cs_list_price AS decimal(12, 2))) AS DOUBLE)) agg2, + (CAST(as_noised_sum(priv_hash(hash(c_customer_sk)), cast(cs_coupon_amt AS decimal(12, 2))) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c_customer_sk)), cast(cs_coupon_amt AS decimal(12, 2))) AS DOUBLE)) agg3, + (CAST(as_noised_sum(priv_hash(hash(c_customer_sk)), cast(cs_sales_price AS decimal(12, 2))) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c_customer_sk)), cast(cs_sales_price AS decimal(12, 2))) AS DOUBLE)) agg4, + (CAST(as_noised_sum(priv_hash(hash(c_customer_sk)), cast(cs_net_profit AS decimal(12, 2))) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c_customer_sk)), cast(cs_net_profit AS decimal(12, 2))) AS DOUBLE)) agg5, + (CAST(as_noised_sum(priv_hash(hash(c_customer_sk)), cast(c_birth_year AS decimal(12, 2))) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c_customer_sk)), cast(c_birth_year AS decimal(12, 2))) AS DOUBLE)) agg6, + (CAST(as_noised_sum(priv_hash(hash(c_customer_sk)), cast(cd1.cd_dep_count AS decimal(12, 2))) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c_customer_sk)), cast(cd1.cd_dep_count AS decimal(12, 2))) AS DOUBLE)) agg7 +FROM catalog_sales, + customer_demographics cd1, + customer_demographics cd2, + customer, + customer_address, + date_dim, + item +WHERE cs_sold_date_sk = d_date_sk + AND cs_item_sk = i_item_sk + AND cs_bill_cdemo_sk = cd1.cd_demo_sk + AND cs_bill_customer_sk = c_customer_sk + AND cd1.cd_gender = 'F' + AND cd1.cd_education_status = 'Unknown' + AND c_current_cdemo_sk = cd2.cd_demo_sk + AND c_current_addr_sk = ca_address_sk + AND c_birth_month IN (1, + 6, + 8, + 9, + 12, + 2) + AND d_year = 1998 + AND ca_state IN ('MS', + 'IN', + 'ND', + 'OK', + 'NM', + 'VA', + 'MS') +GROUP BY ROLLUP (i_item_id, + ca_country, + ca_state, + ca_county) +ORDER BY ca_country NULLS FIRST, + ca_state NULLS FIRST, + ca_county NULLS FIRST, + i_item_id NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q19.sql b/benchmark/tpcds/as_queries/q19.sql new file mode 100644 index 00000000..1488e632 --- /dev/null +++ b/benchmark/tpcds/as_queries/q19.sql @@ -0,0 +1,31 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT i_brand_id brand_id, + i_brand brand, + i_manufact_id, + i_manufact, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_ext_sales_price) ext_price +FROM date_dim, + store_sales, + item, + customer, + customer_address, + store +WHERE d_date_sk = ss_sold_date_sk + AND ss_item_sk = i_item_sk + AND i_manager_id=8 + AND d_moy=11 + AND d_year=1998 + AND ss_customer_sk = c_customer_sk + AND c_current_addr_sk = ca_address_sk + AND SUBSTRING(ca_zip, 1, 5) <> SUBSTRING(s_zip, 1, 5) + AND ss_store_sk = s_store_sk +GROUP BY i_brand, + i_brand_id, + i_manufact_id, + i_manufact +ORDER BY ext_price DESC, + i_brand, + i_brand_id, + i_manufact_id, + i_manufact +LIMIT 100 ; diff --git a/benchmark/tpcds/as_queries/q23.sql b/benchmark/tpcds/as_queries/q23.sql new file mode 100644 index 00000000..ffebd1d1 --- /dev/null +++ b/benchmark/tpcds/as_queries/q23.sql @@ -0,0 +1,83 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Per-customer inner totals remain ordinary; the aggregate across those totals is stochastic. +WITH frequent_ss_items AS (SELECT itemdesc, + i_item_sk item_sk, + d_date solddate, + as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) cnt + FROM store_sales, + date_dim, + (SELECT SUBSTRING(i_item_desc, 1, 30) itemdesc, + * + FROM item) sq1 + WHERE ss_sold_date_sk = d_date_sk + AND ss_item_sk = i_item_sk + AND d_year IN (2000, + 2000+1, + 2000+2, + 2000+3) + GROUP BY itemdesc, + i_item_sk, + d_date + HAVING as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) >4), +max_store_sales AS (SELECT as_noised_max(priv_hash(hash(c_customer_sk)), csales) tpcds_cmax + FROM + (SELECT c_customer_sk, + sum(ss_quantity*ss_sales_price) csales + FROM store_sales, + customer, + date_dim + WHERE ss_customer_sk = c_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year IN (2000, + 2000+1, + 2000+2, + 2000+3) + GROUP BY c_customer_sk) sq2), +best_ss_customer AS (SELECT c_customer_sk, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_quantity*ss_sales_price) ssales + FROM store_sales, + customer, + max_store_sales + WHERE ss_customer_sk = c_customer_sk + GROUP BY c_customer_sk + HAVING as_noised_sum(priv_hash(hash(c_customer_sk)), ss_quantity*ss_sales_price) > (50/100.0) * as_noised_max(priv_hash(hash(c_customer_sk)), tpcds_cmax)) +SELECT c_last_name, + c_first_name, + sales +FROM + (SELECT c_last_name, + c_first_name, + as_noised_sum(priv_hash(hash(customer.c_customer_sk)), cs_quantity*cs_list_price) sales + FROM catalog_sales, + customer, + date_dim, + frequent_ss_items, + best_ss_customer + WHERE d_year = 2000 + AND d_moy = 2 + AND cs_sold_date_sk = d_date_sk + AND cs_item_sk = item_sk + AND cs_bill_customer_sk = best_ss_customer.c_customer_sk + AND cs_bill_customer_sk = customer.c_customer_sk + GROUP BY c_last_name, + c_first_name + UNION ALL SELECT c_last_name, + c_first_name, + as_noised_sum(priv_hash(hash(customer.c_customer_sk)), ws_quantity*ws_list_price) sales + FROM web_sales, + customer, + date_dim, + frequent_ss_items, + best_ss_customer + WHERE d_year = 2000 + AND d_moy = 2 + AND ws_sold_date_sk = d_date_sk + AND ws_item_sk = item_sk + AND ws_bill_customer_sk = best_ss_customer.c_customer_sk + AND ws_bill_customer_sk = customer.c_customer_sk + GROUP BY c_last_name, + c_first_name) sq3 +ORDER BY c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + sales NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q24.sql b/benchmark/tpcds/as_queries/q24.sql new file mode 100644 index 00000000..7e61d583 --- /dev/null +++ b/benchmark/tpcds/as_queries/q24.sql @@ -0,0 +1,53 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- The ssales CTE scalarizes its SUM; later SUM/AVG and HAVING operate on those scalar values. +WITH ssales AS (SELECT c_last_name, + c_first_name, + s_store_name, + ca_state, + s_state, + i_color, + i_current_price, + i_manager_id, + i_units, + i_size, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_net_paid) netpaid + FROM store_sales, + store_returns, + store, + item, + customer, + customer_address + WHERE ss_ticket_number = sr_ticket_number + AND ss_item_sk = sr_item_sk + AND ss_customer_sk = c_customer_sk + AND ss_item_sk = i_item_sk + AND ss_store_sk = s_store_sk + AND c_current_addr_sk = ca_address_sk + AND c_birth_country <> upper(ca_country) + AND s_zip = ca_zip + AND s_market_id=8 + GROUP BY c_last_name, + c_first_name, + s_store_name, + ca_state, + s_state, + i_color, + i_current_price, + i_manager_id, + i_units, + i_size) +SELECT c_last_name, + c_first_name, + s_store_name, + sum(netpaid) paid +FROM ssales +WHERE i_color = 'peach' +GROUP BY c_last_name, + c_first_name, + s_store_name +HAVING sum(netpaid) > + (SELECT 0.05*avg(netpaid) + FROM ssales) +ORDER BY c_last_name, + c_first_name, + s_store_name ; diff --git a/benchmark/tpcds/as_queries/q25.sql b/benchmark/tpcds/as_queries/q25.sql new file mode 100644 index 00000000..b4e038e6 --- /dev/null +++ b/benchmark/tpcds/as_queries/q25.sql @@ -0,0 +1,42 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. + +SELECT i_item_id , + i_item_desc , + s_store_id , + s_store_name , + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit) AS store_sales_profit , + as_noised_sum(priv_hash(hash(ss_customer_sk)), sr_net_loss) AS store_returns_loss , + as_noised_sum(priv_hash(hash(ss_customer_sk)), cs_net_profit) AS catalog_sales_profit +FROM store_sales , + store_returns , + catalog_sales , + date_dim d1 , + date_dim d2 , + date_dim d3 , + store , + item +WHERE d1.d_moy = 4 + AND d1.d_year = 2001 + AND d1.d_date_sk = ss_sold_date_sk + AND i_item_sk = ss_item_sk + AND s_store_sk = ss_store_sk + AND ss_customer_sk = sr_customer_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND sr_returned_date_sk = d2.d_date_sk + AND d2.d_moy BETWEEN 4 AND 10 + AND d2.d_year = 2001 + AND sr_customer_sk = cs_bill_customer_sk + AND sr_item_sk = cs_item_sk + AND cs_sold_date_sk = d3.d_date_sk + AND d3.d_moy BETWEEN 4 AND 10 + AND d3.d_year = 2001 +GROUP BY i_item_id , + i_item_desc , + s_store_id , + s_store_name +ORDER BY i_item_id , + i_item_desc , + s_store_id , + s_store_name +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q26.sql b/benchmark/tpcds/as_queries/q26.sql new file mode 100644 index 00000000..36b06fce --- /dev/null +++ b/benchmark/tpcds/as_queries/q26.sql @@ -0,0 +1,24 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT i_item_id, + (CAST(as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(cs_bill_customer_sk)), cs_quantity) AS DOUBLE)) agg1, + (CAST(as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_list_price) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(cs_bill_customer_sk)), cs_list_price) AS DOUBLE)) agg2, + (CAST(as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_coupon_amt) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(cs_bill_customer_sk)), cs_coupon_amt) AS DOUBLE)) agg3, + (CAST(as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_sales_price) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(cs_bill_customer_sk)), cs_sales_price) AS DOUBLE)) agg4 +FROM catalog_sales, + customer_demographics, + date_dim, + item, + promotion +WHERE cs_sold_date_sk = d_date_sk + AND cs_item_sk = i_item_sk + AND cs_bill_cdemo_sk = cd_demo_sk + AND cs_promo_sk = p_promo_sk + AND cd_gender = 'M' + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND (p_channel_email = 'N' + OR p_channel_event = 'N') + AND d_year = 2000 +GROUP BY i_item_id +ORDER BY i_item_id +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q27.sql b/benchmark/tpcds/as_queries/q27.sql new file mode 100644 index 00000000..93f09123 --- /dev/null +++ b/benchmark/tpcds/as_queries/q27.sql @@ -0,0 +1,61 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Carry the source customer key through the row-level CTE into all three UNION aggregate scopes. +WITH results AS (SELECT ss_customer_sk, i_item_id, + s_state, + 0 AS g_state, + ss_quantity agg1, + ss_list_price agg2, + ss_coupon_amt agg3, + ss_sales_price agg4 + FROM store_sales, + customer_demographics, + date_dim, + store, + item + WHERE ss_sold_date_sk = d_date_sk + AND ss_item_sk = i_item_sk + AND ss_store_sk = s_store_sk + AND ss_cdemo_sk = cd_demo_sk + AND cd_gender = 'M' + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND d_year = 2002 + AND s_state = 'TN' ) +SELECT i_item_id, + s_state, + g_state, + agg1, + agg2, + agg3, + agg4 +FROM + ( SELECT i_item_id, + s_state, + 0 AS g_state, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg1) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg1) AS DOUBLE)) agg1, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg2) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg2) AS DOUBLE)) agg2, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg3) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg3) AS DOUBLE)) agg3, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg4) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg4) AS DOUBLE)) agg4 + FROM results + GROUP BY i_item_id , + s_state + UNION ALL SELECT i_item_id, + NULL AS s_state, + 1 AS g_state, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg1) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg1) AS DOUBLE)) agg1, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg2) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg2) AS DOUBLE)) agg2, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg3) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg3) AS DOUBLE)) agg3, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg4) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg4) AS DOUBLE)) agg4 + FROM results + GROUP BY i_item_id + UNION ALL SELECT NULL AS i_item_id, + NULL AS s_state, + 1 AS g_state, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg1) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg1) AS DOUBLE)) agg1, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg2) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg2) AS DOUBLE)) agg2, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg3) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg3) AS DOUBLE)) agg3, + (CAST(as_noised_sum(priv_hash(hash(ss_customer_sk)), agg4) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ss_customer_sk)), agg4) AS DOUBLE)) agg4 + FROM results ) foo +ORDER BY i_item_id NULLS FIRST, + s_state NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q28.sql b/benchmark/tpcds/as_queries/q28.sql new file mode 100644 index 00000000..2a5d29f8 --- /dev/null +++ b/benchmark/tpcds/as_queries/q28.sql @@ -0,0 +1,45 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Each bucket has independent scalar aggregates and a mask-union DISTINCT-count branch. +WITH b1_input AS NOT MATERIALIZED (SELECT ss_list_price, priv_hash(hash(ss_customer_sk)) AS membership FROM store_sales + WHERE ss_quantity BETWEEN 0 AND 5 + AND (ss_list_price BETWEEN 8 AND 8+10 + OR ss_coupon_amt BETWEEN 459 AND 459+1000 + OR ss_wholesale_cost BETWEEN 57 AND 57+20)), +b1_unique AS NOT MATERIALIZED (SELECT ss_list_price, bit_or(membership) FILTER (WHERE ss_list_price IS NOT NULL) AS membership FROM b1_input GROUP BY ss_list_price), +b1 AS NOT MATERIALIZED (SELECT CAST(as_noised_sum(membership,ss_list_price) AS DOUBLE)/CAST(as_noised_count(membership,ss_list_price) AS DOUBLE) AS B1_LP, as_noised_count(membership,ss_list_price) AS B1_CNT, (SELECT as_noised_count(membership,1::BIGINT) FROM b1_unique) AS B1_CNTD FROM b1_input), +b2_input AS NOT MATERIALIZED (SELECT ss_list_price, priv_hash(hash(ss_customer_sk)) AS membership FROM store_sales + WHERE ss_quantity BETWEEN 6 AND 10 + AND (ss_list_price BETWEEN 90 AND 90+10 + OR ss_coupon_amt BETWEEN 2323 AND 2323+1000 + OR ss_wholesale_cost BETWEEN 31 AND 31+20)), +b2_unique AS NOT MATERIALIZED (SELECT ss_list_price, bit_or(membership) FILTER (WHERE ss_list_price IS NOT NULL) AS membership FROM b2_input GROUP BY ss_list_price), +b2 AS NOT MATERIALIZED (SELECT CAST(as_noised_sum(membership,ss_list_price) AS DOUBLE)/CAST(as_noised_count(membership,ss_list_price) AS DOUBLE) AS B2_LP, as_noised_count(membership,ss_list_price) AS B2_CNT, (SELECT as_noised_count(membership,1::BIGINT) FROM b2_unique) AS B2_CNTD FROM b2_input), +b3_input AS NOT MATERIALIZED (SELECT ss_list_price, priv_hash(hash(ss_customer_sk)) AS membership FROM store_sales + WHERE ss_quantity BETWEEN 11 AND 15 + AND (ss_list_price BETWEEN 142 AND 142+10 + OR ss_coupon_amt BETWEEN 12214 AND 12214+1000 + OR ss_wholesale_cost BETWEEN 79 AND 79+20)), +b3_unique AS NOT MATERIALIZED (SELECT ss_list_price, bit_or(membership) FILTER (WHERE ss_list_price IS NOT NULL) AS membership FROM b3_input GROUP BY ss_list_price), +b3 AS NOT MATERIALIZED (SELECT CAST(as_noised_sum(membership,ss_list_price) AS DOUBLE)/CAST(as_noised_count(membership,ss_list_price) AS DOUBLE) AS B3_LP, as_noised_count(membership,ss_list_price) AS B3_CNT, (SELECT as_noised_count(membership,1::BIGINT) FROM b3_unique) AS B3_CNTD FROM b3_input), +b4_input AS NOT MATERIALIZED (SELECT ss_list_price, priv_hash(hash(ss_customer_sk)) AS membership FROM store_sales + WHERE ss_quantity BETWEEN 16 AND 20 + AND (ss_list_price BETWEEN 135 AND 135+10 + OR ss_coupon_amt BETWEEN 6071 AND 6071+1000 + OR ss_wholesale_cost BETWEEN 38 AND 38+20)), +b4_unique AS NOT MATERIALIZED (SELECT ss_list_price, bit_or(membership) FILTER (WHERE ss_list_price IS NOT NULL) AS membership FROM b4_input GROUP BY ss_list_price), +b4 AS NOT MATERIALIZED (SELECT CAST(as_noised_sum(membership,ss_list_price) AS DOUBLE)/CAST(as_noised_count(membership,ss_list_price) AS DOUBLE) AS B4_LP, as_noised_count(membership,ss_list_price) AS B4_CNT, (SELECT as_noised_count(membership,1::BIGINT) FROM b4_unique) AS B4_CNTD FROM b4_input), +b5_input AS NOT MATERIALIZED (SELECT ss_list_price, priv_hash(hash(ss_customer_sk)) AS membership FROM store_sales + WHERE ss_quantity BETWEEN 21 AND 25 + AND (ss_list_price BETWEEN 122 AND 122+10 + OR ss_coupon_amt BETWEEN 836 AND 836+1000 + OR ss_wholesale_cost BETWEEN 17 AND 17+20)), +b5_unique AS NOT MATERIALIZED (SELECT ss_list_price, bit_or(membership) FILTER (WHERE ss_list_price IS NOT NULL) AS membership FROM b5_input GROUP BY ss_list_price), +b5 AS NOT MATERIALIZED (SELECT CAST(as_noised_sum(membership,ss_list_price) AS DOUBLE)/CAST(as_noised_count(membership,ss_list_price) AS DOUBLE) AS B5_LP, as_noised_count(membership,ss_list_price) AS B5_CNT, (SELECT as_noised_count(membership,1::BIGINT) FROM b5_unique) AS B5_CNTD FROM b5_input), +b6_input AS NOT MATERIALIZED (SELECT ss_list_price, priv_hash(hash(ss_customer_sk)) AS membership FROM store_sales + WHERE ss_quantity BETWEEN 26 AND 30 + AND (ss_list_price BETWEEN 154 AND 154+10 + OR ss_coupon_amt BETWEEN 7326 AND 7326+1000 + OR ss_wholesale_cost BETWEEN 7 AND 7+20)), +b6_unique AS NOT MATERIALIZED (SELECT ss_list_price, bit_or(membership) FILTER (WHERE ss_list_price IS NOT NULL) AS membership FROM b6_input GROUP BY ss_list_price), +b6 AS NOT MATERIALIZED (SELECT CAST(as_noised_sum(membership,ss_list_price) AS DOUBLE)/CAST(as_noised_count(membership,ss_list_price) AS DOUBLE) AS B6_LP, as_noised_count(membership,ss_list_price) AS B6_CNT, (SELECT as_noised_count(membership,1::BIGINT) FROM b6_unique) AS B6_CNTD FROM b6_input) +SELECT * FROM b1, b2, b3, b4, b5, b6 LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q29.sql b/benchmark/tpcds/as_queries/q29.sql new file mode 100644 index 00000000..a58132ca --- /dev/null +++ b/benchmark/tpcds/as_queries/q29.sql @@ -0,0 +1,42 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT i_item_id, + i_item_desc, + s_store_id, + s_store_name, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_quantity) AS store_sales_quantity, + as_noised_sum(priv_hash(hash(ss_customer_sk)), sr_return_quantity) AS store_returns_quantity, + as_noised_sum(priv_hash(hash(ss_customer_sk)), cs_quantity) AS catalog_sales_quantity +FROM store_sales, + store_returns, + catalog_sales, + date_dim d1, + date_dim d2, + date_dim d3, + store, + item +WHERE d1.d_moy = 9 + AND d1.d_year = 1999 + AND d1.d_date_sk = ss_sold_date_sk + AND i_item_sk = ss_item_sk + AND s_store_sk = ss_store_sk + AND ss_customer_sk = sr_customer_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND sr_returned_date_sk = d2.d_date_sk + AND d2.d_moy BETWEEN 9 AND 9 + 3 + AND d2.d_year = 1999 + AND sr_customer_sk = cs_bill_customer_sk + AND sr_item_sk = cs_item_sk + AND cs_sold_date_sk = d3.d_date_sk + AND d3.d_year IN (1999, + 1999+1, + 1999+2) +GROUP BY i_item_id, + i_item_desc, + s_store_id, + s_store_name +ORDER BY i_item_id, + i_item_desc, + s_store_id, + s_store_name +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q30.sql b/benchmark/tpcds/as_queries/q30.sql new file mode 100644 index 00000000..7c835ab5 --- /dev/null +++ b/benchmark/tpcds/as_queries/q30.sql @@ -0,0 +1,49 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Per-customer CTE totals stay scalar; only the correlated cross-customer AVG supplies a counter list. +WITH customer_total_return AS (SELECT wr_returning_customer_sk AS ctr_customer_sk, + ca_state AS ctr_state, + sum(wr_return_amt) AS ctr_total_return + FROM web_returns, + date_dim, + customer_address + WHERE wr_returned_date_sk = d_date_sk + AND d_year = 2002 + AND wr_returning_addr_sk = ca_address_sk + GROUP BY wr_returning_customer_sk, + ca_state) +SELECT c_customer_id, + c_salutation, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_day, + c_birth_month, + c_birth_year, + c_birth_country, + c_login, + c_email_address, + c_last_review_date_sk, + ctr_total_return +FROM customer_total_return ctr1, + customer_address, + customer +WHERE priv_filter_gt(CAST(CAST(ctr1.ctr_total_return AS DOUBLE) * 0.8333333333333334 AS FLOAT), (SELECT priv_div(as_sum(priv_hash(hash(ctr2.ctr_customer_sk)), ctr_total_return), as_count(priv_hash(hash(ctr2.ctr_customer_sk)), ctr_total_return)) + FROM customer_total_return ctr2 + WHERE ctr1.ctr_state = ctr2.ctr_state)) + AND ca_address_sk = c_current_addr_sk + AND ca_state = 'GA' + AND ctr1.ctr_customer_sk = c_customer_sk +ORDER BY c_customer_id NULLS FIRST, + c_salutation NULLS FIRST, + c_first_name NULLS FIRST, + c_last_name NULLS FIRST, + c_preferred_cust_flag NULLS FIRST, + c_birth_day NULLS FIRST, + c_birth_month NULLS FIRST, + c_birth_year NULLS FIRST, + c_birth_country NULLS FIRST, + c_login NULLS FIRST, + c_email_address NULLS FIRST, + c_last_review_date_sk NULLS FIRST, + ctr_total_return NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q31.sql b/benchmark/tpcds/as_queries/q31.sql new file mode 100644 index 00000000..a232e042 --- /dev/null +++ b/benchmark/tpcds/as_queries/q31.sql @@ -0,0 +1,69 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH ss AS (SELECT ca_county, + d_qoy, + d_year, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS store_sales + FROM store_sales, + date_dim, + customer_address + WHERE ss_sold_date_sk = d_date_sk + AND ss_addr_sk=ca_address_sk + GROUP BY ca_county, + d_qoy, + d_year), +ws AS (SELECT ca_county, + d_qoy, + d_year, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) AS web_sales + FROM web_sales, + date_dim, + customer_address + WHERE ws_sold_date_sk = d_date_sk + AND ws_bill_addr_sk=ca_address_sk + GROUP BY ca_county, + d_qoy, + d_year) +SELECT ss1.ca_county , + ss1.d_year , + (ws2.web_sales*1.0000)/ws1.web_sales web_q1_q2_increase , + (ss2.store_sales*1.0000)/ss1.store_sales store_q1_q2_increase , + (ws3.web_sales*1.0000)/ws2.web_sales web_q2_q3_increase , + (ss3.store_sales*1.0000)/ss2.store_sales store_q2_q3_increase +FROM ss ss1 , + ss ss2 , + ss ss3 , + ws ws1 , + ws ws2 , + ws ws3 +WHERE ss1.d_qoy = 1 + AND ss1.d_year = 2000 + AND ss1.ca_county = ss2.ca_county + AND ss2.d_qoy = 2 + AND ss2.d_year = 2000 + AND ss2.ca_county = ss3.ca_county + AND ss3.d_qoy = 3 + AND ss3.d_year = 2000 + AND ss1.ca_county = ws1.ca_county + AND ws1.d_qoy = 1 + AND ws1.d_year = 2000 + AND ws1.ca_county = ws2.ca_county + AND ws2.d_qoy = 2 + AND ws2.d_year = 2000 + AND ws1.ca_county = ws3.ca_county + AND ws3.d_qoy = 3 + AND ws3.d_year = 2000 + AND CASE + WHEN ws1.web_sales > 0 THEN (ws2.web_sales*1.0000)/ws1.web_sales + ELSE NULL + END > CASE + WHEN ss1.store_sales > 0 THEN (ss2.store_sales*1.0000)/ss1.store_sales + ELSE NULL + END + AND CASE + WHEN ws2.web_sales > 0 THEN (ws3.web_sales*1.0000)/ws2.web_sales + ELSE NULL + END > CASE + WHEN ss2.store_sales > 0 THEN (ss3.store_sales*1.0000)/ss2.store_sales + ELSE NULL + END +ORDER BY ss1.ca_county; diff --git a/benchmark/tpcds/as_queries/q32.sql b/benchmark/tpcds/as_queries/q32.sql new file mode 100644 index 00000000..9c4ae6b7 --- /dev/null +++ b/benchmark/tpcds/as_queries/q32.sql @@ -0,0 +1,22 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- The correlated threshold narrows the tuple mask before the outer stochastic SUM. +SELECT as_noised_sum(priv_select_gt(priv_hash(hash(cs_bill_customer_sk)), CAST(cs_ext_discount_amt AS FLOAT), ( SELECT list_transform(priv_div(as_sum(priv_hash(hash(cs_bill_customer_sk)), CAST(cs_ext_discount_amt AS DOUBLE)), as_count(priv_hash(hash(cs_bill_customer_sk)), cs_ext_discount_amt)), lambda x: CAST(1.3 * x AS FLOAT)) + FROM catalog_sales , + date_dim + WHERE cs_item_sk = i_item_sk + AND d_date BETWEEN '2000-01-27' AND cast('2000-04-26' AS date) + AND d_date_sk = cs_sold_date_sk )), cs_ext_discount_amt) AS "excess discount amount" +FROM catalog_sales , + item , + date_dim +WHERE i_manufact_id = 977 + AND i_item_sk = cs_item_sk + AND d_date BETWEEN '2000-01-27' AND cast('2000-04-26' AS date) + AND d_date_sk = cs_sold_date_sk + AND priv_select_gt(priv_hash(hash(cs_bill_customer_sk)), CAST(cs_ext_discount_amt AS FLOAT), ( SELECT list_transform(priv_div(as_sum(priv_hash(hash(cs_bill_customer_sk)), CAST(cs_ext_discount_amt AS DOUBLE)), as_count(priv_hash(hash(cs_bill_customer_sk)), cs_ext_discount_amt)), lambda x: CAST(1.3 * x AS FLOAT)) + FROM catalog_sales , + date_dim + WHERE cs_item_sk = i_item_sk + AND d_date BETWEEN '2000-01-27' AND cast('2000-04-26' AS date) + AND d_date_sk = cs_sold_date_sk )) <> 0 +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q33.sql b/benchmark/tpcds/as_queries/q33.sql new file mode 100644 index 00000000..c4288e8c --- /dev/null +++ b/benchmark/tpcds/as_queries/q33.sql @@ -0,0 +1,64 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH ss AS ( SELECT i_manufact_id, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) total_sales + FROM store_sales, + date_dim, + customer_address, + item + WHERE i_manufact_id IN + (SELECT i_manufact_id + FROM item + WHERE i_category IN ('Electronics')) + AND ss_item_sk = i_item_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 5 + AND ss_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_manufact_id), +cs AS ( SELECT i_manufact_id, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) total_sales + FROM catalog_sales, + date_dim, + customer_address, + item + WHERE i_manufact_id IN + (SELECT i_manufact_id + FROM item + WHERE i_category IN ('Electronics')) + AND cs_item_sk = i_item_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 5 + AND cs_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_manufact_id), +ws AS ( SELECT i_manufact_id, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) total_sales + FROM web_sales, + date_dim, + customer_address, + item + WHERE i_manufact_id IN + (SELECT i_manufact_id + FROM item + WHERE i_category IN ('Electronics')) + AND ws_item_sk = i_item_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 5 + AND ws_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_manufact_id) +SELECT i_manufact_id, + sum(total_sales) total_sales +FROM + (SELECT * + FROM ss + UNION ALL SELECT * + FROM cs + UNION ALL SELECT * + FROM ws) tmp1 +GROUP BY i_manufact_id +ORDER BY total_sales +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q34.sql b/benchmark/tpcds/as_queries/q34.sql new file mode 100644 index 00000000..e7cdd84b --- /dev/null +++ b/benchmark/tpcds/as_queries/q34.sql @@ -0,0 +1,42 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- The terminal BETWEEN uses two separate PAC majority comparisons, not one per-world conjunction. +SELECT c_last_name , + c_first_name , + c_salutation , + c_preferred_cust_flag , + ss_ticket_number , + CAST(as_noised(cnt) AS BIGINT) AS cnt +FROM + (SELECT ss_ticket_number , + ss_customer_sk , + as_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) cnt + FROM store_sales, + date_dim, + store, + household_demographics + WHERE store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND (date_dim.d_dom BETWEEN 1 AND 3 + OR date_dim.d_dom BETWEEN 25 AND 28) + AND (household_demographics.hd_buy_potential = '>10000' + OR household_demographics.hd_buy_potential = 'Unknown') + AND household_demographics.hd_vehicle_count > 0 + AND (CASE + WHEN household_demographics.hd_vehicle_count > 0 THEN (household_demographics.hd_dep_count*1.000)/ household_demographics.hd_vehicle_count + ELSE NULL + END) > 1.2 + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_county = 'Williamson County' + GROUP BY ss_ticket_number, + ss_customer_sk) dn, + customer +WHERE ss_customer_sk = c_customer_sk + AND priv_filter_lte(15::FLOAT, cnt) AND priv_filter_gte(20::FLOAT, cnt) +ORDER BY c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + c_salutation NULLS FIRST, + c_preferred_cust_flag DESC NULLS FIRST, + ss_ticket_number NULLS FIRST; diff --git a/benchmark/tpcds/as_queries/q35.sql b/benchmark/tpcds/as_queries/q35.sql new file mode 100644 index 00000000..a6a41304 --- /dev/null +++ b/benchmark/tpcds/as_queries/q35.sql @@ -0,0 +1,61 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT ca_state, + cd_gender, + cd_marital_status, + cd_dep_count, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt1, + as_noised_min(priv_hash(hash(c.c_customer_sk)), cd_dep_count) min1, + as_noised_max(priv_hash(hash(c.c_customer_sk)), cd_dep_count) max1, + (CAST(as_noised_sum(priv_hash(hash(c.c_customer_sk)), cd_dep_count) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c.c_customer_sk)), cd_dep_count) AS DOUBLE)) avg1, + cd_dep_employed_count, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt2, + as_noised_min(priv_hash(hash(c.c_customer_sk)), cd_dep_employed_count) min2, + as_noised_max(priv_hash(hash(c.c_customer_sk)), cd_dep_employed_count) max2, + (CAST(as_noised_sum(priv_hash(hash(c.c_customer_sk)), cd_dep_employed_count) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c.c_customer_sk)), cd_dep_employed_count) AS DOUBLE)) avg2, + cd_dep_college_count, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt3, + as_noised_min(priv_hash(hash(c.c_customer_sk)), cd_dep_college_count), + as_noised_max(priv_hash(hash(c.c_customer_sk)), cd_dep_college_count), + (CAST(as_noised_sum(priv_hash(hash(c.c_customer_sk)), cd_dep_college_count) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(c.c_customer_sk)), cd_dep_college_count) AS DOUBLE)) +FROM customer c, + customer_address ca, + customer_demographics +WHERE c.c_current_addr_sk = ca.ca_address_sk + AND cd_demo_sk = c.c_current_cdemo_sk + AND EXISTS + (SELECT * + FROM store_sales, + date_dim + WHERE c.c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) + AND (EXISTS + (SELECT * + FROM web_sales, + date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) + OR EXISTS + (SELECT * + FROM catalog_sales, + date_dim + WHERE c.c_customer_sk = cs_ship_customer_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4)) +GROUP BY ca_state, + cd_gender, + cd_marital_status, + cd_dep_count, + cd_dep_employed_count, + cd_dep_college_count +ORDER BY ca_state NULLS FIRST, + cd_gender NULLS FIRST, + cd_marital_status NULLS FIRST, + cd_dep_count NULLS FIRST, + cd_dep_employed_count NULLS FIRST, + cd_dep_college_count NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q40.sql b/benchmark/tpcds/as_queries/q40.sql new file mode 100644 index 00000000..18e49653 --- /dev/null +++ b/benchmark/tpcds/as_queries/q40.sql @@ -0,0 +1,27 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- LEFT JOIN uses the catalog-sales owner once; do not intersect the return customer mask. +SELECT w_state, + i_item_id, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN (cast(d_date AS date) < CAST ('2000-03-11' AS date)) THEN cs_sales_price - coalesce(cr_refunded_cash,0) + ELSE 0 + END) AS sales_before, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN (cast(d_date AS date) >= CAST ('2000-03-11' AS date)) THEN cs_sales_price - coalesce(cr_refunded_cash,0) + ELSE 0 + END) AS sales_after +FROM catalog_sales +LEFT OUTER JOIN catalog_returns ON (cs_order_number = cr_order_number + AND cs_item_sk = cr_item_sk) ,warehouse, + item, + date_dim +WHERE i_current_price BETWEEN 0.99 AND 1.49 + AND i_item_sk = cs_item_sk + AND cs_warehouse_sk = w_warehouse_sk + AND cs_sold_date_sk = d_date_sk + AND d_date BETWEEN CAST ('2000-02-10' AS date) AND CAST ('2000-04-10' AS date) +GROUP BY w_state, + i_item_id +ORDER BY w_state, + i_item_id +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q42.sql b/benchmark/tpcds/as_queries/q42.sql new file mode 100644 index 00000000..c0bc6259 --- /dev/null +++ b/benchmark/tpcds/as_queries/q42.sql @@ -0,0 +1,15 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH asa_states AS (SELECT dt.d_year AS d_year, item.i_category_id AS i_category_id, item.i_category AS i_category, as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_sales_price AS DOUBLE)) AS sum_agg FROM date_dim dt, + store_sales, + item +WHERE dt.d_date_sk = store_sales.ss_sold_date_sk + AND store_sales.ss_item_sk = item.i_item_sk + AND item.i_manager_id = 1 + AND dt.d_moy=11 + AND dt.d_year=2000 +GROUP BY dt.d_year, + item.i_category_id, + item.i_category +), +asa_ranked AS (SELECT * FROM asa_states ORDER BY priv_mean(sum_agg) DESC, d_year, i_category_id, i_category LIMIT 100) +SELECT d_year, i_category_id, i_category, CAST(as_noised(sum_agg) AS DECIMAL(38,2)) AS sum_agg FROM asa_ranked ORDER BY sum_agg DESC, d_year, i_category_id, i_category; diff --git a/benchmark/tpcds/as_queries/q43.sql b/benchmark/tpcds/as_queries/q43.sql new file mode 100644 index 00000000..caafc1e3 --- /dev/null +++ b/benchmark/tpcds/as_queries/q43.sql @@ -0,0 +1,13 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH asa_states AS (SELECT s_store_name, s_store_id, as_sum(priv_hash(hash(ss_customer_sk)), CAST(CASE WHEN d_day_name='Sunday' THEN ss_sales_price ELSE NULL END AS DOUBLE)) AS sun_sales, as_sum(priv_hash(hash(ss_customer_sk)), CAST(CASE WHEN d_day_name='Monday' THEN ss_sales_price ELSE NULL END AS DOUBLE)) AS mon_sales, as_sum(priv_hash(hash(ss_customer_sk)), CAST(CASE WHEN d_day_name='Tuesday' THEN ss_sales_price ELSE NULL END AS DOUBLE)) AS tue_sales, as_sum(priv_hash(hash(ss_customer_sk)), CAST(CASE WHEN d_day_name='Wednesday' THEN ss_sales_price ELSE NULL END AS DOUBLE)) AS wed_sales, as_sum(priv_hash(hash(ss_customer_sk)), CAST(CASE WHEN d_day_name='Thursday' THEN ss_sales_price ELSE NULL END AS DOUBLE)) AS thu_sales, as_sum(priv_hash(hash(ss_customer_sk)), CAST(CASE WHEN d_day_name='Friday' THEN ss_sales_price ELSE NULL END AS DOUBLE)) AS fri_sales, as_sum(priv_hash(hash(ss_customer_sk)), CAST(CASE WHEN d_day_name='Saturday' THEN ss_sales_price ELSE NULL END AS DOUBLE)) AS sat_sales FROM date_dim, + store_sales, + store +WHERE d_date_sk = ss_sold_date_sk + AND s_store_sk = ss_store_sk + AND s_gmt_offset = -5 + AND d_year = 2000 +GROUP BY s_store_name, + s_store_id +), +asa_ranked AS (SELECT * FROM asa_states ORDER BY s_store_name, s_store_id, priv_mean(sun_sales), priv_mean(mon_sales), priv_mean(tue_sales), priv_mean(wed_sales), priv_mean(thu_sales), priv_mean(fri_sales), priv_mean(sat_sales) LIMIT 100) +SELECT s_store_name, s_store_id, CAST(as_noised(sun_sales) AS DECIMAL(38,2)) AS sun_sales, CAST(as_noised(mon_sales) AS DECIMAL(38,2)) AS mon_sales, CAST(as_noised(tue_sales) AS DECIMAL(38,2)) AS tue_sales, CAST(as_noised(wed_sales) AS DECIMAL(38,2)) AS wed_sales, CAST(as_noised(thu_sales) AS DECIMAL(38,2)) AS thu_sales, CAST(as_noised(fri_sales) AS DECIMAL(38,2)) AS fri_sales, CAST(as_noised(sat_sales) AS DECIMAL(38,2)) AS sat_sales FROM asa_ranked ORDER BY s_store_name, s_store_id, sun_sales, mon_sales, tue_sales, wed_sales, thu_sales, fri_sales, sat_sales; diff --git a/benchmark/tpcds/as_queries/q45.sql b/benchmark/tpcds/as_queries/q45.sql new file mode 100644 index 00000000..1fa8f442 --- /dev/null +++ b/benchmark/tpcds/as_queries/q45.sql @@ -0,0 +1,42 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT ca_zip, + ca_city, + as_noised_sum(priv_hash(hash(c_customer_sk)), ws_sales_price) +FROM web_sales, + customer, + customer_address, + date_dim, + item +WHERE ws_bill_customer_sk = c_customer_sk + AND c_current_addr_sk = ca_address_sk + AND ws_item_sk = i_item_sk + AND (SUBSTRING(ca_zip,1,5) IN ('85669', + '86197', + '88274', + '83405', + '86475', + '85392', + '85460', + '80348', + '81792') + OR i_item_id IN + (SELECT i_item_id + FROM item + WHERE i_item_sk IN (2, + 3, + 5, + 7, + 11, + 13, + 17, + 19, + 23, + 29) )) + AND ws_sold_date_sk = d_date_sk + AND d_qoy = 2 + AND d_year = 2001 +GROUP BY ca_zip, + ca_city +ORDER BY ca_zip, + ca_city +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q46.sql b/benchmark/tpcds/as_queries/q46.sql new file mode 100644 index 00000000..839b21fa --- /dev/null +++ b/benchmark/tpcds/as_queries/q46.sql @@ -0,0 +1,48 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. + +SELECT c_last_name, + c_first_name, + ca_city, + bought_city, + ss_ticket_number, + amt, + profit +FROM + (SELECT ss_ticket_number, + ss_customer_sk, + ca_city bought_city, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_coupon_amt) amt, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit) profit + FROM store_sales, + date_dim, + store, + household_demographics, + customer_address + WHERE store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND store_sales.ss_addr_sk = customer_address.ca_address_sk + AND (household_demographics.hd_dep_count = 4 + OR household_demographics.hd_vehicle_count= 3) + AND date_dim.d_dow IN (6, + 0) + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_city IN ('Fairview', + 'Midway') + GROUP BY ss_ticket_number, + ss_customer_sk, + ss_addr_sk, + ca_city) dn, + customer, + customer_address current_addr +WHERE ss_customer_sk = c_customer_sk + AND customer.c_current_addr_sk = current_addr.ca_address_sk + AND current_addr.ca_city <> bought_city +ORDER BY c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + ca_city NULLS FIRST, + bought_city NULLS FIRST, + ss_ticket_number NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q48.sql b/benchmark/tpcds/as_queries/q48.sql new file mode 100644 index 00000000..b2796c71 --- /dev/null +++ b/benchmark/tpcds/as_queries/q48.sql @@ -0,0 +1,40 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_quantity) +FROM store_sales, + store, + customer_demographics, + customer_address, + date_dim +WHERE s_store_sk = ss_store_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2000 + AND ((cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'M' + AND cd_education_status = '4 yr Degree' + AND ss_sales_price BETWEEN 100.00 AND 150.00) + OR (cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'D' + AND cd_education_status = '2 yr Degree' + AND ss_sales_price BETWEEN 50.00 AND 100.00) + OR (cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND ss_sales_price BETWEEN 150.00 AND 200.00)) + AND ((ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('CO', + 'OH', + 'TX') + AND ss_net_profit BETWEEN 0 AND 2000) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('OR', + 'MN', + 'KY') + AND ss_net_profit BETWEEN 150 AND 3000) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('VA', + 'CA', + 'MS') + AND ss_net_profit BETWEEN 50 AND 25000)) ; diff --git a/benchmark/tpcds/as_queries/q50.sql b/benchmark/tpcds/as_queries/q50.sql new file mode 100644 index 00000000..07fc3b8b --- /dev/null +++ b/benchmark/tpcds/as_queries/q50.sql @@ -0,0 +1,68 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT s_store_name, + s_company_id, + s_street_number, + s_street_name, + s_street_type, + s_suite_number, + s_city, + s_county, + s_state, + s_zip, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (sr_returned_date_sk - ss_sold_date_sk <= 30) THEN 1 + ELSE 0 + END) AS "30 days", + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (sr_returned_date_sk - ss_sold_date_sk > 30) + AND (sr_returned_date_sk - ss_sold_date_sk <= 60) THEN 1 + ELSE 0 + END) AS "31-60 days", + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (sr_returned_date_sk - ss_sold_date_sk > 60) + AND (sr_returned_date_sk - ss_sold_date_sk <= 90) THEN 1 + ELSE 0 + END) AS "61-90 days", + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (sr_returned_date_sk - ss_sold_date_sk > 90) + AND (sr_returned_date_sk - ss_sold_date_sk <= 120) THEN 1 + ELSE 0 + END) AS "91-120 days", + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (sr_returned_date_sk - ss_sold_date_sk > 120) THEN 1 + ELSE 0 + END) AS ">120 days" +FROM store_sales, + store_returns, + store, + date_dim d1, + date_dim d2 +WHERE d2.d_year = 2001 + AND d2.d_moy = 8 + AND ss_ticket_number = sr_ticket_number + AND ss_item_sk = sr_item_sk + AND ss_sold_date_sk = d1.d_date_sk + AND sr_returned_date_sk = d2.d_date_sk + AND ss_customer_sk = sr_customer_sk + AND ss_store_sk = s_store_sk +GROUP BY s_store_name, + s_company_id, + s_street_number, + s_street_name, + s_street_type, + s_suite_number, + s_city, + s_county, + s_state, + s_zip +ORDER BY s_store_name, + s_company_id, + s_street_number, + s_street_name, + s_street_type, + s_suite_number, + s_city, + s_county, + s_state, + s_zip +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q52.sql b/benchmark/tpcds/as_queries/q52.sql new file mode 100644 index 00000000..adad0f2a --- /dev/null +++ b/benchmark/tpcds/as_queries/q52.sql @@ -0,0 +1,15 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH asa_states AS (SELECT dt.d_year AS d_year, item.i_brand_id AS brand_id, item.i_brand AS brand, as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_sales_price AS DOUBLE)) AS ext_price FROM date_dim dt, + store_sales, + item +WHERE dt.d_date_sk = store_sales.ss_sold_date_sk + AND store_sales.ss_item_sk = item.i_item_sk + AND item.i_manager_id = 1 + AND dt.d_moy=11 + AND dt.d_year=2000 +GROUP BY dt.d_year, + item.i_brand, + item.i_brand_id +), +asa_ranked AS (SELECT * FROM asa_states ORDER BY d_year, priv_mean(ext_price) DESC, brand_id LIMIT 100) +SELECT d_year, brand_id, brand, CAST(as_noised(ext_price) AS DECIMAL(38,2)) AS ext_price FROM asa_ranked ORDER BY d_year, ext_price DESC, brand_id; diff --git a/benchmark/tpcds/as_queries/q55.sql b/benchmark/tpcds/as_queries/q55.sql new file mode 100644 index 00000000..a93b0782 --- /dev/null +++ b/benchmark/tpcds/as_queries/q55.sql @@ -0,0 +1,14 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH asa_states AS (SELECT i_brand_id AS brand_id, i_brand AS brand, as_sum(priv_hash(hash(ss_customer_sk)), CAST(ss_ext_sales_price AS DOUBLE)) AS ext_price FROM date_dim, + store_sales, + item +WHERE d_date_sk = ss_sold_date_sk + AND ss_item_sk = i_item_sk + AND i_manager_id=28 + AND d_moy=11 + AND d_year=1999 +GROUP BY i_brand, + i_brand_id +), +asa_ranked AS (SELECT * FROM asa_states ORDER BY priv_mean(ext_price) DESC, brand_id LIMIT 100) +SELECT brand_id, brand, CAST(as_noised(ext_price) AS DECIMAL(38,2)) AS ext_price FROM asa_ranked ORDER BY ext_price DESC, brand_id; diff --git a/benchmark/tpcds/as_queries/q56.sql b/benchmark/tpcds/as_queries/q56.sql new file mode 100644 index 00000000..7e10f771 --- /dev/null +++ b/benchmark/tpcds/as_queries/q56.sql @@ -0,0 +1,71 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH ss AS (SELECT i_item_id, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) total_sales + FROM store_sales, + date_dim, + customer_address, + item + WHERE i_item_id IN + (SELECT i_item_id + FROM item + WHERE i_color IN ('slate', + 'blanched', + 'burnished')) + AND ss_item_sk = i_item_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy = 2 + AND ss_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id), +cs AS (SELECT i_item_id, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) total_sales + FROM catalog_sales, + date_dim, + customer_address, + item + WHERE i_item_id IN + (SELECT i_item_id + FROM item + WHERE i_color IN ('slate', + 'blanched', + 'burnished')) + AND cs_item_sk = i_item_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy = 2 + AND cs_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id), +ws AS (SELECT i_item_id, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) total_sales + FROM web_sales, + date_dim, + customer_address, + item + WHERE i_item_id IN + (SELECT i_item_id + FROM item + WHERE i_color IN ('slate', + 'blanched', + 'burnished')) + AND ws_item_sk = i_item_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy = 2 + AND ws_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id) +SELECT i_item_id, + sum(total_sales) total_sales +FROM + (SELECT * + FROM ss + UNION ALL SELECT * + FROM cs + UNION ALL SELECT * + FROM ws) tmp1 +GROUP BY i_item_id +ORDER BY total_sales NULLS FIRST, + i_item_id NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q58.sql b/benchmark/tpcds/as_queries/q58.sql new file mode 100644 index 00000000..cbc64b88 --- /dev/null +++ b/benchmark/tpcds/as_queries/q58.sql @@ -0,0 +1,68 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH ss_items AS (SELECT i_item_id item_id, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) ss_item_rev + FROM store_sales, + item, + date_dim + WHERE ss_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM date_dim + WHERE d_week_seq = + (SELECT d_week_seq + FROM date_dim + WHERE d_date = '2000-01-03')) + AND ss_sold_date_sk = d_date_sk + GROUP BY i_item_id), +cs_items AS (SELECT i_item_id item_id, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) cs_item_rev + FROM catalog_sales, + item, + date_dim + WHERE cs_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM date_dim + WHERE d_week_seq = + (SELECT d_week_seq + FROM date_dim + WHERE d_date = '2000-01-03')) + AND cs_sold_date_sk = d_date_sk + GROUP BY i_item_id), +ws_items AS (SELECT i_item_id item_id, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) ws_item_rev + FROM web_sales, + item, + date_dim + WHERE ws_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM date_dim + WHERE d_week_seq = + (SELECT d_week_seq + FROM date_dim + WHERE d_date = '2000-01-03')) + AND ws_sold_date_sk = d_date_sk + GROUP BY i_item_id) +SELECT ss_items.item_id, + ss_item_rev, + ss_item_rev/((ss_item_rev+cs_item_rev+ws_item_rev)/3) * 100 ss_dev, + cs_item_rev, + cs_item_rev/((ss_item_rev+cs_item_rev+ws_item_rev)/3) * 100 cs_dev, + ws_item_rev, + ws_item_rev/((ss_item_rev+cs_item_rev+ws_item_rev)/3) * 100 ws_dev, + (ss_item_rev+cs_item_rev+ws_item_rev)/3 average +FROM ss_items, + cs_items, + ws_items +WHERE ss_items.item_id=cs_items.item_id + AND ss_items.item_id=ws_items.item_id + AND ss_item_rev BETWEEN 0.9 * cs_item_rev AND 1.1 * cs_item_rev + AND ss_item_rev BETWEEN 0.9 * ws_item_rev AND 1.1 * ws_item_rev + AND cs_item_rev BETWEEN 0.9 * ss_item_rev AND 1.1 * ss_item_rev + AND cs_item_rev BETWEEN 0.9 * ws_item_rev AND 1.1 * ws_item_rev + AND ws_item_rev BETWEEN 0.9 * ss_item_rev AND 1.1 * ss_item_rev + AND ws_item_rev BETWEEN 0.9 * cs_item_rev AND 1.1 * cs_item_rev +ORDER BY ss_items.item_id NULLS FIRST, + ss_item_rev NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q59.sql b/benchmark/tpcds/as_queries/q59.sql new file mode 100644 index 00000000..4dd90e46 --- /dev/null +++ b/benchmark/tpcds/as_queries/q59.sql @@ -0,0 +1,85 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH wss AS (SELECT d_week_seq, + ss_store_sk, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Sunday') THEN ss_sales_price + ELSE NULL + END) sun_sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Monday') THEN ss_sales_price + ELSE NULL + END) mon_sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Tuesday') THEN ss_sales_price + ELSE NULL + END) tue_sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Wednesday') THEN ss_sales_price + ELSE NULL + END) wed_sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Thursday') THEN ss_sales_price + ELSE NULL + END) thu_sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Friday') THEN ss_sales_price + ELSE NULL + END) fri_sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Saturday') THEN ss_sales_price + ELSE NULL + END) sat_sales + FROM store_sales, + date_dim + WHERE d_date_sk = ss_sold_date_sk + GROUP BY d_week_seq, + ss_store_sk) +SELECT s_store_name1, + s_store_id1, + d_week_seq1, + sun_sales1/sun_sales2 AS sun_sales_ratio, + mon_sales1/mon_sales2 AS mon_sales_ratio, + tue_sales1/tue_sales2 AS tue_sales_ratio, + wed_sales1/wed_sales2 AS wed_sales_ratio, + thu_sales1/thu_sales2 AS thu_sales_ratio, + fri_sales1/fri_sales2 AS fri_sales_ratio, + sat_sales1/sat_sales2 AS sat_sales_ratio +FROM + (SELECT s_store_name s_store_name1, + wss.d_week_seq d_week_seq1, + s_store_id s_store_id1, + sun_sales sun_sales1, + mon_sales mon_sales1, + tue_sales tue_sales1, + wed_sales wed_sales1, + thu_sales thu_sales1, + fri_sales fri_sales1, + sat_sales sat_sales1 + FROM wss, + store, + date_dim d + WHERE d.d_week_seq = wss.d_week_seq + AND ss_store_sk = s_store_sk + AND d_month_seq BETWEEN 1212 AND 1212 + 11) y, + (SELECT s_store_name s_store_name2, + wss.d_week_seq d_week_seq2, + s_store_id s_store_id2, + sun_sales sun_sales2, + mon_sales mon_sales2, + tue_sales tue_sales2, + wed_sales wed_sales2, + thu_sales thu_sales2, + fri_sales fri_sales2, + sat_sales sat_sales2 + FROM wss, + store, + date_dim d + WHERE d.d_week_seq = wss.d_week_seq + AND ss_store_sk = s_store_sk + AND d_month_seq BETWEEN 1212 + 12 AND 1212 + 23) x +WHERE s_store_id1=s_store_id2 + AND d_week_seq1=d_week_seq2-52 +ORDER BY s_store_name1 NULLS FIRST, + s_store_id1 NULLS FIRST, + d_week_seq1 NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q60.sql b/benchmark/tpcds/as_queries/q60.sql new file mode 100644 index 00000000..e2430099 --- /dev/null +++ b/benchmark/tpcds/as_queries/q60.sql @@ -0,0 +1,65 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH ss AS (SELECT i_item_id, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) total_sales + FROM store_sales, + date_dim, + customer_address, + item + WHERE i_item_id IN + (SELECT i_item_id + FROM item + WHERE i_category ='Music') + AND ss_item_sk = i_item_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 9 + AND ss_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id), +cs AS (SELECT i_item_id, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) total_sales + FROM catalog_sales, + date_dim, + customer_address, + item + WHERE i_item_id IN + (SELECT i_item_id + FROM item + WHERE i_category ='Music') + AND cs_item_sk = i_item_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 9 + AND cs_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id), +ws AS (SELECT i_item_id, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) total_sales + FROM web_sales, + date_dim, + customer_address, + item + WHERE i_item_id IN + (SELECT i_item_id + FROM item + WHERE i_category = 'Music') + AND ws_item_sk = i_item_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 9 + AND ws_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id) +SELECT i_item_id, + sum(total_sales) total_sales +FROM + (SELECT * + FROM ss + UNION ALL SELECT * + FROM cs + UNION ALL SELECT * + FROM ws) tmp1 +GROUP BY i_item_id +ORDER BY i_item_id, + total_sales +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q61.sql b/benchmark/tpcds/as_queries/q61.sql new file mode 100644 index 00000000..4f924fc8 --- /dev/null +++ b/benchmark/tpcds/as_queries/q61.sql @@ -0,0 +1,44 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Ratio arithmetic is lane-wise; only final outputs are scalarized, matching categorical compilation. +SELECT CAST(as_noised(promotions) AS DECIMAL(38,2)) AS promotions, CAST(as_noised(total) AS DECIMAL(38,2)) AS total, CAST(as_noised(list_transform(list_zip(promotions,total), lambda x: CAST(x[1] AS DECIMAL(15,4)) / CAST(x[2] AS DECIMAL(15,4)) * 100)::FLOAT[]) AS DOUBLE) +FROM (SELECT as_sum(priv_hash(hash(c_customer_sk)), ss_ext_sales_price) promotions + FROM store_sales, + store, + promotion, + date_dim, + customer, + customer_address, + item + WHERE ss_sold_date_sk = d_date_sk + AND ss_store_sk = s_store_sk + AND ss_promo_sk = p_promo_sk + AND ss_customer_sk= c_customer_sk + AND ca_address_sk = c_current_addr_sk + AND ss_item_sk = i_item_sk + AND ca_gmt_offset = -5 + AND i_category = 'Jewelry' + AND (p_channel_dmail = 'Y' + OR p_channel_email = 'Y' + OR p_channel_tv = 'Y') + AND s_gmt_offset = -5 + AND d_year = 1998 + AND d_moy = 11) promotional_sales, (SELECT as_sum(priv_hash(hash(c_customer_sk)), ss_ext_sales_price) total + FROM store_sales, + store, + date_dim, + customer, + customer_address, + item + WHERE ss_sold_date_sk = d_date_sk + AND ss_store_sk = s_store_sk + AND ss_customer_sk= c_customer_sk + AND ca_address_sk = c_current_addr_sk + AND ss_item_sk = i_item_sk + AND ca_gmt_offset = -5 + AND i_category = 'Jewelry' + AND s_gmt_offset = -5 + AND d_year = 1998 + AND d_moy = 11) all_sales +ORDER BY promotions, + total +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q62.sql b/benchmark/tpcds/as_queries/q62.sql new file mode 100644 index 00000000..a95aa874 --- /dev/null +++ b/benchmark/tpcds/as_queries/q62.sql @@ -0,0 +1,46 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT w_substr, + sm_type, + web_name, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), CASE + WHEN (ws_ship_date_sk - ws_sold_date_sk <= 30) THEN 1 + ELSE 0 + END) AS "30 days", + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), CASE + WHEN (ws_ship_date_sk - ws_sold_date_sk > 30) + AND (ws_ship_date_sk - ws_sold_date_sk <= 60) THEN 1 + ELSE 0 + END) AS "31-60 days", + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), CASE + WHEN (ws_ship_date_sk - ws_sold_date_sk > 60) + AND (ws_ship_date_sk - ws_sold_date_sk <= 90) THEN 1 + ELSE 0 + END) AS "61-90 days", + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), CASE + WHEN (ws_ship_date_sk - ws_sold_date_sk > 90) + AND (ws_ship_date_sk - ws_sold_date_sk <= 120) THEN 1 + ELSE 0 + END) AS "91-120 days", + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), CASE + WHEN (ws_ship_date_sk - ws_sold_date_sk > 120) THEN 1 + ELSE 0 + END) AS ">120 days" +FROM web_sales, + (SELECT SUBSTRING(w_warehouse_name,1,20) w_substr, + * + FROM warehouse) sq1, + ship_mode, + web_site, + date_dim +WHERE d_month_seq BETWEEN 1200 AND 1200 + 11 + AND ws_ship_date_sk = d_date_sk + AND ws_warehouse_sk = w_warehouse_sk + AND ws_ship_mode_sk = sm_ship_mode_sk + AND ws_web_site_sk = web_site_sk +GROUP BY w_substr, + sm_type, + web_name +ORDER BY 1 NULLS FIRST, + 2 NULLS FIRST, + 3 NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q64.sql b/benchmark/tpcds/as_queries/q64.sql new file mode 100644 index 00000000..bed6a7ea --- /dev/null +++ b/benchmark/tpcds/as_queries/q64.sql @@ -0,0 +1,124 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Each CTE retains scalar aggregates and HAVING; source ownership differs between its two scopes. +WITH cs_ui AS (SELECT cs_item_sk, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_list_price) AS sale, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cr_refunded_cash+cr_reversed_charge+cr_store_credit) AS refund + FROM catalog_sales, + catalog_returns + WHERE cs_item_sk = cr_item_sk + AND cs_order_number = cr_order_number + GROUP BY cs_item_sk + HAVING as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_list_price)>2*as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cr_refunded_cash+cr_reversed_charge+cr_store_credit)), +cross_sales AS (SELECT i_product_name product_name, + i_item_sk item_sk, + s_store_name store_name, + s_zip store_zip, + ad1.ca_street_number b_street_number, + ad1.ca_street_name b_street_name, + ad1.ca_city b_city, + ad1.ca_zip b_zip, + ad2.ca_street_number c_street_number, + ad2.ca_street_name c_street_name, + ad2.ca_city c_city, + ad2.ca_zip c_zip, + d1.d_year AS syear, + d2.d_year AS fsyear, + d3.d_year s2year, + as_noised_count(priv_hash(hash(c_customer_sk)), 1::BIGINT) cnt, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_wholesale_cost) s1, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_list_price) s2, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_coupon_amt) s3 + FROM store_sales, + store_returns, + cs_ui, + date_dim d1, + date_dim d2, + date_dim d3, + store, + customer, + customer_demographics cd1, + customer_demographics cd2, + promotion, + household_demographics hd1, + household_demographics hd2, + customer_address ad1, + customer_address ad2, + income_band ib1, + income_band ib2, + item + WHERE ss_store_sk = s_store_sk + AND ss_sold_date_sk = d1.d_date_sk + AND ss_customer_sk = c_customer_sk + AND ss_cdemo_sk= cd1.cd_demo_sk + AND ss_hdemo_sk = hd1.hd_demo_sk + AND ss_addr_sk = ad1.ca_address_sk + AND ss_item_sk = i_item_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND ss_item_sk = cs_ui.cs_item_sk + AND c_current_cdemo_sk = cd2.cd_demo_sk + AND c_current_hdemo_sk = hd2.hd_demo_sk + AND c_current_addr_sk = ad2.ca_address_sk + AND c_first_sales_date_sk = d2.d_date_sk + AND c_first_shipto_date_sk = d3.d_date_sk + AND ss_promo_sk = p_promo_sk + AND hd1.hd_income_band_sk = ib1.ib_income_band_sk + AND hd2.hd_income_band_sk = ib2.ib_income_band_sk + AND cd1.cd_marital_status <> cd2.cd_marital_status + AND i_color IN ('purple', + 'burlywood', + 'indian', + 'spring', + 'floral', + 'medium') + AND i_current_price BETWEEN 64 AND 64 + 10 + AND i_current_price BETWEEN 64 + 1 AND 64 + 15 + GROUP BY i_product_name, + i_item_sk, + s_store_name, + s_zip, + ad1.ca_street_number, + ad1.ca_street_name, + ad1.ca_city, + ad1.ca_zip, + ad2.ca_street_number, + ad2.ca_street_name, + ad2.ca_city, + ad2.ca_zip, + d1.d_year, + d2.d_year, + d3.d_year) +SELECT cs1.product_name, + cs1.store_name, + cs1.store_zip, + cs1.b_street_number, + cs1.b_street_name, + cs1.b_city, + cs1.b_zip, + cs1.c_street_number, + cs1.c_street_name, + cs1.c_city, + cs1.c_zip, + cs1.syear cs1syear, + cs1.cnt cs1cnt, + cs1.s1 AS s11, + cs1.s2 AS s21, + cs1.s3 AS s31, + cs2.s1 AS s12, + cs2.s2 AS s22, + cs2.s3 AS s32, + cs2.syear, + cs2.cnt +FROM cross_sales cs1, + cross_sales cs2 +WHERE cs1.item_sk=cs2.item_sk + AND cs1.syear = 1999 + AND cs2.syear = 1999 + 1 + AND cs2.cnt <= cs1.cnt + AND cs1.store_name = cs2.store_name + AND cs1.store_zip = cs2.store_zip +ORDER BY cs1.product_name, + cs1.store_name, + cs2.cnt, + cs1.s1, + cs2.s1; diff --git a/benchmark/tpcds/as_queries/q65.sql b/benchmark/tpcds/as_queries/q65.sql new file mode 100644 index 00000000..e774e277 --- /dev/null +++ b/benchmark/tpcds/as_queries/q65.sql @@ -0,0 +1,23 @@ +-- Hand transcription of Q65's compiled PAC dataflow, for auditing (priv_rewrite=false). +-- This intentionally retains the scalarized inner SUM and majority filter from the compiler. +SELECT s_store_name, i_item_desc, + CAST(as_noised(sc.revenue) AS DECIMAL(38,2)) AS revenue, + i_current_price, i_wholesale_cost, i_brand +FROM main.store, main.item, + (SELECT ss_store_sk, avg(revenue) AS ave + FROM (SELECT ss_store_sk, ss_item_sk, + as_noised_sum(priv_hash(hash(ss_customer_sk)),ss_sales_price) AS revenue + FROM main.store_sales, main.date_dim + WHERE ss_sold_date_sk=d_date_sk AND d_month_seq BETWEEN 1176 AND 1187 + GROUP BY ss_store_sk,ss_item_sk) sa + GROUP BY ss_store_sk) sb, + (SELECT ss_store_sk,ss_item_sk, + as_sum(priv_hash(hash(ss_customer_sk)),ss_sales_price) AS revenue + FROM main.store_sales, main.date_dim + WHERE ss_sold_date_sk=d_date_sk AND d_month_seq BETWEEN 1176 AND 1187 + GROUP BY ss_store_sk,ss_item_sk) sc +WHERE sb.ss_store_sk=sc.ss_store_sk + AND priv_filter_gte(CAST(0.1*sb.ave AS FLOAT),sc.revenue) + AND s_store_sk=sc.ss_store_sk AND i_item_sk=sc.ss_item_sk +ORDER BY s_store_name NULLS FIRST,i_item_desc NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q66.sql b/benchmark/tpcds/as_queries/q66.sql new file mode 100644 index 00000000..daad2b26 --- /dev/null +++ b/benchmark/tpcds/as_queries/q66.sql @@ -0,0 +1,221 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Only the two leaf UNION branches are stochastic; the outer monthly rollup remains ordinary. +select + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,ship_carriers + ,year_ + ,sum(jan_sales) as jan_sales + ,sum(feb_sales) as feb_sales + ,sum(mar_sales) as mar_sales + ,sum(apr_sales) as apr_sales + ,sum(may_sales) as may_sales + ,sum(jun_sales) as jun_sales + ,sum(jul_sales) as jul_sales + ,sum(aug_sales) as aug_sales + ,sum(sep_sales) as sep_sales + ,sum(oct_sales) as oct_sales + ,sum(nov_sales) as nov_sales + ,sum(dec_sales) as dec_sales + ,sum(jan_sales/w_warehouse_sq_ft) as jan_sales_per_sq_foot + ,sum(feb_sales/w_warehouse_sq_ft) as feb_sales_per_sq_foot + ,sum(mar_sales/w_warehouse_sq_ft) as mar_sales_per_sq_foot + ,sum(apr_sales/w_warehouse_sq_ft) as apr_sales_per_sq_foot + ,sum(may_sales/w_warehouse_sq_ft) as may_sales_per_sq_foot + ,sum(jun_sales/w_warehouse_sq_ft) as jun_sales_per_sq_foot + ,sum(jul_sales/w_warehouse_sq_ft) as jul_sales_per_sq_foot + ,sum(aug_sales/w_warehouse_sq_ft) as aug_sales_per_sq_foot + ,sum(sep_sales/w_warehouse_sq_ft) as sep_sales_per_sq_foot + ,sum(oct_sales/w_warehouse_sq_ft) as oct_sales_per_sq_foot + ,sum(nov_sales/w_warehouse_sq_ft) as nov_sales_per_sq_foot + ,sum(dec_sales/w_warehouse_sq_ft) as dec_sales_per_sq_foot + ,sum(jan_net) as jan_net + ,sum(feb_net) as feb_net + ,sum(mar_net) as mar_net + ,sum(apr_net) as apr_net + ,sum(may_net) as may_net + ,sum(jun_net) as jun_net + ,sum(jul_net) as jul_net + ,sum(aug_net) as aug_net + ,sum(sep_net) as sep_net + ,sum(oct_net) as oct_net + ,sum(nov_net) as nov_net + ,sum(dec_net) as dec_net + from ( + select + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,'DHL,BARIAN' as ship_carriers + ,d_year as year_ + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 1 + then ws_ext_sales_price* ws_quantity else 0 end) as jan_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 2 + then ws_ext_sales_price* ws_quantity else 0 end) as feb_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 3 + then ws_ext_sales_price* ws_quantity else 0 end) as mar_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 4 + then ws_ext_sales_price* ws_quantity else 0 end) as apr_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 5 + then ws_ext_sales_price* ws_quantity else 0 end) as may_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 6 + then ws_ext_sales_price* ws_quantity else 0 end) as jun_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 7 + then ws_ext_sales_price* ws_quantity else 0 end) as jul_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 8 + then ws_ext_sales_price* ws_quantity else 0 end) as aug_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 9 + then ws_ext_sales_price* ws_quantity else 0 end) as sep_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 10 + then ws_ext_sales_price* ws_quantity else 0 end) as oct_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 11 + then ws_ext_sales_price* ws_quantity else 0 end) as nov_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 12 + then ws_ext_sales_price* ws_quantity else 0 end) as dec_sales + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 1 + then ws_net_paid * ws_quantity else 0 end) as jan_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 2 + then ws_net_paid * ws_quantity else 0 end) as feb_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 3 + then ws_net_paid * ws_quantity else 0 end) as mar_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 4 + then ws_net_paid * ws_quantity else 0 end) as apr_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 5 + then ws_net_paid * ws_quantity else 0 end) as may_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 6 + then ws_net_paid * ws_quantity else 0 end) as jun_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 7 + then ws_net_paid * ws_quantity else 0 end) as jul_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 8 + then ws_net_paid * ws_quantity else 0 end) as aug_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 9 + then ws_net_paid * ws_quantity else 0 end) as sep_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 10 + then ws_net_paid * ws_quantity else 0 end) as oct_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 11 + then ws_net_paid * ws_quantity else 0 end) as nov_net + ,as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 12 + then ws_net_paid * ws_quantity else 0 end) as dec_net + from + web_sales + ,warehouse + ,date_dim + ,time_dim + ,ship_mode + where + ws_warehouse_sk = w_warehouse_sk + and ws_sold_date_sk = d_date_sk + and ws_sold_time_sk = t_time_sk + and ws_ship_mode_sk = sm_ship_mode_sk + and d_year = 2001 + and t_time between 30838 and 30838+28800 + and sm_carrier in ('DHL','BARIAN') + group by + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,d_year + +UNION ALL + + select + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,'DHL,BARIAN' as ship_carriers + ,d_year as year_ + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 1 + then cs_sales_price* cs_quantity else 0 end) as jan_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 2 + then cs_sales_price* cs_quantity else 0 end) as feb_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 3 + then cs_sales_price* cs_quantity else 0 end) as mar_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 4 + then cs_sales_price* cs_quantity else 0 end) as apr_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 5 + then cs_sales_price* cs_quantity else 0 end) as may_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 6 + then cs_sales_price* cs_quantity else 0 end) as jun_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 7 + then cs_sales_price* cs_quantity else 0 end) as jul_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 8 + then cs_sales_price* cs_quantity else 0 end) as aug_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 9 + then cs_sales_price* cs_quantity else 0 end) as sep_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 10 + then cs_sales_price* cs_quantity else 0 end) as oct_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 11 + then cs_sales_price* cs_quantity else 0 end) as nov_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 12 + then cs_sales_price* cs_quantity else 0 end) as dec_sales + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 1 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as jan_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 2 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as feb_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 3 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as mar_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 4 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as apr_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 5 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as may_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 6 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as jun_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 7 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as jul_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 8 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as aug_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 9 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as sep_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 10 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as oct_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 11 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as nov_net + ,as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 12 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as dec_net + from + catalog_sales + ,warehouse + ,date_dim + ,time_dim + ,ship_mode + where + cs_warehouse_sk = w_warehouse_sk + and cs_sold_date_sk = d_date_sk + and cs_sold_time_sk = t_time_sk + and cs_ship_mode_sk = sm_ship_mode_sk + and d_year = 2001 + and t_time between 30838 AND 30838+28800 + and sm_carrier in ('DHL','BARIAN') + group by + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,d_year + ) x + group by + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,ship_carriers + ,year_ + order by w_warehouse_name NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q68.sql b/benchmark/tpcds/as_queries/q68.sql new file mode 100644 index 00000000..7cf7f5c7 --- /dev/null +++ b/benchmark/tpcds/as_queries/q68.sql @@ -0,0 +1,45 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT c_last_name, + c_first_name, + ca_city, + bought_city, + ss_ticket_number, + extended_price, + extended_tax, + list_price +FROM + (SELECT ss_ticket_number, + ss_customer_sk, + ca_city bought_city, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) extended_price, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_list_price) list_price, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_tax) extended_tax + FROM store_sales, + date_dim, + store, + household_demographics, + customer_address + WHERE store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND store_sales.ss_addr_sk = customer_address.ca_address_sk + AND date_dim.d_dom BETWEEN 1 AND 2 + AND (household_demographics.hd_dep_count = 4 + OR household_demographics.hd_vehicle_count= 3) + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_city IN ('Fairview', + 'Midway') + GROUP BY ss_ticket_number, + ss_customer_sk, + ss_addr_sk, + ca_city) dn, + customer, + customer_address current_addr +WHERE ss_customer_sk = c_customer_sk + AND customer.c_current_addr_sk = current_addr.ca_address_sk + AND current_addr.ca_city <> bought_city +ORDER BY c_last_name NULLS FIRST, + ss_ticket_number NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q69.sql b/benchmark/tpcds/as_queries/q69.sql new file mode 100644 index 00000000..58d35272 --- /dev/null +++ b/benchmark/tpcds/as_queries/q69.sql @@ -0,0 +1,52 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT cd_gender, + cd_marital_status, + cd_education_status, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt1, + cd_purchase_estimate, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt2, + cd_credit_rating, + as_noised_count(priv_hash(hash(c.c_customer_sk)), 1::BIGINT) cnt3 +FROM customer c, + customer_address ca, + customer_demographics +WHERE c.c_current_addr_sk = ca.ca_address_sk + AND ca_state IN ('KY', + 'GA', + 'NM') + AND cd_demo_sk = c.c_current_cdemo_sk + AND EXISTS + (SELECT * + FROM store_sales, + date_dim + WHERE c.c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy BETWEEN 4 AND 4+2) + AND (NOT EXISTS + (SELECT * + FROM web_sales, + date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy BETWEEN 4 AND 4+2) + AND NOT EXISTS + (SELECT * + FROM catalog_sales, + date_dim + WHERE c.c_customer_sk = cs_ship_customer_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy BETWEEN 4 AND 4+2)) +GROUP BY cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating +ORDER BY cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q72.sql b/benchmark/tpcds/as_queries/q72.sql new file mode 100644 index 00000000..fb593e23 --- /dev/null +++ b/benchmark/tpcds/as_queries/q72.sql @@ -0,0 +1,40 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- One catalog-sales mask drives the states after the original joins, including LEFT JOINs. +SELECT i_item_desc, + w_warehouse_name, + d1.d_week_seq, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN p_promo_sk IS NULL THEN 1 + ELSE 0 + END) no_promo, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN p_promo_sk IS NOT NULL THEN 1 + ELSE 0 + END) promo, + as_noised_count(priv_hash(hash(cs_bill_customer_sk)), 1::BIGINT) total_cnt +FROM catalog_sales +JOIN inventory ON (cs_item_sk = inv_item_sk) +JOIN warehouse ON (w_warehouse_sk=inv_warehouse_sk) +JOIN item ON (i_item_sk = cs_item_sk) +JOIN customer_demographics ON (cs_bill_cdemo_sk = cd_demo_sk) +JOIN household_demographics ON (cs_bill_hdemo_sk = hd_demo_sk) +JOIN date_dim d1 ON (cs_sold_date_sk = d1.d_date_sk) +JOIN date_dim d2 ON (inv_date_sk = d2.d_date_sk) +JOIN date_dim d3 ON (cs_ship_date_sk = d3.d_date_sk) +LEFT OUTER JOIN promotion ON (cs_promo_sk=p_promo_sk) +LEFT OUTER JOIN catalog_returns ON (cr_item_sk = cs_item_sk + AND cr_order_number = cs_order_number) +WHERE d1.d_week_seq = d2.d_week_seq + AND inv_quantity_on_hand < cs_quantity + AND d3.d_date > d1.d_date + 5 -- SQL Server: DATEADD(day, 5, d1.d_date) + AND hd_buy_potential = '>10000' + AND d1.d_year = 1999 + AND cd_marital_status = 'D' +GROUP BY i_item_desc, + w_warehouse_name, + d1.d_week_seq +ORDER BY total_cnt DESC NULLS FIRST, + i_item_desc NULLS FIRST, + w_warehouse_name NULLS FIRST, + d1.d_week_seq NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q73.sql b/benchmark/tpcds/as_queries/q73.sql new file mode 100644 index 00000000..c6eb962c --- /dev/null +++ b/benchmark/tpcds/as_queries/q73.sql @@ -0,0 +1,42 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Terminal range comparisons are separate majority decisions; output cnt is finalized afterwards. + +SELECT c_last_name, + c_first_name, + c_salutation, + c_preferred_cust_flag, + ss_ticket_number, + CAST(as_noised(cnt) AS BIGINT) AS cnt +FROM + (SELECT ss_ticket_number, + ss_customer_sk, + as_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) cnt + FROM store_sales, + date_dim, + store, + household_demographics + WHERE store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND date_dim.d_dom BETWEEN 1 AND 2 + AND (household_demographics.hd_buy_potential = 'Unknown' + OR household_demographics.hd_buy_potential = '>10000') + AND household_demographics.hd_vehicle_count > 0 + AND CASE + WHEN household_demographics.hd_vehicle_count > 0 THEN (household_demographics.hd_dep_count*1.000)/ household_demographics.hd_vehicle_count + ELSE NULL + END > 1 + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_county IN ('Orange County', + 'Bronx County', + 'Franklin Parish', + 'Williamson County') + GROUP BY ss_ticket_number, + ss_customer_sk) dj, + customer +WHERE ss_customer_sk = c_customer_sk + AND priv_filter_lte(1::FLOAT, cnt) AND priv_filter_gte(5::FLOAT, cnt) +ORDER BY cnt DESC, + c_last_name ASC; diff --git a/benchmark/tpcds/as_queries/q74.sql b/benchmark/tpcds/as_queries/q74.sql new file mode 100644 index 00000000..1a7ee67d --- /dev/null +++ b/benchmark/tpcds/as_queries/q74.sql @@ -0,0 +1,64 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH year_total AS (SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + d_year AS year_, + as_noised_sum(priv_hash(hash(c_customer_sk)), ss_net_paid) year_total, + 's' sale_type + FROM customer, + store_sales, + date_dim + WHERE c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year IN (2001, + 2001+1) + GROUP BY c_customer_id, + c_first_name, + c_last_name, + d_year + UNION ALL SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + d_year AS year_, + as_noised_sum(priv_hash(hash(c_customer_sk)), ws_net_paid) year_total, + 'w' sale_type + FROM customer, + web_sales, + date_dim + WHERE c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year IN (2001, + 2001+1) + GROUP BY c_customer_id, + c_first_name, + c_last_name, + d_year) +SELECT t_s_secyear.customer_id, + t_s_secyear.customer_first_name, + t_s_secyear.customer_last_name +FROM year_total t_s_firstyear, + year_total t_s_secyear, + year_total t_w_firstyear, + year_total t_w_secyear +WHERE t_s_secyear.customer_id = t_s_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_secyear.customer_id + AND t_s_firstyear.customer_id = t_w_firstyear.customer_id + AND t_s_firstyear.sale_type = 's' + AND t_w_firstyear.sale_type = 'w' + AND t_s_secyear.sale_type = 's' + AND t_w_secyear.sale_type = 'w' + AND t_s_firstyear.year_ = 2001 + AND t_s_secyear.year_ = 2001+1 + AND t_w_firstyear.year_ = 2001 + AND t_w_secyear.year_ = 2001+1 + AND t_s_firstyear.year_total > 0 + AND t_w_firstyear.year_total > 0 + AND CASE + WHEN t_w_firstyear.year_total > 0 THEN t_w_secyear.year_total / t_w_firstyear.year_total + ELSE NULL + END > CASE + WHEN t_s_firstyear.year_total > 0 THEN t_s_secyear.year_total / t_s_firstyear.year_total + ELSE NULL + END +ORDER BY 1 NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q77.sql b/benchmark/tpcds/as_queries/q77.sql new file mode 100644 index 00000000..c29146cd --- /dev/null +++ b/benchmark/tpcds/as_queries/q77.sql @@ -0,0 +1,91 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Keep all six original branches, including the original catalog Cartesian product. +WITH ss AS (SELECT s_store_sk, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit) AS profit + FROM store_sales, + date_dim, + store + WHERE ss_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND ss_store_sk = s_store_sk + GROUP BY s_store_sk), +sr AS (SELECT s_store_sk, + as_noised_sum(priv_hash(hash(sr_customer_sk)), sr_return_amt) AS returns_, + as_noised_sum(priv_hash(hash(sr_customer_sk)), sr_net_loss) AS profit_loss + FROM store_returns, + date_dim, + store + WHERE sr_returned_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND sr_store_sk = s_store_sk + GROUP BY s_store_sk), +cs AS (SELECT cs_call_center_sk, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) AS sales, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_net_profit) AS profit + FROM catalog_sales, + date_dim + WHERE cs_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + GROUP BY cs_call_center_sk), +cr AS (SELECT cr_call_center_sk, + as_noised_sum(priv_hash(hash(cr_returning_customer_sk)), cr_return_amount) AS returns_, + as_noised_sum(priv_hash(hash(cr_returning_customer_sk)), cr_net_loss) AS profit_loss + FROM catalog_returns, + date_dim + WHERE cr_returned_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + GROUP BY cr_call_center_sk ), +ws AS (SELECT wp_web_page_sk, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) AS sales, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_net_profit) AS profit + FROM web_sales, + date_dim, + web_page + WHERE ws_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND ws_web_page_sk = wp_web_page_sk + GROUP BY wp_web_page_sk), +wr AS (SELECT wp_web_page_sk, + as_noised_sum(priv_hash(hash(wr_returning_customer_sk)), wr_return_amt) AS returns_, + as_noised_sum(priv_hash(hash(wr_returning_customer_sk)), wr_net_loss) AS profit_loss + FROM web_returns, + date_dim, + web_page + WHERE wr_returned_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND wr_web_page_sk = wp_web_page_sk + GROUP BY wp_web_page_sk) +SELECT channel , + id , + sum(sales) AS sales , + sum(returns_) AS returns_ , + sum(profit) AS profit +FROM + (SELECT 'store channel' AS channel , + ss.s_store_sk AS id , + sales , + coalesce(returns_, 0) AS returns_ , + (profit - coalesce(profit_loss,0)) AS profit + FROM ss + LEFT JOIN sr ON ss.s_store_sk = sr.s_store_sk + UNION ALL SELECT 'catalog channel' AS channel , + cs_call_center_sk AS id , + sales , + returns_ , + (profit - profit_loss) AS profit + FROM cs , + cr + UNION ALL SELECT 'web channel' AS channel , + ws.wp_web_page_sk AS id , + sales , + coalesce(returns_, 0) returns_ , + (profit - coalesce(profit_loss,0)) AS profit + FROM ws + LEFT JOIN wr ON ws.wp_web_page_sk = wr.wp_web_page_sk ) x +GROUP BY ROLLUP (channel, + id) +ORDER BY channel NULLS FIRST, + id NULLS FIRST, + returns_ DESC +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q78.sql b/benchmark/tpcds/as_queries/q78.sql new file mode 100644 index 00000000..d91eeae1 --- /dev/null +++ b/benchmark/tpcds/as_queries/q78.sql @@ -0,0 +1,75 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Preserve original sales/returns outer joins; ownership comes from each sales branch. +WITH ws AS (SELECT d_year AS ws_sold_year, + ws_item_sk, + ws_bill_customer_sk ws_customer_sk, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_quantity) ws_qty, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_wholesale_cost) ws_wc, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_sales_price) ws_sp + FROM web_sales + LEFT JOIN web_returns ON wr_order_number=ws_order_number + AND ws_item_sk=wr_item_sk + JOIN date_dim ON ws_sold_date_sk = d_date_sk + WHERE wr_order_number IS NULL + GROUP BY d_year, + ws_item_sk, + ws_bill_customer_sk ), +cs AS (SELECT d_year AS cs_sold_year, + cs_item_sk, + cs_bill_customer_sk cs_customer_sk, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_quantity) cs_qty, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_wholesale_cost) cs_wc, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_sales_price) cs_sp + FROM catalog_sales + LEFT JOIN catalog_returns ON cr_order_number=cs_order_number + AND cs_item_sk=cr_item_sk + JOIN date_dim ON cs_sold_date_sk = d_date_sk + WHERE cr_order_number IS NULL + GROUP BY d_year, + cs_item_sk, + cs_bill_customer_sk ), +ss AS (SELECT d_year AS ss_sold_year, + ss_item_sk, + ss_customer_sk, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_quantity) ss_qty, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_wholesale_cost) ss_wc, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_sales_price) ss_sp + FROM store_sales + LEFT JOIN store_returns ON sr_ticket_number=ss_ticket_number + AND ss_item_sk=sr_item_sk + JOIN date_dim ON ss_sold_date_sk = d_date_sk + WHERE sr_ticket_number IS NULL + GROUP BY d_year, + ss_item_sk, + ss_customer_sk ) +SELECT ss_sold_year, + ss_item_sk, + ss_customer_sk, + round((ss_qty*1.00)/(coalesce(ws_qty,0)+coalesce(cs_qty,0)),2) ratio, + ss_qty store_qty, + ss_wc store_wholesale_cost, + ss_sp store_sales_price, + coalesce(ws_qty,0)+coalesce(cs_qty,0) other_chan_qty, + coalesce(ws_wc,0)+coalesce(cs_wc,0) other_chan_wholesale_cost, + coalesce(ws_sp,0)+coalesce(cs_sp,0) other_chan_sales_price +FROM ss +LEFT JOIN ws ON (ws_sold_year=ss_sold_year + AND ws_item_sk=ss_item_sk + AND ws_customer_sk=ss_customer_sk) +LEFT JOIN cs ON (cs_sold_year=ss_sold_year + AND cs_item_sk=ss_item_sk + AND cs_customer_sk=ss_customer_sk) +WHERE (coalesce(ws_qty,0)>0 + OR coalesce(cs_qty, 0)>0) + AND ss_sold_year=2000 +ORDER BY ss_sold_year, + ss_item_sk, + ss_customer_sk, + ss_qty DESC, + ss_wc DESC, + ss_sp DESC, + other_chan_qty, + other_chan_wholesale_cost, + other_chan_sales_price, + ratio +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q79.sql b/benchmark/tpcds/as_queries/q79.sql new file mode 100644 index 00000000..670f5494 --- /dev/null +++ b/benchmark/tpcds/as_queries/q79.sql @@ -0,0 +1,39 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT c_last_name, + c_first_name, + SUBSTRING(s_city,1,30), + ss_ticket_number, + amt, + profit +FROM + (SELECT ss_ticket_number , + ss_customer_sk , + store.s_city , + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_coupon_amt) amt , + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit) profit + FROM store_sales, + date_dim, + store, + household_demographics + WHERE store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND (household_demographics.hd_dep_count = 6 + OR household_demographics.hd_vehicle_count > 2) + AND date_dim.d_dow = 1 + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_number_employees BETWEEN 200 AND 295 + GROUP BY ss_ticket_number, + ss_customer_sk, + ss_addr_sk, + store.s_city) ms, + customer +WHERE ss_customer_sk = c_customer_sk +ORDER BY c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + SUBSTRING(s_city,1,30) NULLS FIRST, + profit NULLS FIRST, + ss_ticket_number +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q80.sql b/benchmark/tpcds/as_queries/q80.sql new file mode 100644 index 00000000..ae118341 --- /dev/null +++ b/benchmark/tpcds/as_queries/q80.sql @@ -0,0 +1,85 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Stochastic sales/returns expressions share the sales-side owner; outer ROLLUP stays scalar. +WITH ssr AS (SELECT s_store_id AS store_id, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS sales, + as_noised_sum(priv_hash(hash(ss_customer_sk)), coalesce(sr_return_amt, 0)) AS returns_, + as_noised_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit - coalesce(sr_net_loss, 0)) AS profit + FROM store_sales + LEFT OUTER JOIN store_returns ON (ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number), date_dim, + store, + item, + promotion + WHERE ss_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND ss_store_sk = s_store_sk + AND ss_item_sk = i_item_sk + AND i_current_price > 50 + AND ss_promo_sk = p_promo_sk + AND p_channel_tv = 'N' + GROUP BY s_store_id), +csr AS (SELECT cp_catalog_page_id AS catalog_page_id, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) AS sales, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), coalesce(cr_return_amount, 0)) AS returns_, + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), cs_net_profit - coalesce(cr_net_loss, 0)) AS profit + FROM catalog_sales + LEFT OUTER JOIN catalog_returns ON (cs_item_sk = cr_item_sk + AND cs_order_number = cr_order_number), date_dim, + catalog_page, + item, + promotion + WHERE cs_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND cs_catalog_page_sk = cp_catalog_page_sk + AND cs_item_sk = i_item_sk + AND i_current_price > 50 + AND cs_promo_sk = p_promo_sk + AND p_channel_tv = 'N' + GROUP BY cp_catalog_page_id), +wsr AS (SELECT web_site_id, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) AS sales, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), coalesce(wr_return_amt, 0)) AS returns_, + as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_net_profit - coalesce(wr_net_loss, 0)) AS profit + FROM web_sales + LEFT OUTER JOIN web_returns ON (ws_item_sk = wr_item_sk + AND ws_order_number = wr_order_number), date_dim, + web_site, + item, + promotion + WHERE ws_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND ws_web_site_sk = web_site_sk + AND ws_item_sk = i_item_sk + AND i_current_price > 50 + AND ws_promo_sk = p_promo_sk + AND p_channel_tv = 'N' + GROUP BY web_site_id) +SELECT channel , + id , + sum(sales) AS sales , + sum(returns_) AS returns_ , + sum(profit) AS profit +FROM + (SELECT 'store channel' AS channel , + concat('store', store_id) AS id , + sales , + returns_ , + profit + FROM ssr + UNION ALL SELECT 'catalog channel' AS channel , + concat('catalog_page', catalog_page_id) AS id , + sales , + returns_ , + profit + FROM csr + UNION ALL SELECT 'web channel' AS channel , + concat('web_site', web_site_id) AS id , + sales , + returns_ , + profit + FROM wsr ) x +GROUP BY ROLLUP (channel, + id) +ORDER BY channel NULLS FIRST, + id NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q81.sql b/benchmark/tpcds/as_queries/q81.sql new file mode 100644 index 00000000..7549b3f6 --- /dev/null +++ b/benchmark/tpcds/as_queries/q81.sql @@ -0,0 +1,55 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Per-customer CTE totals stay scalar; only the correlated cross-customer AVG supplies a counter list. +WITH customer_total_return AS (SELECT cr_returning_customer_sk AS ctr_customer_sk , + ca_state AS ctr_state, + sum(cr_return_amt_inc_tax) AS ctr_total_return + FROM catalog_returns , + date_dim , + customer_address + WHERE cr_returned_date_sk = d_date_sk + AND d_year = 2000 + AND cr_returning_addr_sk = ca_address_sk + GROUP BY cr_returning_customer_sk , + ca_state) +SELECT c_customer_id, + c_salutation, + c_first_name, + c_last_name, + ca_street_number, + ca_street_name , + ca_street_type, + ca_suite_number, + ca_city, + ca_county, + ca_state, + ca_zip, + ca_country, + ca_gmt_offset , + ca_location_type, + ctr_total_return +FROM customer_total_return ctr1 , + customer_address , + customer +WHERE priv_filter_gt(CAST(CAST(ctr1.ctr_total_return AS DOUBLE) * 0.8333333333333334 AS FLOAT), (SELECT priv_div(as_sum(priv_hash(hash(ctr2.ctr_customer_sk)), ctr_total_return), as_count(priv_hash(hash(ctr2.ctr_customer_sk)), ctr_total_return)) + FROM customer_total_return ctr2 + WHERE ctr1.ctr_state = ctr2.ctr_state)) + AND ca_address_sk = c_current_addr_sk + AND ca_state = 'GA' + AND ctr1.ctr_customer_sk = c_customer_sk +ORDER BY c_customer_id, + c_salutation, + c_first_name, + c_last_name, + ca_street_number, + ca_street_name , + ca_street_type, + ca_suite_number, + ca_city, + ca_county, + ca_state, + ca_zip, + ca_country, + ca_gmt_offset , + ca_location_type, + ctr_total_return +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q83.sql b/benchmark/tpcds/as_queries/q83.sql new file mode 100644 index 00000000..9f365214 --- /dev/null +++ b/benchmark/tpcds/as_queries/q83.sql @@ -0,0 +1,68 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +WITH sr_items AS (SELECT i_item_id item_id, + as_noised_sum(priv_hash(hash(sr_customer_sk)), sr_return_quantity) sr_item_qty + FROM store_returns, + item, + date_dim + WHERE sr_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM date_dim + WHERE d_week_seq IN + (SELECT d_week_seq + FROM date_dim + WHERE d_date IN ('2000-06-30', + '2000-09-27', + '2000-11-17'))) + AND sr_returned_date_sk = d_date_sk + GROUP BY i_item_id), +cr_items AS (SELECT i_item_id item_id, + as_noised_sum(priv_hash(hash(cr_returning_customer_sk)), cr_return_quantity) cr_item_qty + FROM catalog_returns, + item, + date_dim + WHERE cr_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM date_dim + WHERE d_week_seq IN + (SELECT d_week_seq + FROM date_dim + WHERE d_date IN ('2000-06-30', + '2000-09-27', + '2000-11-17'))) + AND cr_returned_date_sk = d_date_sk + GROUP BY i_item_id), +wr_items AS (SELECT i_item_id item_id, + as_noised_sum(priv_hash(hash(wr_returning_customer_sk)), wr_return_quantity) wr_item_qty + FROM web_returns, + item, + date_dim + WHERE wr_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM date_dim + WHERE d_week_seq IN + (SELECT d_week_seq + FROM date_dim + WHERE d_date IN ('2000-06-30', + '2000-09-27', + '2000-11-17'))) + AND wr_returned_date_sk = d_date_sk + GROUP BY i_item_id) +SELECT sr_items.item_id , + sr_item_qty , + (sr_item_qty*1.0000)/(sr_item_qty+cr_item_qty+wr_item_qty)/3.0000 * 100 sr_dev , + cr_item_qty , + (cr_item_qty*1.0000)/(sr_item_qty+cr_item_qty+wr_item_qty)/3.0000 * 100 cr_dev , + wr_item_qty , + (wr_item_qty*1.0000)/(sr_item_qty+cr_item_qty+wr_item_qty)/3.0000 * 100 wr_dev , + (sr_item_qty+cr_item_qty+wr_item_qty)/3.0 average +FROM sr_items , + cr_items , + wr_items +WHERE sr_items.item_id=cr_items.item_id + AND sr_items.item_id=wr_items.item_id +ORDER BY sr_items.item_id NULLS FIRST, + sr_item_qty NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q85.sql b/benchmark/tpcds/as_queries/q85.sql new file mode 100644 index 00000000..47ba8f73 --- /dev/null +++ b/benchmark/tpcds/as_queries/q85.sql @@ -0,0 +1,60 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +-- The compiler uses one accessible web-sales customer mask, not a second-mask intersection. + +SELECT SUBSTRING(r_reason_desc,1,20) , + (CAST(as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ws_bill_customer_sk)), ws_quantity) AS DOUBLE)) avg1, + (CAST(as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), wr_refunded_cash) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ws_bill_customer_sk)), wr_refunded_cash) AS DOUBLE)) avg2, + (CAST(as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), wr_fee) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ws_bill_customer_sk)), wr_fee) AS DOUBLE)) +FROM web_sales, + web_returns, + web_page, + customer_demographics cd1, + customer_demographics cd2, + customer_address, + date_dim, + reason +WHERE ws_web_page_sk = wp_web_page_sk + AND ws_item_sk = wr_item_sk + AND ws_order_number = wr_order_number + AND ws_sold_date_sk = d_date_sk + AND d_year = 2000 + AND cd1.cd_demo_sk = wr_refunded_cdemo_sk + AND cd2.cd_demo_sk = wr_returning_cdemo_sk + AND ca_address_sk = wr_refunded_addr_sk + AND r_reason_sk = wr_reason_sk + AND ( ( cd1.cd_marital_status = 'M' + AND cd1.cd_marital_status = cd2.cd_marital_status + AND cd1.cd_education_status = 'Advanced Degree' + AND cd1.cd_education_status = cd2.cd_education_status + AND ws_sales_price BETWEEN 100.00 AND 150.00 ) + OR ( cd1.cd_marital_status = 'S' + AND cd1.cd_marital_status = cd2.cd_marital_status + AND cd1.cd_education_status = 'College' + AND cd1.cd_education_status = cd2.cd_education_status + AND ws_sales_price BETWEEN 50.00 AND 100.00 ) + OR ( cd1.cd_marital_status = 'W' + AND cd1.cd_marital_status = cd2.cd_marital_status + AND cd1.cd_education_status = '2 yr Degree' + AND cd1.cd_education_status = cd2.cd_education_status + AND ws_sales_price BETWEEN 150.00 AND 200.00 ) ) + AND ( ( ca_country = 'United States' + AND ca_state IN ('IN', + 'OH', + 'NJ') + AND ws_net_profit BETWEEN 100 AND 200) + OR ( ca_country = 'United States' + AND ca_state IN ('WI', + 'CT', + 'KY') + AND ws_net_profit BETWEEN 150 AND 300) + OR ( ca_country = 'United States' + AND ca_state IN ('LA', + 'IA', + 'AR') + AND ws_net_profit BETWEEN 50 AND 250) ) +GROUP BY r_reason_desc +ORDER BY SUBSTRING(r_reason_desc,1,20) , + (CAST(as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), ws_quantity) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ws_bill_customer_sk)), ws_quantity) AS DOUBLE)) , + (CAST(as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), wr_refunded_cash) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ws_bill_customer_sk)), wr_refunded_cash) AS DOUBLE)) , + (CAST(as_noised_sum(priv_hash(hash(ws_bill_customer_sk)), wr_fee) AS DOUBLE) / CAST(as_noised_count(priv_hash(hash(ws_bill_customer_sk)), wr_fee) AS DOUBLE)) +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q88.sql b/benchmark/tpcds/as_queries/q88.sql new file mode 100644 index 00000000..5d178052 --- /dev/null +++ b/benchmark/tpcds/as_queries/q88.sql @@ -0,0 +1,139 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT * +FROM + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h8_30_to_9 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 8 + AND time_dim.t_minute >= 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s1, + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h9_to_9_30 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 9 + AND time_dim.t_minute < 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s2, + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h9_30_to_10 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 9 + AND time_dim.t_minute >= 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s3, + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h10_to_10_30 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 10 + AND time_dim.t_minute < 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s4, + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h10_30_to_11 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 10 + AND time_dim.t_minute >= 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s5, + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h11_to_11_30 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 11 + AND time_dim.t_minute < 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s6, + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h11_30_to_12 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 11 + AND time_dim.t_minute >= 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s7, + (SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) h12_to_12_30 + FROM store_sales, + household_demographics, + time_dim, + store + WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 12 + AND time_dim.t_minute < 30 + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese') s8 ; diff --git a/benchmark/tpcds/as_queries/q90.sql b/benchmark/tpcds/as_queries/q90.sql new file mode 100644 index 00000000..2de65cf8 --- /dev/null +++ b/benchmark/tpcds/as_queries/q90.sql @@ -0,0 +1,26 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- Evaluate the NULL guard and DECIMAL ratio lane-wise before FLOAT-list finalization. +SELECT CAST(as_noised(list_transform(list_zip(amc,pmc), lambda x: CASE WHEN x[2]=0 THEN NULL ELSE CAST(x[1] AS DECIMAL(15,4))/CAST(x[2] AS DECIMAL(15,4)) END)::FLOAT[]) AS DOUBLE) AS am_pm_ratio +FROM (SELECT as_count(priv_hash(hash(ws_bill_customer_sk)), 1::BIGINT) amc + FROM web_sales, + household_demographics, + time_dim, + web_page + WHERE ws_sold_time_sk = time_dim.t_time_sk + AND ws_ship_hdemo_sk = household_demographics.hd_demo_sk + AND ws_web_page_sk = web_page.wp_web_page_sk + AND time_dim.t_hour BETWEEN 8 AND 8+1 + AND household_demographics.hd_dep_count = 6 + AND web_page.wp_char_count BETWEEN 5000 AND 5200) at_, (SELECT as_count(priv_hash(hash(ws_bill_customer_sk)), 1::BIGINT) pmc + FROM web_sales, + household_demographics, + time_dim, + web_page + WHERE ws_sold_time_sk = time_dim.t_time_sk + AND ws_ship_hdemo_sk = household_demographics.hd_demo_sk + AND ws_web_page_sk = web_page.wp_web_page_sk + AND time_dim.t_hour BETWEEN 19 AND 19+1 + AND household_demographics.hd_dep_count = 6 + AND web_page.wp_char_count BETWEEN 5000 AND 5200) pt +ORDER BY am_pm_ratio +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q91.sql b/benchmark/tpcds/as_queries/q91.sql new file mode 100644 index 00000000..cc0f31e5 --- /dev/null +++ b/benchmark/tpcds/as_queries/q91.sql @@ -0,0 +1,31 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT cc_call_center_id Call_Center, + cc_name Call_Center_Name, + cc_manager Manager, + as_noised_sum(priv_hash(hash(c_customer_sk)), cr_net_loss) Returns_Loss +FROM call_center, + catalog_returns, + date_dim, + customer, + customer_address, + customer_demographics, + household_demographics +WHERE cr_call_center_sk = cc_call_center_sk + AND cr_returned_date_sk = d_date_sk + AND cr_returning_customer_sk= c_customer_sk + AND cd_demo_sk = c_current_cdemo_sk + AND hd_demo_sk = c_current_hdemo_sk + AND ca_address_sk = c_current_addr_sk + AND d_year = 1998 + AND d_moy = 11 + AND ((cd_marital_status = 'M' + AND cd_education_status = 'Unknown') or(cd_marital_status = 'W' + AND cd_education_status = 'Advanced Degree')) + AND hd_buy_potential LIKE 'Unknown%' + AND ca_gmt_offset = -7 +GROUP BY cc_call_center_id, + cc_name, + cc_manager, + cd_marital_status, + cd_education_status +ORDER BY as_noised_sum(priv_hash(hash(c_customer_sk)), cr_net_loss) DESC; diff --git a/benchmark/tpcds/as_queries/q92.sql b/benchmark/tpcds/as_queries/q92.sql new file mode 100644 index 00000000..6f041b12 --- /dev/null +++ b/benchmark/tpcds/as_queries/q92.sql @@ -0,0 +1,22 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT as_noised_sum(priv_select_gt(priv_hash(hash(ws_bill_customer_sk)), CAST(ws_ext_discount_amt AS FLOAT), (SELECT list_transform(priv_div(as_sum(priv_hash(hash(ws_bill_customer_sk)), CAST(ws_ext_discount_amt AS DOUBLE)), as_count(priv_hash(hash(ws_bill_customer_sk)), ws_ext_discount_amt)), lambda x: CAST(1.3 * x AS FLOAT)) + FROM web_sales, + date_dim + WHERE ws_item_sk = i_item_sk + AND d_date BETWEEN '2000-01-27' AND cast('2000-04-26' AS date) + AND d_date_sk = ws_sold_date_sk )), ws_ext_discount_amt) AS "Excess Discount Amount" +FROM web_sales, + item, + date_dim +WHERE i_manufact_id = 350 + AND i_item_sk = ws_item_sk + AND d_date BETWEEN '2000-01-27' AND cast('2000-04-26' AS date) + AND d_date_sk = ws_sold_date_sk + AND priv_select_gt(priv_hash(hash(ws_bill_customer_sk)), CAST(ws_ext_discount_amt AS FLOAT), (SELECT list_transform(priv_div(as_sum(priv_hash(hash(ws_bill_customer_sk)), CAST(ws_ext_discount_amt AS DOUBLE)), as_count(priv_hash(hash(ws_bill_customer_sk)), ws_ext_discount_amt)), lambda x: CAST(1.3 * x AS FLOAT)) + FROM web_sales, + date_dim + WHERE ws_item_sk = i_item_sk + AND d_date BETWEEN '2000-01-27' AND cast('2000-04-26' AS date) + AND d_date_sk = ws_sold_date_sk )) <> 0 +ORDER BY "Excess Discount Amount" +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q93.sql b/benchmark/tpcds/as_queries/q93.sql new file mode 100644 index 00000000..8be9d191 --- /dev/null +++ b/benchmark/tpcds/as_queries/q93.sql @@ -0,0 +1,20 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +SELECT ss_customer_sk, + as_noised_sum(priv_hash(hash(ss_customer_sk)), act_sales) sumsales +FROM + (SELECT ss_item_sk, + ss_ticket_number, + ss_customer_sk, + CASE + WHEN sr_return_quantity IS NOT NULL THEN (ss_quantity-sr_return_quantity)*ss_sales_price + ELSE (ss_quantity*ss_sales_price) + END act_sales + FROM store_sales + LEFT OUTER JOIN store_returns ON (sr_item_sk = ss_item_sk + AND sr_ticket_number = ss_ticket_number) ,reason + WHERE sr_reason_sk = r_reason_sk + AND r_reason_desc = 'reason 28') t +GROUP BY ss_customer_sk +ORDER BY sumsales NULLS FIRST, + ss_customer_sk NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q94.sql b/benchmark/tpcds/as_queries/q94.sql new file mode 100644 index 00000000..3b2858b8 --- /dev/null +++ b/benchmark/tpcds/as_queries/q94.sql @@ -0,0 +1,24 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- COUNT(DISTINCT) unions membership by order; EXISTS/NOT EXISTS retain their original SQL semantics. +WITH asa_input AS NOT MATERIALIZED (SELECT ws_order_number, ws_ext_ship_cost, ws_net_profit, priv_hash(hash(ws1.ws_bill_customer_sk)) AS membership FROM web_sales ws1 , + date_dim , + customer_address , + web_site +WHERE d_date BETWEEN '1999-02-01' AND cast('1999-04-02' AS date) + AND ws1.ws_ship_date_sk = d_date_sk + AND ws1.ws_ship_addr_sk = ca_address_sk + AND ca_state = 'IL' + AND ws1.ws_web_site_sk = web_site_sk + AND web_company_name = 'pri' + AND EXISTS + (SELECT * + FROM web_sales ws2 + WHERE ws1.ws_order_number = ws2.ws_order_number + AND ws1.ws_warehouse_sk <> ws2.ws_warehouse_sk) + AND NOT exists + (SELECT * + FROM web_returns wr1 + WHERE ws1.ws_order_number = wr1.wr_order_number) +), +asa_distinct AS NOT MATERIALIZED (SELECT ws_order_number, bit_or(membership) FILTER (WHERE ws_order_number IS NOT NULL) AS membership FROM asa_input GROUP BY ws_order_number) +SELECT d.n AS "order count", s.shipping AS "total shipping cost", s.profit AS "total net profit" FROM (SELECT as_noised_count(membership, 1::BIGINT) AS n FROM asa_distinct) d CROSS JOIN (SELECT as_noised_sum(membership, ws_ext_ship_cost) AS shipping, as_noised_sum(membership, ws_net_profit) AS profit FROM asa_input) s ORDER BY "order count" LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q95.sql b/benchmark/tpcds/as_queries/q95.sql new file mode 100644 index 00000000..32c7aedd --- /dev/null +++ b/benchmark/tpcds/as_queries/q95.sql @@ -0,0 +1,30 @@ +-- Handwritten PAC SQL, following the compiled aggregate scopes and scalar output semantics. +-- The ws_wh CTE stays ordinary; order membership unions and SUMs use the outer web-sales owner. +WITH ws_wh AS NOT MATERIALIZED (SELECT ws1.ws_order_number, + ws1.ws_warehouse_sk wh1, + ws2.ws_warehouse_sk wh2 + FROM web_sales ws1, + web_sales ws2 + WHERE ws1.ws_order_number = ws2.ws_order_number + AND ws1.ws_warehouse_sk <> ws2.ws_warehouse_sk), +asa_input AS NOT MATERIALIZED (SELECT ws_order_number, ws_ext_ship_cost, ws_net_profit, priv_hash(hash(ws1.ws_bill_customer_sk)) AS membership FROM web_sales ws1 , + date_dim , + customer_address , + web_site +WHERE d_date BETWEEN '1999-02-01' AND cast('1999-04-02' AS date) + AND ws1.ws_ship_date_sk = d_date_sk + AND ws1.ws_ship_addr_sk = ca_address_sk + AND ca_state = 'IL' + AND ws1.ws_web_site_sk = web_site_sk + AND web_company_name = 'pri' + AND ws1.ws_order_number IN + (SELECT ws_order_number + FROM ws_wh) + AND ws1.ws_order_number IN + (SELECT wr_order_number + FROM web_returns, + ws_wh + WHERE wr_order_number = ws_wh.ws_order_number) +), +asa_distinct AS NOT MATERIALIZED (SELECT ws_order_number, bit_or(membership) FILTER (WHERE ws_order_number IS NOT NULL) AS membership FROM asa_input GROUP BY ws_order_number) +SELECT d.n AS "order count", s.shipping AS "total shipping cost", s.profit AS "total net profit" FROM (SELECT as_noised_count(membership, 1::BIGINT) AS n FROM asa_distinct) d CROSS JOIN (SELECT as_noised_sum(membership, ws_ext_ship_cost) AS shipping, as_noised_sum(membership, ws_net_profit) AS profit FROM asa_input) s ORDER BY "order count" LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q96.sql b/benchmark/tpcds/as_queries/q96.sql new file mode 100644 index 00000000..32da38b4 --- /dev/null +++ b/benchmark/tpcds/as_queries/q96.sql @@ -0,0 +1,15 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) +FROM store_sales , + household_demographics, + time_dim, + store +WHERE ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 20 + AND time_dim.t_minute >= 30 + AND household_demographics.hd_dep_count = 7 + AND store.s_store_name = 'ese' +ORDER BY as_noised_count(priv_hash(hash(ss_customer_sk)), 1::BIGINT) +LIMIT 100; diff --git a/benchmark/tpcds/as_queries/q99.sql b/benchmark/tpcds/as_queries/q99.sql new file mode 100644 index 00000000..4b680ee8 --- /dev/null +++ b/benchmark/tpcds/as_queries/q99.sql @@ -0,0 +1,45 @@ +-- Handwritten PAC aggregates; automatic query rewriting is disabled by the benchmark. +SELECT w_substr , + sm_type , + LOWER(cc_name) cc_name_lower , + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN (cs_ship_date_sk - cs_sold_date_sk <= 30) THEN 1 + ELSE 0 + END) AS "30 days", + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN (cs_ship_date_sk - cs_sold_date_sk > 30) + AND (cs_ship_date_sk - cs_sold_date_sk <= 60) THEN 1 + ELSE 0 + END) AS "31-60 days", + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN (cs_ship_date_sk - cs_sold_date_sk > 60) + AND (cs_ship_date_sk - cs_sold_date_sk <= 90) THEN 1 + ELSE 0 + END) AS "61-90 days", + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN (cs_ship_date_sk - cs_sold_date_sk > 90) + AND (cs_ship_date_sk - cs_sold_date_sk <= 120) THEN 1 + ELSE 0 + END) AS "91-120 days", + as_noised_sum(priv_hash(hash(cs_bill_customer_sk)), CASE + WHEN (cs_ship_date_sk - cs_sold_date_sk > 120) THEN 1 + ELSE 0 + END) AS ">120 days" +FROM catalog_sales , + (SELECT SUBSTRING(w_warehouse_name,1,20) w_substr, * + FROM warehouse) AS sq1 , + ship_mode , + call_center , + date_dim +WHERE d_month_seq BETWEEN 1200 AND 1200 + 11 + AND cs_ship_date_sk = d_date_sk + AND cs_warehouse_sk = w_warehouse_sk + AND cs_ship_mode_sk = sm_ship_mode_sk + AND cs_call_center_sk = cc_call_center_sk +GROUP BY w_substr , + sm_type , + cc_name +ORDER BY w_substr NULLS FIRST, + sm_type NULLS FIRST, + cc_name_lower NULLS FIRST +LIMIT 100; diff --git a/benchmark/tpcds/as_tpcds_benchmark.cpp b/benchmark/tpcds/as_tpcds_benchmark.cpp index 5fe7a50a..d622a741 100644 --- a/benchmark/tpcds/as_tpcds_benchmark.cpp +++ b/benchmark/tpcds/as_tpcds_benchmark.cpp @@ -1,10 +1,14 @@ -// TPC-DS coverage and performance use the original SQL and the automatic rewriter. -// Execution success is not an independent validation of per-world correctness. +// Performance/coverage follows TPC-H's PAC output semantics: 64 internal worlds and scalar/categorical outputs. +// pac_mi=0 disables additive noise; priv_filter still uses PAC's deterministic majority decision. +// The timed AS path uses handwritten PAC SQL, with automatic compilation recorded separately for coverage. +// Per-world AS references are separate diagnostics, not compiler-equivalence or timing oracles. #include "duckdb.hpp" #include "benchmark_json.hpp" #include "benchmark_paths.hpp" +#include #include +#include #include #include #include @@ -53,10 +57,363 @@ static string Name(int query) { return name.str(); } +// Separate per-world reference queries expand reduced aggregate results, never base tuples. +using WorldRows = vector>>; + +static void SetHandwrittenAggregates(Connection &con, bool conditional, idx_t first_world, idx_t world_count) { + for (auto &operation : + {string("sum"), string("count"), string("avg"), string("stddev_samp"), string("min"), string("max")}) { + string expression; + if (conditional) { + expression = "["; + for (idx_t world = 0; world < 64; world++) { + if (world) { + expression += ","; + } + if (world < first_world || world >= first_world + world_count) { + expression += "NULL"; + } else { + expression += operation + "(v) FILTER (WHERE (m & " + std::to_string(uint64_t(1) << world) + + "::UBIGINT) <> 0)"; + } + } + expression += "]"; + } else if (operation == "stddev_samp") { + expression = "as_stddev_samp(m, v)"; + } else if (operation == "count") { + expression = "list_transform(as_count(m, v), lambda x: x / 2.0)"; + } else { + auto aggregate = operation == "avg" ? "sum" : operation; + auto value = operation == "avg" ? "x[1] / x[2]" : operation == "sum" ? "x[1] / 2.0" : "x[1]"; + // MIN/MAX dispatch on their SQL input type during binding, including macro definition. + auto argument = operation == "min" || operation == "max" ? "CAST(v AS DOUBLE)" : "v"; + expression = "list_transform(list_zip(as_" + string(aggregate) + "(m, " + argument + + "), as_count(m, v)), lambda x: CASE WHEN x[2] = 0 THEN NULL ELSE " + value + " END)"; + } + Query(con, "CREATE OR REPLACE TEMP MACRO tpcds_" + operation + "(m, v) AS " + expression); + } +} + +static WorldRows CollectHandwritten(QueryResult &result) { + WorldRows rows(64); + for (idx_t r = 0; r < result.RowCount(); r++) { + auto world = result.Collection().GetValue(0, r).GetValue(); + if (world < 0 || world >= 64) { + throw std::runtime_error("Invalid handwritten world index"); + } + vector row; + for (idx_t col = 1; col < result.ColumnCount(); col++) { + row.push_back(result.Collection().GetValue(col, r)); + } + rows[world].push_back(std::move(row)); + } + return rows; +} + +static void InstallSampledViews(Connection &con) { + Query(con, "SET VARIABLE tpcds_world=0"); + Query(con, "CREATE SCHEMA IF NOT EXISTS tpcds_sampled"); + Query(con, "CREATE OR REPLACE VIEW tpcds_sampled.customer AS SELECT * FROM main.customer " + "WHERE ((priv_hash(hash(c_customer_sk)) >> getvariable('tpcds_world')) & 1) <> 0"); + for (const auto &owner : vector> {{"store_sales", "ss_customer_sk"}, + {"store_returns", "sr_customer_sk"}, + {"catalog_sales", "cs_bill_customer_sk"}, + {"catalog_returns", "cr_returning_customer_sk"}, + {"web_sales", "ws_bill_customer_sk"}, + {"web_returns", "wr_returning_customer_sk"}}) { + Query(con, "CREATE OR REPLACE VIEW tpcds_sampled." + owner.first + " AS SELECT * FROM main." + owner.first + + " WHERE " + owner.second + " IN (SELECT c_customer_sk FROM tpcds_sampled.customer)"); + } +} + +struct ValidationComparison { + idx_t rows = 0; + idx_t values = 0; + idx_t exact_mismatches = 0; + idx_t float_mismatches = 0; + idx_t empty_worlds = 0; + double max_absolute_error = 0; + double max_relative_error = 0; +}; + +// SQL ORDER BY may leave ties unresolved. Compare result multisets, retaining the SQL's per-world LIMIT. +static vector CanonicalRowOrder(const vector> &rows, const vector &keys) { + vector order; + vector labels; + for (idx_t row = 0; row < rows.size(); row++) { + order.push_back(row); + string key; + for (idx_t col = 0; col < keys.size(); col++) { + if (keys[col]) { + auto value = rows[row][col].IsNull() ? string("NULL") : rows[row][col].ToString(); + key += std::to_string(value.size()) + ":" + value; + } + } + labels.push_back(std::move(key)); + } + std::sort(order.begin(), order.end(), [&](idx_t a, idx_t b) { + if (labels[a] != labels[b]) { + return labels[a] < labels[b]; + } + for (idx_t col = 0; col < keys.size(); col++) { + if (keys[col]) { + continue; + } + auto &x = rows[a][col]; + auto &y = rows[b][col]; + if (x.IsNull() != y.IsNull()) { + return x.IsNull(); + } + if (!x.IsNull()) { + auto xv = x.GetValue(), yv = y.GetValue(); + if (std::isnan(xv) != std::isnan(yv)) { + return std::isnan(xv); + } + if (xv != yv && !(std::isnan(xv) && std::isnan(yv))) { + return xv < yv; + } + } + } + return false; + }); + return order; +} + +static ValidationComparison CompareWorldRows(const WorldRows &expected, const WorldRows &actual, idx_t world_count = 64, + bool integral_keys = true) { + ValidationComparison comparison; + for (idx_t world = 0; world < world_count; world++) { + if (expected[world].size() != actual[world].size()) { + throw std::runtime_error("World " + std::to_string(world) + " row count: expected " + + std::to_string(expected[world].size()) + ", got " + + std::to_string(actual[world].size())); + } + comparison.empty_worlds += expected[world].empty(); + comparison.rows += expected[world].size(); + if (expected[world].empty()) { + continue; + } + if (expected[world][0].size() != actual[world][0].size()) { + throw std::runtime_error("Handwritten output column count differs"); + } + vector keys; + for (idx_t col = 0; col < expected[world][0].size(); col++) { + auto &e = expected[world][0][col].type(); + auto &a = actual[world][0][col].type(); + keys.push_back( + !e.IsNumeric() || !a.IsNumeric() || + (integral_keys && e == a && e.id() != LogicalTypeId::DOUBLE && e.id() != LogicalTypeId::FLOAT)); + } + auto eo = CanonicalRowOrder(expected[world], keys); + auto ao = CanonicalRowOrder(actual[world], keys); + for (idx_t row = 0; row < expected[world].size(); row++) { + if (expected[world][eo[row]].size() != actual[world][ao[row]].size()) { + throw std::runtime_error("Handwritten output column count differs"); + } + for (idx_t col = 0; col < expected[world][row].size(); col++) { + auto &e = expected[world][eo[row]][col]; + auto &a = actual[world][ao[row]][col]; + auto location = "world=" + std::to_string(world) + ", row=" + std::to_string(row) + + ", column=" + std::to_string(col); + if (e.IsNull() != a.IsNull()) { + throw std::runtime_error("NULL mismatch: " + location); + } + if (e.IsNull()) { + continue; + } + if (!e.type().IsNumeric() || !a.type().IsNumeric()) { + if (e.ToString() != a.ToString()) { + throw std::runtime_error("Value/order mismatch: " + location); + } + continue; + } + double x = e.GetValue(), y = a.GetValue(); + if (x == y || (std::isnan(x) && std::isnan(y))) { + comparison.values++; + continue; + } + if (!std::isfinite(x) || !std::isfinite(y)) { + throw std::runtime_error("Non-finite value mismatch: " + location); + } + comparison.exact_mismatches++; + comparison.float_mismatches += static_cast(x) != static_cast(y); + comparison.values++; + auto error = std::abs(x - y); + comparison.max_absolute_error = std::max(comparison.max_absolute_error, error); + comparison.max_relative_error = + std::max(comparison.max_relative_error, error / std::max(1.0, std::abs(x))); + } + } + } + return comparison; +} + +static void ValidateHandwritten(Connection &con, const JsonValue &config, int id) { + auto name = Name(id); + auto output = JsonString(config, "out_dir"); + auto directory = JsonString(config, "reference_queries_dir", "benchmark/tpcds/reference_queries"); + auto handwritten = Read(directory + "/" + name + ".sql"); + auto original = Read(JsonString(config, "queries_dir") + "/" + name + ".sql"); + Query(con, "SET priv_rewrite=false"); + InstallSampledViews(con); + Query(con, "SET search_path='tpcds_sampled,main'"); + WorldRows expected(64); + for (idx_t world = 0; world < 64; world++) { + Query(con, "SET VARIABLE tpcds_world=" + std::to_string(world)); + auto result = Query(con, original); + for (idx_t row = 0; row < result->RowCount(); row++) { + vector values; + for (idx_t col = 0; col < result->ColumnCount(); col++) { + values.push_back(result->Collection().GetValue(col, row)); + } + expected[world].push_back(std::move(values)); + } + } + std::ofstream csv(output + "/" + name + "_validation.csv"); + csv << "query,method,status,worlds,rows,numeric_values,exact_mismatches,float_rounded_mismatches," + "max_absolute_error,max_relative_error,empty_worlds,error\n"; + for (bool conditional : {true, false}) { + auto method = conditional ? "conditional_sql" : "simd_asa_handwritten"; + try { + WorldRows actual(64); + // Bound the ordinary conditional oracle's state size; this is validation, not timing. + auto block_size = conditional ? idx_t(8) : idx_t(64); + for (idx_t first = 0; first < 64; first += block_size) { + SetHandwrittenAggregates(con, conditional, first, block_size); + auto result = Query(con, handwritten); + auto block = CollectHandwritten(*result); + for (idx_t world = first; world < first + block_size; world++) { + actual[world] = std::move(block[world]); + } + } + auto comparison = CompareWorldRows(expected, actual); + auto status = comparison.exact_mismatches ? "numeric_difference" + : comparison.empty_worlds == 64 ? "empty_only" + : "exact_match"; + csv << name << ',' << method << ',' << status << ",64," << comparison.rows << ',' << comparison.values + << ',' << comparison.exact_mismatches << ',' << comparison.float_mismatches << ',' + << std::setprecision(17) << comparison.max_absolute_error << ',' << comparison.max_relative_error << ',' + << comparison.empty_worlds << ",\"\"\n"; + } catch (const std::exception &error) { + csv << name << ',' << method << ",error,64,,,,,,,," << Csv(error.what()) << '\n'; + } + csv.flush(); + } + Query(con, "SET search_path='main'"); + Query(con, "DROP SCHEMA tpcds_sampled CASCADE"); +} + +// TPC-H-style equivalence check: original SQL through the compiler versus explicit PAC SQL. +static void ValidatePacQuery(Connection &con, const JsonValue &config, int id) { + auto name = Name(id); + auto output = JsonString(config, "out_dir"); + auto original = Read(JsonString(config, "queries_dir") + "/" + name + ".sql"); + auto handwritten = Read(JsonString(config, "as_queries_dir", "benchmark/tpcds/as_queries") + "/" + name + ".sql"); + std::ofstream csv(output + "/" + name + "_pac_validation.csv"); + csv << "query,status,compiled_rows,handwritten_rows,numeric_values,exact_mismatches,float_rounded_mismatches," + "max_absolute_error,max_relative_error,error\n"; + idx_t compiled_rows = 0, handwritten_rows = 0; + try { + WorldRows expected(64), actual(64); + for (bool automatic : {true, false}) { + Query(con, "SET priv_rewrite=" + string(automatic ? "true" : "false")); + auto &sql = automatic ? original : handwritten; + auto plan = Query(con, "EXPLAIN " + sql); + std::ofstream plan_file(output + "/" + name + (automatic ? "_compiled.plan.txt" : "_handwritten.plan.txt")); + for (idx_t row = 0; row < plan->RowCount(); row++) { + plan_file << plan->Collection().GetValue(1, row).ToString() << '\n'; + } + auto result = Query(con, sql); + if (automatic) { + compiled_rows = result->RowCount(); + } else { + handwritten_rows = result->RowCount(); + } + auto &rows = automatic ? expected[0] : actual[0]; + for (idx_t row = 0; row < result->RowCount(); row++) { + vector values; + for (idx_t col = 0; col < result->ColumnCount(); col++) { + values.push_back(result->Collection().GetValue(col, row)); + } + rows.push_back(std::move(values)); + } + } + auto comparison = CompareWorldRows(expected, actual, 1, false); + auto status = comparison.exact_mismatches ? "numeric_difference" + : comparison.empty_worlds ? "empty_only" + : "exact_match"; + csv << name << ',' << status << ',' << compiled_rows << ',' << handwritten_rows << ',' << comparison.values + << ',' << comparison.exact_mismatches << ',' << comparison.float_mismatches << ',' << std::setprecision(17) + << comparison.max_absolute_error << ',' << comparison.max_relative_error << ",\"\"\n"; + } catch (const std::exception &error) { + csv << name << ",error," << compiled_rows << ',' << handwritten_rows << ",,,,,," << Csv(error.what()) << '\n'; + } + Query(con, "SET priv_rewrite=false"); +} + +// Output-semantics diagnostic only: ordinary world-zero SQL is not an equivalence oracle for PAC output. +// With mi=0, scalar terminals select lane 0, but PAC terminal filters may use majority decisions and SUM/COUNT +// retain their scaling. Differences recorded here must not be interpreted as compiler-correctness failures. +static void ValidateCompiled(Connection &con, const JsonValue &config, int id) { + auto name = Name(id); + auto output = JsonString(config, "out_dir"); + auto original = Read(JsonString(config, "queries_dir") + "/" + name + ".sql"); + Query(con, "SET priv_rewrite=false"); + InstallSampledViews(con); + Query(con, "SET search_path='tpcds_sampled,main'"); + auto reference = Query(con, original); + WorldRows expected(64), actual(64); + for (idx_t row = 0; row < reference->RowCount(); row++) { + vector values; + for (idx_t col = 0; col < reference->ColumnCount(); col++) { + values.push_back(reference->Collection().GetValue(col, row)); + } + expected[0].push_back(std::move(values)); + } + Query(con, "SET search_path='main'; SET priv_rewrite=true"); + std::ofstream csv(output + "/" + name + "_compiled_validation.csv"); + csv << "query,status,reference_world,reference_rows,compiled_rows,numeric_values,exact_mismatches," + "float_rounded_mismatches,max_absolute_error,max_relative_error,error\n"; + idx_t compiled_rows = 0; + bool executed = false; + try { + auto explain = Query(con, "EXPLAIN " + original); + std::ofstream plan(output + "/" + name + "_compiled_validation.plan.txt"); + for (idx_t row = 0; row < explain->RowCount(); row++) { + plan << explain->Collection().GetValue(1, row).ToString() << '\n'; + } + auto compiled = Query(con, original); + compiled_rows = compiled->RowCount(); + executed = true; + for (idx_t row = 0; row < compiled_rows; row++) { + vector values; + for (idx_t col = 0; col < compiled->ColumnCount(); col++) { + values.push_back(compiled->Collection().GetValue(col, row)); + } + actual[0].push_back(std::move(values)); + } + auto comparison = CompareWorldRows(expected, actual, 1, false); + auto status = comparison.exact_mismatches ? "numeric_difference" + : comparison.empty_worlds ? "empty_only" + : "exact_match"; + csv << name << ',' << status << ",0," << reference->RowCount() << ',' << compiled_rows << ',' + << comparison.values << ',' << comparison.exact_mismatches << ',' << comparison.float_mismatches << ',' + << std::setprecision(17) << comparison.max_absolute_error << ',' << comparison.max_relative_error + << ",\"\"\n"; + } catch (const std::exception &error) { + csv << name << (executed ? ",result_mismatch,0," : ",execution_error,0,") << reference->RowCount() << ',' + << compiled_rows << ",,,,,," << Csv(error.what()) << '\n'; + } + Query(con, "SET priv_rewrite=false; SET search_path='main'"); + Query(con, "DROP SCHEMA tpcds_sampled CASCADE"); +} + int main(int argc, char **argv) { try { - if (argc != 3) { - throw std::runtime_error("Usage: as_tpcds_benchmark CONFIG --prepare|QUERY_NUMBER"); + if (argc != 3 && !(argc == 4 && (string(argv[3]) == "--validate" || string(argv[3]) == "--validate-worlds" || + string(argv[3]) == "--validate-compiled"))) { + throw std::runtime_error("Usage: as_tpcds_benchmark CONFIG --prepare|QUERY_NUMBER " + "[--validate|--validate-worlds|--validate-compiled]"); } auto config = JsonParser(Read(argv[1])).Parse(); auto db_path = JsonString(config, "db"); @@ -77,7 +434,7 @@ int main(int argc, char **argv) { Query(con, "SET memory_limit=" + Quote(JsonString(config, "memory_limit", "4GB"))); // privacy_noise=false bypasses PAC compilation; mi=0 disables additive noise without bypassing it. Query(con, "SET priv_rewrite=false; SET pac_mi=0; SET privacy_noise=true; SET privacy_seed=42; " - "SET pac_sample_diversity_check=false; SET pac_conservative_mode=true;"); + "SET pac_sample_diversity_check=false; SET pac_conservative_mode=true; SET priv_check=false;"); if (string(argv[2]) == "--prepare") { auto extension_dir = JsonString(config, "extension_directory"); if (!extension_dir.empty()) { @@ -124,7 +481,7 @@ int main(int argc, char **argv) { metadata << "SUM: approximate\n"; #endif metadata << "Settings: m=64, privacy_seed=42, pac_mi=0, privacy_noise=true, " - "pac_sample_diversity_check=false, pac_conservative_mode=true\n"; + "pac_sample_diversity_check=false, pac_conservative_mode=true, priv_check=false\n"; Query(con, "CHECKPOINT"); return 0; } @@ -144,17 +501,49 @@ int main(int argc, char **argv) { Query(con, declaration); } } + if (argc == 4) { + if (string(argv[3]) == "--validate-compiled") { + ValidateCompiled(con, config, id); + return 0; + } + if (string(argv[3]) == "--validate-worlds") { + ValidateHandwritten(con, config, id); + } else { + ValidatePacQuery(con, config, id); + } + return 0; + } std::ofstream csv(output + "/" + name + ".csv"); if (!csv) { throw std::runtime_error("Cannot create result CSV"); } - csv << "query,mode,phase,status,rewritten,repetition,runtime_ms,rows,error\n"; - for (auto mode : {string("duckdb"), string("simd_asa_auto")}) { - Query(con, "SET priv_rewrite=" + string(mode == "duckdb" ? "false" : "true")); + csv << "query,mode,phase,status,rewritten,repetition,runtime_ms,rows,world_multiplier,error\n"; + for (auto mode : + {string("duckdb"), string("simd_asa_handwritten"), string("simd_asa_auto"), string("naive_as")}) { + Query(con, "SET priv_rewrite=" + string(mode == "simd_asa_auto" ? "true" : "false")); + string query_sql = sql; + if (mode == "simd_asa_handwritten") { + auto path = JsonString(config, "as_queries_dir", "benchmark/tpcds/as_queries") + "/" + name + ".sql"; + std::ifstream handwritten(path); + if (!handwritten) { + csv << name << ',' << mode << ",setup,not_available,0,0,,,,\"\"\n"; + continue; + } + query_sql = Read(path); + } + auto multiplier = mode == "naive_as" ? 64 : 1; bool rewritten = false; string phase = "explain"; try { - auto explain = Query(con, "EXPLAIN " + sql); + if (mode == "naive_as") { + // Match TPC-H: prepare once outside timing, time one sampled-world execution, + // and multiply by 64. Views apply customer sampling at query time to every fact scan. + InstallSampledViews(con); + Query(con, "SET search_path='tpcds_sampled,main'"); + Query(con, "PREPARE tpcds_naive AS " + sql); + query_sql = "EXECUTE tpcds_naive"; + } + auto explain = Query(con, "EXPLAIN " + query_sql); string plan; for (idx_t row = 0; row < explain->RowCount(); row++) { plan += explain->Collection().GetValue(1, row).ToString() + "\n"; @@ -163,27 +552,32 @@ int main(int argc, char **argv) { plan_file << plan; rewritten = plan.find("as_noised_") != string::npos || plan.find("as_sum(") != string::npos || plan.find("as_count(") != string::npos || plan.find("priv_select") != string::npos; - if (mode != "duckdb" && !rewritten) { - csv << name << ',' << mode << ",explain,no_stochastic_operator,0,0,,,\"\"\n"; + if ((mode == "simd_asa_auto" || mode == "simd_asa_handwritten") && !rewritten) { + csv << name << ',' << mode << ",explain,no_stochastic_operator,0,0,,,,\"\"\n"; csv.flush(); continue; } phase = "warmup"; - Query(con, sql); + Query(con, query_sql); phase = "measure"; for (int run = 1; run <= repetitions; run++) { auto start = std::chrono::steady_clock::now(); - auto result = Query(con, sql); + auto result = Query(con, query_sql); auto elapsed = std::chrono::duration(std::chrono::steady_clock::now() - start); csv << name << ',' << mode << ",measure,ok," << rewritten << ',' << run << ',' - << std::setprecision(12) << elapsed.count() << ',' << result->RowCount() << ",\"\"\n"; + << std::setprecision(12) << elapsed.count() * multiplier << ',' << result->RowCount() << ',' + << multiplier << ",\"\"\n"; csv.flush(); } } catch (const std::exception &error) { - csv << name << ',' << mode << ',' << phase << ",error," << rewritten << ",0,,," << Csv(error.what()) + csv << name << ',' << mode << ',' << phase << ",error," << rewritten << ",0,,,," << Csv(error.what()) << '\n'; csv.flush(); } + if (mode == "naive_as") { + Query(con, "SET search_path='main'"); + Query(con, "DROP SCHEMA IF EXISTS tpcds_sampled CASCADE"); + } } return 0; } catch (const std::exception &error) { diff --git a/benchmark/tpcds/q17_fixture.sql b/benchmark/tpcds/q17_fixture.sql new file mode 100644 index 00000000..2beeac68 --- /dev/null +++ b/benchmark/tpcds/q17_fixture.sql @@ -0,0 +1,22 @@ +-- Synthetic nonempty correctness fixture for the unchanged TPC-DS Q17 SQL, not a performance dataset. +-- Run against a fresh database. Empty owned tables allow the standard ownership setup to be reused. +SET priv_rewrite=false; +CREATE TABLE customer AS SELECT i::INTEGER AS c_customer_sk FROM range(128) r(i); +CREATE TABLE store_sales AS +SELECT c_customer_sk AS ss_customer_sk, 1 AS ss_item_sk, c_customer_sk AS ss_ticket_number, + 1 AS ss_sold_date_sk, 1 AS ss_store_sk, c_customer_sk % 10 + 1 AS ss_quantity +FROM customer; +CREATE TABLE store_returns AS +SELECT c_customer_sk AS sr_customer_sk, 1 AS sr_item_sk, c_customer_sk AS sr_ticket_number, + 1 AS sr_returned_date_sk, c_customer_sk % 4 + 1 AS sr_return_quantity +FROM customer; +CREATE TABLE catalog_sales AS +SELECT c_customer_sk AS cs_bill_customer_sk, 1 AS cs_item_sk, 1 AS cs_sold_date_sk, + c_customer_sk % 13 + 1 AS cs_quantity +FROM customer; +CREATE TABLE catalog_returns(cr_returning_customer_sk INTEGER); +CREATE TABLE web_sales(ws_bill_customer_sk INTEGER); +CREATE TABLE web_returns(wr_returning_customer_sk INTEGER); +CREATE TABLE date_dim AS SELECT 1 AS d_date_sk, '2001Q1' AS d_quarter_name; +CREATE TABLE store AS SELECT 1 AS s_store_sk, 'CA' AS s_state; +CREATE TABLE item AS SELECT 1 AS i_item_sk, 'ITEM1' AS i_item_id, 'test item' AS i_item_desc; diff --git a/benchmark/tpcds/reference_queries/q01.sql b/benchmark/tpcds/reference_queries/q01.sql new file mode 100644 index 00000000..5509f88e --- /dev/null +++ b/benchmark/tpcds/reference_queries/q01.sql @@ -0,0 +1,30 @@ +-- Correlated thresholds use only the matching world of the reduced return aggregates. +WITH return_stats AS ( +SELECT sr_customer_sk AS ctr_customer_sk, + sr_store_sk AS ctr_store_sk, + tpcds_sum(priv_hash(hash(sr_customer_sk)), sr_return_amt) AS ctr_total_return, + tpcds_count(priv_hash(hash(sr_customer_sk)),1) AS presence +FROM main.store_returns, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE sr_customer_sk=asa_owner.asa_key AND sr_returned_date_sk = d_date_sk + AND d_year = 2000 + GROUP BY sr_customer_sk, + sr_store_sk +), customer_total_return AS ( +SELECT world, ctr_customer_sk, ctr_store_sk, ctr_total_return[world+1] AS ctr_total_return +FROM return_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT ctr1.world AS world, c_customer_id +FROM customer_total_return ctr1, + main.store, + main.customer +WHERE ctr1.ctr_total_return > + (SELECT avg(ctr_total_return)*1.2 + FROM customer_total_return ctr2 + WHERE ctr1.world=ctr2.world AND ctr1.ctr_store_sk = ctr2.ctr_store_sk) + AND s_store_sk = ctr1.ctr_store_sk + AND s_state = 'TN' + AND ctr1.ctr_customer_sk = c_customer_sk +QUALIFY row_number() OVER (PARTITION BY ctr1.world ORDER BY c_customer_id) <= 100 +ORDER BY ctr1.world, c_customer_id; diff --git a/benchmark/tpcds/reference_queries/q03.sql b/benchmark/tpcds/reference_queries/q03.sql new file mode 100644 index 00000000..06c8dada --- /dev/null +++ b/benchmark/tpcds/reference_queries/q03.sql @@ -0,0 +1,30 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT dt.d_year AS d_year, + item.i_brand_id AS brand_id, + item.i_brand AS brand, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_ext_sales_price) AS sum_agg, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.date_dim dt, + main.store_sales, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND dt.d_date_sk = store_sales.ss_sold_date_sk + AND store_sales.ss_item_sk = item.i_item_sk + AND item.i_manufact_id = 128 + AND dt.d_moy=11 +GROUP BY dt.d_year, + main.item.i_brand, + main.item.i_brand_id +), answers AS ( + SELECT world, d_year, + brand_id, + brand, + sum_agg[world+1] AS sum_agg + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY d_year, sum_agg DESC, brand_id) <= 100 +ORDER BY world, d_year, sum_agg DESC, brand_id; diff --git a/benchmark/tpcds/reference_queries/q04.sql b/benchmark/tpcds/reference_queries/q04.sql new file mode 100644 index 00000000..935850d8 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q04.sql @@ -0,0 +1,135 @@ +-- Shared AS states per channel/customer/year; joins align the world index. +WITH year_total_stats AS ( +SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + tpcds_sum(priv_hash(hash(c_customer_sk)), ((ss_ext_list_price-ss_ext_wholesale_cost-ss_ext_discount_amt)+ss_ext_sales_price)/2) year_total, + 's' sale_type, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.customer, + main.store_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year + +UNION ALL + SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + tpcds_sum(priv_hash(hash(c_customer_sk)), (((cs_ext_list_price-cs_ext_wholesale_cost-cs_ext_discount_amt)+cs_ext_sales_price)/2)) year_total, + 'c' sale_type, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.customer, + main.catalog_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND c_customer_sk = cs_bill_customer_sk + AND cs_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year + +UNION ALL + SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + tpcds_sum(priv_hash(hash(c_customer_sk)), (((ws_ext_list_price-ws_ext_wholesale_cost-ws_ext_discount_amt)+ws_ext_sales_price)/2)) year_total, + 'w' sale_type, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.customer, + main.web_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year +), year_total AS ( +SELECT world, customer_id, customer_first_name, customer_last_name, customer_preferred_cust_flag, customer_birth_country, customer_login, customer_email_address, dyear, year_total[world+1] AS year_total, sale_type +FROM year_total_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT t_s_firstyear.world AS world, t_s_secyear.customer_id, + t_s_secyear.customer_first_name, + t_s_secyear.customer_last_name, + t_s_secyear.customer_preferred_cust_flag +FROM year_total t_s_firstyear, + year_total t_s_secyear, + year_total t_c_firstyear, + year_total t_c_secyear, + year_total t_w_firstyear, + year_total t_w_secyear +WHERE t_s_firstyear.world=t_s_secyear.world AND t_s_firstyear.world=t_c_firstyear.world AND t_s_firstyear.world=t_c_secyear.world AND t_s_firstyear.world=t_w_firstyear.world AND t_s_firstyear.world=t_w_secyear.world AND t_s_secyear.customer_id = t_s_firstyear.customer_id + AND t_s_firstyear.customer_id = t_c_secyear.customer_id + AND t_s_firstyear.customer_id = t_c_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_secyear.customer_id + AND t_s_firstyear.sale_type = 's' + AND t_c_firstyear.sale_type = 'c' + AND t_w_firstyear.sale_type = 'w' + AND t_s_secyear.sale_type = 's' + AND t_c_secyear.sale_type = 'c' + AND t_w_secyear.sale_type = 'w' + AND t_s_firstyear.dyear = 2001 + AND t_s_secyear.dyear = 2001+1 + AND t_c_firstyear.dyear = 2001 + AND t_c_secyear.dyear = 2001+1 + AND t_w_firstyear.dyear = 2001 + AND t_w_secyear.dyear = 2001+1 + AND t_s_firstyear.year_total > 0 + AND t_c_firstyear.year_total > 0 + AND t_w_firstyear.year_total > 0 + AND CASE + WHEN t_c_firstyear.year_total > 0 THEN t_c_secyear.year_total / t_c_firstyear.year_total + ELSE NULL + END > CASE + WHEN t_s_firstyear.year_total > 0 THEN t_s_secyear.year_total / t_s_firstyear.year_total + ELSE NULL + END + AND CASE + WHEN t_c_firstyear.year_total > 0 THEN t_c_secyear.year_total / t_c_firstyear.year_total + ELSE NULL + END > CASE + WHEN t_w_firstyear.year_total > 0 THEN t_w_secyear.year_total / t_w_firstyear.year_total + ELSE NULL + END +QUALIFY row_number() OVER (PARTITION BY t_s_firstyear.world ORDER BY t_s_secyear.customer_id NULLS FIRST, + t_s_secyear.customer_first_name NULLS FIRST, + t_s_secyear.customer_last_name NULLS FIRST, + t_s_secyear.customer_preferred_cust_flag NULLS FIRST) <= 100 +ORDER BY t_s_firstyear.world, t_s_secyear.customer_id NULLS FIRST, + t_s_secyear.customer_first_name NULLS FIRST, + t_s_secyear.customer_last_name NULLS FIRST, + t_s_secyear.customer_preferred_cust_flag NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q06.sql b/benchmark/tpcds/reference_queries/q06.sql new file mode 100644 index 00000000..25dfcac0 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q06.sql @@ -0,0 +1,36 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT a.ca_state AS state, + tpcds_count((priv_hash(hash(s.ss_customer_sk))), 1) AS cnt, + tpcds_count((priv_hash(hash(s.ss_customer_sk))), 1) AS presence + FROM main.customer_address a , + main.customer c , + main.store_sales s , + main.date_dim d , + main.item i, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE s.ss_customer_sk = asa_owner0.asa_key0 + AND a.ca_address_sk = c.c_current_addr_sk + AND c.c_customer_sk = s.ss_customer_sk + AND s.ss_sold_date_sk = d.d_date_sk + AND s.ss_item_sk = i.i_item_sk + AND d.d_month_seq = + (SELECT DISTINCT (d_month_seq) + FROM main.date_dim + WHERE d_year = 2001 + AND d_moy = 1 ) + AND i.i_current_price > 1.2 * + (SELECT avg(j.i_current_price) + FROM main.item j + WHERE j.i_category = i.i_category) +GROUP BY a.ca_state +), answers AS ( + SELECT world, state, + cnt[world+1] AS cnt + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +WHERE cnt >= 10 +QUALIFY row_number() OVER (PARTITION BY world ORDER BY cnt NULLS FIRST, state NULLS FIRST) <= 100 +ORDER BY world, cnt NULLS FIRST, state NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q07.sql b/benchmark/tpcds/reference_queries/q07.sql new file mode 100644 index 00000000..43f73f96 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q07.sql @@ -0,0 +1,38 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_item_id, + tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_quantity) AS agg1, + tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_list_price) AS agg2, + tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_coupon_amt) AS agg3, + tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_sales_price) AS agg4, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales, + main.customer_demographics, + main.date_dim, + main.item, + main.promotion, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND ss_sold_date_sk = d_date_sk + AND ss_item_sk = i_item_sk + AND ss_cdemo_sk = cd_demo_sk + AND ss_promo_sk = p_promo_sk + AND cd_gender = 'M' + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND (p_channel_email = 'N' + OR p_channel_event = 'N') + AND d_year = 2000 +GROUP BY i_item_id +), answers AS ( + SELECT world, i_item_id, + agg1[world+1] AS agg1, + agg2[world+1] AS agg2, + agg3[world+1] AS agg3, + agg4[world+1] AS agg4 + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY i_item_id) <= 100 +ORDER BY world, i_item_id; diff --git a/benchmark/tpcds/reference_queries/q09.sql b/benchmark/tpcds/reference_queries/q09.sql new file mode 100644 index 00000000..3cb2df1b --- /dev/null +++ b/benchmark/tpcds/reference_queries/q09.sql @@ -0,0 +1,17 @@ +-- Each CASE selects between its world-specific aggregate results. +WITH stats AS (SELECT tpcds_count(CASE WHEN ss_quantity BETWEEN 1 AND 20 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS n1, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 1 AND 20 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_ext_discount_amt) AS discount1, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 1 AND 20 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_net_paid) AS paid1, +tpcds_count(CASE WHEN ss_quantity BETWEEN 21 AND 40 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS n2, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 21 AND 40 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_ext_discount_amt) AS discount2, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 21 AND 40 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_net_paid) AS paid2, +tpcds_count(CASE WHEN ss_quantity BETWEEN 41 AND 60 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS n3, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 41 AND 60 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_ext_discount_amt) AS discount3, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 41 AND 60 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_net_paid) AS paid3, +tpcds_count(CASE WHEN ss_quantity BETWEEN 61 AND 80 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS n4, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 61 AND 80 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_ext_discount_amt) AS discount4, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 61 AND 80 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_net_paid) AS paid4, +tpcds_count(CASE WHEN ss_quantity BETWEEN 81 AND 100 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS n5, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 81 AND 100 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_ext_discount_amt) AS discount5, +tpcds_avg(CASE WHEN ss_quantity BETWEEN 81 AND 100 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,ss_net_paid) AS paid5 FROM main.store_sales JOIN main.customer ON ss_customer_sk=c_customer_sk) +SELECT world, CASE WHEN n1[world+1]>74129 THEN discount1[world+1] ELSE paid1[world+1] END AS bucket1, CASE WHEN n2[world+1]>122840 THEN discount2[world+1] ELSE paid2[world+1] END AS bucket2, CASE WHEN n3[world+1]>56580 THEN discount3[world+1] ELSE paid3[world+1] END AS bucket3, CASE WHEN n4[world+1]>10097 THEN discount4[world+1] ELSE paid4[world+1] END AS bucket4, CASE WHEN n5[world+1]>165306 THEN discount5[world+1] ELSE paid5[world+1] END AS bucket5 FROM stats CROSS JOIN range(64) worlds(world) CROSS JOIN main.reason WHERE r_reason_sk=1 ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q10.sql b/benchmark/tpcds/reference_queries/q10.sql new file mode 100644 index 00000000..710638ad --- /dev/null +++ b/benchmark/tpcds/reference_queries/q10.sql @@ -0,0 +1,59 @@ +-- Same-owner EXISTS is static after entity inclusion; shipping-customer EXISTS needs the bill-owner mask. +WITH catalog_presence AS ( +SELECT cs_ship_customer_sk,bit_or(priv_hash(hash(cs_bill_customer_sk))) AS membership + FROM main.catalog_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND cs_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_moy BETWEEN 1 AND 1+3 +GROUP BY cs_ship_customer_sk +), stats AS (SELECT cd_gender, +cd_marital_status, +cd_education_status, +cd_purchase_estimate, +cd_credit_rating, +cd_dep_count, +cd_dep_employed_count, +cd_dep_college_count, +tpcds_count((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_moy BETWEEN 1 AND 1+3) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),1) AS n +FROM main.customer c CROSS JOIN + main.customer_address ca CROSS JOIN + main.customer_demographics LEFT JOIN catalog_presence ON c.c_customer_sk=cs_ship_customer_sk +WHERE c.c_current_addr_sk = ca.ca_address_sk + AND ca_county IN ('Rush County', + 'Toole County', + 'Jefferson County', + 'Dona Ana County', + 'La Porte County') + AND cd_demo_sk = c.c_current_cdemo_sk + +AND EXISTS(SELECT * + FROM main.store_sales, + main.date_dim + WHERE c.c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_moy BETWEEN 1 AND 1+3) +GROUP BY cd_gender, cd_marital_status, cd_education_status, cd_purchase_estimate, cd_credit_rating, cd_dep_count, cd_dep_employed_count, cd_dep_college_count +), answers AS (SELECT world, cd_gender, cd_marital_status, cd_education_status, n[world+1] AS cnt1, cd_purchase_estimate, n[world+1] AS cnt2, cd_credit_rating, n[world+1] AS cnt3, cd_dep_count, n[world+1] AS cnt4, cd_dep_employed_count, n[world+1] AS cnt5, cd_dep_college_count, n[world+1] AS cnt6 FROM stats CROSS JOIN range(64) worlds(world) WHERE n[world+1]>0) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating, + cd_dep_count, + cd_dep_employed_count, + cd_dep_college_count)<=100 ORDER BY world,cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating, + cd_dep_count, + cd_dep_employed_count, + cd_dep_college_count; diff --git a/benchmark/tpcds/reference_queries/q11.sql b/benchmark/tpcds/reference_queries/q11.sql new file mode 100644 index 00000000..6c447759 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q11.sql @@ -0,0 +1,93 @@ +-- Shared AS states per channel/customer/year; joins align the world index. +WITH year_total_stats AS ( +SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + tpcds_sum(priv_hash(hash(c_customer_sk)), ss_ext_list_price-ss_ext_discount_amt) year_total, + 's' sale_type, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.customer, + main.store_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year + +UNION ALL + SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + c_preferred_cust_flag customer_preferred_cust_flag, + c_birth_country customer_birth_country, + c_login customer_login, + c_email_address customer_email_address, + d_year dyear, + tpcds_sum(priv_hash(hash(c_customer_sk)), ws_ext_list_price-ws_ext_discount_amt) year_total, + 'w' sale_type, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.customer, + main.web_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + GROUP BY c_customer_id, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_country, + c_login, + c_email_address, + d_year +), year_total AS ( +SELECT world, customer_id, customer_first_name, customer_last_name, customer_preferred_cust_flag, customer_birth_country, customer_login, customer_email_address, dyear, year_total[world+1] AS year_total, sale_type +FROM year_total_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT t_s_firstyear.world AS world, t_s_secyear.customer_id, + t_s_secyear.customer_first_name, + t_s_secyear.customer_last_name, + t_s_secyear.customer_preferred_cust_flag +FROM year_total t_s_firstyear, + year_total t_s_secyear, + year_total t_w_firstyear, + year_total t_w_secyear +WHERE t_s_firstyear.world=t_s_secyear.world AND t_s_firstyear.world=t_w_firstyear.world AND t_s_firstyear.world=t_w_secyear.world AND t_s_secyear.customer_id = t_s_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_secyear.customer_id + AND t_s_firstyear.customer_id = t_w_firstyear.customer_id + AND t_s_firstyear.sale_type = 's' + AND t_w_firstyear.sale_type = 'w' + AND t_s_secyear.sale_type = 's' + AND t_w_secyear.sale_type = 'w' + AND t_s_firstyear.dyear = 2001 + AND t_s_secyear.dyear = 2001+1 + AND t_w_firstyear.dyear = 2001 + AND t_w_secyear.dyear = 2001+1 + AND t_s_firstyear.year_total > 0 + AND t_w_firstyear.year_total > 0 + AND CASE + WHEN t_w_firstyear.year_total > 0 THEN (t_w_secyear.year_total*1.0000) / t_w_firstyear.year_total + ELSE 0.0 + END > CASE + WHEN t_s_firstyear.year_total > 0 THEN (t_s_secyear.year_total*1.0000) / t_s_firstyear.year_total + ELSE 0.0 + END +QUALIFY row_number() OVER (PARTITION BY t_s_firstyear.world ORDER BY t_s_secyear.customer_id NULLS FIRST, + t_s_secyear.customer_first_name NULLS FIRST, + t_s_secyear.customer_last_name NULLS FIRST, + t_s_secyear.customer_preferred_cust_flag NULLS FIRST) <= 100 +ORDER BY t_s_firstyear.world, t_s_secyear.customer_id NULLS FIRST, + t_s_secyear.customer_first_name NULLS FIRST, + t_s_secyear.customer_last_name NULLS FIRST, + t_s_secyear.customer_preferred_cust_flag NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q13.sql b/benchmark/tpcds/reference_queries/q13.sql new file mode 100644 index 00000000..35325b68 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q13.sql @@ -0,0 +1,55 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_quantity) AS avg1, + tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_ext_sales_price) AS avg2, + tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_ext_wholesale_cost) AS avg3, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_ext_wholesale_cost) AS total, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales , + main.store , + main.customer_demographics , + main.household_demographics , + main.customer_address , + main.date_dim, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND s_store_sk = ss_store_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2001 and((ss_hdemo_sk=hd_demo_sk + AND cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'M' + AND cd_education_status = 'Advanced Degree' + AND ss_sales_price BETWEEN 100.00 AND 150.00 + AND hd_dep_count = 3) + OR (ss_hdemo_sk=hd_demo_sk + AND cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND ss_sales_price BETWEEN 50.00 AND 100.00 + AND hd_dep_count = 1 ) + OR (ss_hdemo_sk=hd_demo_sk + AND cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'W' + AND cd_education_status = '2 yr Degree' + AND ss_sales_price BETWEEN 150.00 AND 200.00 + AND hd_dep_count = 1)) and((ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('TX', 'OH', 'TX') + AND ss_net_profit BETWEEN 100 AND 200) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('OR', 'NM', 'KY') + AND ss_net_profit BETWEEN 150 AND 300) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('VA', 'TX', 'MS') + AND ss_net_profit BETWEEN 50 AND 250)) +), answers AS ( + SELECT world, avg1[world+1] AS avg1, + avg2[world+1] AS avg2, + avg3[world+1] AS avg3, + total[world+1] AS total + FROM stats CROSS JOIN range(64) worlds(world) +) +SELECT * FROM answers +ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q15.sql b/benchmark/tpcds/reference_queries/q15.sql new file mode 100644 index 00000000..07aa9526 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q15.sql @@ -0,0 +1,39 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT ca_zip, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk))), cs_sales_price) AS total, + tpcds_count((priv_hash(hash(cs_bill_customer_sk))), 1) AS presence + FROM main.catalog_sales, + main.customer, + main.customer_address, + main.date_dim, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE cs_bill_customer_sk = asa_owner0.asa_key0 + AND cs_bill_customer_sk = c_customer_sk + AND c_current_addr_sk = ca_address_sk + AND (SUBSTRING(ca_zip, 1, 5) IN ('85669', + '86197', + '88274', + '83405', + '86475', + '85392', + '85460', + '80348', + '81792') + OR ca_state IN ('CA', + 'WA', + 'GA') + OR cs_sales_price > 500) + AND cs_sold_date_sk = d_date_sk + AND d_qoy = 2 + AND d_year = 2001 +GROUP BY ca_zip +), answers AS ( + SELECT world, ca_zip, + total[world+1] AS total + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY ca_zip NULLS FIRST) <= 100 +ORDER BY world, ca_zip NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q16.sql b/benchmark/tpcds/reference_queries/q16.sql new file mode 100644 index 00000000..9d291fd6 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q16.sql @@ -0,0 +1,10 @@ +-- Order-level existence masks are combined before AS; DISTINCT unions memberships by order. +WITH warehouses AS (SELECT cs_order_number AS order_number,cs_warehouse_sk AS warehouse,bit_or(priv_hash(hash(cs_bill_customer_sk))) AS membership FROM main.catalog_sales JOIN main.customer ON cs_bill_customer_sk=c_customer_sk GROUP BY cs_order_number,cs_warehouse_sk), +other_warehouses AS (SELECT a.order_number,a.warehouse,bit_or(b.membership) AS membership FROM warehouses a JOIN warehouses b ON a.order_number=b.order_number AND a.warehouse<>b.warehouse GROUP BY a.order_number,a.warehouse), +return_orders AS (SELECT cr_order_number AS order_number,bit_or(priv_hash(hash(cr_returning_customer_sk))) AS membership FROM main.catalog_returns JOIN main.customer ON cr_returning_customer_sk=c_customer_sk GROUP BY cr_order_number), +input AS (SELECT cs_order_number AS order_number,cs_ext_ship_cost AS shipping,cs_net_profit AS profit,(priv_hash(hash(cs_bill_customer_sk)) & other.membership & ~coalesce(ret.membership,0::UBIGINT)) AS membership +FROM main.catalog_sales JOIN main.customer ON cs_bill_customer_sk=c_customer_sk JOIN main.date_dim ON cs_ship_date_sk=d_date_sk JOIN main.customer_address ON cs_ship_addr_sk=ca_address_sk JOIN main.call_center ON cs_call_center_sk=cc_call_center_sk JOIN other_warehouses other ON cs_order_number=other.order_number AND cs_warehouse_sk=other.warehouse LEFT JOIN return_orders ret ON cs_order_number=ret.order_number WHERE d_date BETWEEN DATE '2002-02-01' AND DATE '2002-04-02' AND ca_state='GA' AND cc_county='Williamson County'), +totals AS (SELECT tpcds_sum(membership,shipping) AS shipping,tpcds_sum(membership,profit) AS profit FROM input), +unique_orders AS (SELECT order_number,bit_or(membership) AS membership FROM input GROUP BY order_number), +counts AS (SELECT tpcds_count(membership,1) AS n FROM unique_orders) +SELECT world,n[world+1] AS order_count,shipping[world+1] AS total_shipping_cost,profit[world+1] AS total_net_profit FROM totals CROSS JOIN counts CROSS JOIN range(64) worlds(world) ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q17.sql b/benchmark/tpcds/reference_queries/q17.sql new file mode 100644 index 00000000..6910c700 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q17.sql @@ -0,0 +1,67 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_item_id, + i_item_desc, + s_state, + tpcds_count((priv_hash(hash(ss_customer_sk))), ss_quantity) AS v0_count, + tpcds_avg((priv_hash(hash(ss_customer_sk))), ss_quantity) AS v0_avg, + tpcds_stddev_samp((priv_hash(hash(ss_customer_sk))), ss_quantity) AS v0_stddev_samp, + tpcds_count((priv_hash(hash(ss_customer_sk))), sr_return_quantity) AS v1_count, + tpcds_avg((priv_hash(hash(ss_customer_sk))), sr_return_quantity) AS v1_avg, + tpcds_stddev_samp((priv_hash(hash(ss_customer_sk))), sr_return_quantity) AS v1_stddev_samp, + tpcds_count((priv_hash(hash(ss_customer_sk))), cs_quantity) AS v2_count, + tpcds_avg((priv_hash(hash(ss_customer_sk))), cs_quantity) AS v2_avg, + tpcds_stddev_samp((priv_hash(hash(ss_customer_sk))), cs_quantity) AS v2_stddev_samp, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales, + main.store_returns, + main.catalog_sales, + main.date_dim d1, + main.date_dim d2, + main.date_dim d3, + main.store, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND d1.d_quarter_name = '2001Q1' + AND d1.d_date_sk = ss_sold_date_sk + AND i_item_sk = ss_item_sk + AND s_store_sk = ss_store_sk + AND ss_customer_sk = sr_customer_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND sr_returned_date_sk = d2.d_date_sk + AND d2.d_quarter_name IN ('2001Q1', + '2001Q2', + '2001Q3') + AND sr_customer_sk = cs_bill_customer_sk + AND sr_item_sk = cs_item_sk + AND cs_sold_date_sk = d3.d_date_sk + AND d3.d_quarter_name IN ('2001Q1', + '2001Q2', + '2001Q3') +GROUP BY i_item_id, + i_item_desc, + s_state +), answers AS ( + SELECT world, i_item_id, + i_item_desc, + s_state, + v0_count[world+1] AS store_sales_quantitycount, + v0_avg[world+1] AS store_sales_quantityave, + v0_stddev_samp[world+1] AS store_sales_quantitystdev, + v0_stddev_samp[world+1]/v0_avg[world+1] AS store_sales_quantitycov, + v1_count[world+1] AS store_returns_quantitycount, + v1_avg[world+1] AS store_returns_quantityave, + v1_stddev_samp[world+1] AS store_returns_quantitystdev, + v1_stddev_samp[world+1]/v1_avg[world+1] AS store_returns_quantitycov, + v2_count[world+1] AS catalog_sales_quantitycount, + v2_avg[world+1] AS catalog_sales_quantityave, + v2_stddev_samp[world+1] AS catalog_sales_quantitystdev, + v2_stddev_samp[world+1]/v2_avg[world+1] AS catalog_sales_quantitycov + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY i_item_id NULLS FIRST, i_item_desc NULLS FIRST, s_state NULLS FIRST) <= 100 +ORDER BY world, i_item_id NULLS FIRST, i_item_desc NULLS FIRST, s_state NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q18.sql b/benchmark/tpcds/reference_queries/q18.sql new file mode 100644 index 00000000..d00e2c97 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q18.sql @@ -0,0 +1,68 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_item_id, + ca_country, + ca_state, + ca_county, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), CAST(cs_quantity AS DECIMAL(12,2))) AS agg1, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), CAST(cs_list_price AS DECIMAL(12,2))) AS agg2, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), CAST(cs_coupon_amt AS DECIMAL(12,2))) AS agg3, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), CAST(cs_sales_price AS DECIMAL(12,2))) AS agg4, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), CAST(cs_net_profit AS DECIMAL(12,2))) AS agg5, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), CAST(c_birth_year AS DECIMAL(12,2))) AS agg6, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), CAST(cd1.cd_dep_count AS DECIMAL(12,2))) AS agg7, + tpcds_count((priv_hash(hash(cs_bill_customer_sk))), 1) AS presence, + GROUPING(i_item_id, ca_country, ca_state, ca_county) AS grouping_level + FROM main.catalog_sales, + main.customer_demographics cd1, + main.customer_demographics cd2, + main.customer, + main.customer_address, + main.date_dim, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE cs_bill_customer_sk = asa_owner0.asa_key0 + AND cs_sold_date_sk = d_date_sk + AND cs_item_sk = i_item_sk + AND cs_bill_cdemo_sk = cd1.cd_demo_sk + AND cs_bill_customer_sk = c_customer_sk + AND cd1.cd_gender = 'F' + AND cd1.cd_education_status = 'Unknown' + AND c_current_cdemo_sk = cd2.cd_demo_sk + AND c_current_addr_sk = ca_address_sk + AND c_birth_month IN (1, + 6, + 8, + 9, + 12, + 2) + AND d_year = 1998 + AND ca_state IN ('MS', + 'IN', + 'ND', + 'OK', + 'NM', + 'VA', + 'MS') +GROUP BY ROLLUP (i_item_id, + ca_country, + ca_state, + ca_county) +), answers AS ( + SELECT world, i_item_id, + ca_country, + ca_state, + ca_county, + agg1[world+1] AS agg1, + agg2[world+1] AS agg2, + agg3[world+1] AS agg3, + agg4[world+1] AS agg4, + agg5[world+1] AS agg5, + agg6[world+1] AS agg6, + agg7[world+1] AS agg7 + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 OR grouping_level = 15 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY ca_country NULLS FIRST, ca_state NULLS FIRST, ca_county NULLS FIRST, i_item_id NULLS FIRST) <= 100 +ORDER BY world, ca_country NULLS FIRST, ca_state NULLS FIRST, ca_county NULLS FIRST, i_item_id NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q19.sql b/benchmark/tpcds/reference_queries/q19.sql new file mode 100644 index 00000000..beecad17 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q19.sql @@ -0,0 +1,41 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_brand_id AS brand_id, + i_brand AS brand, + i_manufact_id, + i_manufact, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_ext_sales_price) AS ext_price, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.date_dim, + main.store_sales, + main.item, + main.customer, + main.customer_address, + main.store, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND d_date_sk = ss_sold_date_sk + AND ss_item_sk = i_item_sk + AND i_manager_id=8 + AND d_moy=11 + AND d_year=1998 + AND ss_customer_sk = c_customer_sk + AND c_current_addr_sk = ca_address_sk + AND SUBSTRING(ca_zip, 1, 5) <> SUBSTRING(s_zip, 1, 5) + AND ss_store_sk = s_store_sk +GROUP BY i_brand, + i_brand_id, + i_manufact_id, + i_manufact +), answers AS ( + SELECT world, brand_id, + brand, + i_manufact_id, + i_manufact, + ext_price[world+1] AS ext_price + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY ext_price DESC, brand, brand_id, i_manufact_id, i_manufact) <= 100 +ORDER BY world, ext_price DESC, brand, brand_id, i_manufact_id, i_manufact; diff --git a/benchmark/tpcds/reference_queries/q23.sql b/benchmark/tpcds/reference_queries/q23.sql new file mode 100644 index 00000000..6eb8f023 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q23.sql @@ -0,0 +1,96 @@ +-- Item-date multiplicities are preserved; global maxima and customer cutoffs remain world-specific. +WITH frequent_stats AS ( +SELECT itemdesc, + i_item_sk item_sk, + d_date solddate, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) cnt, tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.date_dim, + (SELECT SUBSTRING(i_item_desc, 1, 30) itemdesc, + * + FROM main.item) sq1, (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk=asa_owner0.asa_key0 AND ss_sold_date_sk = d_date_sk + AND ss_item_sk = i_item_sk + AND d_year IN (2000, + 2000+1, + 2000+2, + 2000+3) + GROUP BY itemdesc, + i_item_sk, + d_date + +), +frequent_ss_items AS (SELECT itemdesc,item_sk,solddate,priv_select(18446744073709551615::UBIGINT,list_transform(cnt,lambda x: x>4)) AS membership FROM frequent_stats), +customer_period_stats AS ( +SELECT c_customer_sk, + tpcds_sum(priv_hash(hash(c_customer_sk)), ss_quantity*ss_sales_price) csales, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.store_sales, + main.customer, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND ss_customer_sk = c_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year IN (2000, + 2000+1, + 2000+2, + 2000+3) + GROUP BY c_customer_sk +), +customer_period AS ( +SELECT world, c_customer_sk, csales[world+1] AS csales +FROM customer_period_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +max_sales AS (SELECT world,max(csales) AS maximum FROM customer_period GROUP BY world), +max_array AS (SELECT list(maximum ORDER BY w.world) AS thresholds FROM range(64) w(world) LEFT JOIN max_sales USING(world)), +best_stats AS (SELECT c_customer_sk,tpcds_sum(priv_hash(hash(c_customer_sk)),ss_quantity*ss_sales_price) AS ssales FROM main.store_sales JOIN main.customer ON ss_customer_sk=c_customer_sk GROUP BY c_customer_sk), +best_ss_customer AS (SELECT c_customer_sk,priv_select(priv_hash(hash(c_customer_sk)),list_transform(list_zip(ssales,thresholds),lambda x: x[1]>0.5*x[2])) AS membership FROM best_stats CROSS JOIN max_array), +channel0_stats AS ( +SELECT c_last_name, + c_first_name, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk)) & frequent_ss_items.membership & best_ss_customer.membership), cs_quantity*cs_list_price) sales, tpcds_count((priv_hash(hash(cs_bill_customer_sk)) & frequent_ss_items.membership & best_ss_customer.membership),1) AS presence +FROM main.catalog_sales, + main.customer, + main.date_dim, + frequent_ss_items, + best_ss_customer +WHERE d_year = 2000 + AND d_moy = 2 + AND cs_sold_date_sk = d_date_sk + AND cs_item_sk = item_sk + AND cs_bill_customer_sk = best_ss_customer.c_customer_sk + AND cs_bill_customer_sk = customer.c_customer_sk + GROUP BY c_last_name, + c_first_name + +), +channel0 AS ( +SELECT world, c_last_name, c_first_name, sales[world+1] AS sales +FROM channel0_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +channel1_stats AS ( + SELECT c_last_name, + c_first_name, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk)) & frequent_ss_items.membership & best_ss_customer.membership), ws_quantity*ws_list_price) sales, tpcds_count((priv_hash(hash(ws_bill_customer_sk)) & frequent_ss_items.membership & best_ss_customer.membership),1) AS presence +FROM main.web_sales, + main.customer, + main.date_dim, + frequent_ss_items, + best_ss_customer +WHERE d_year = 2000 + AND d_moy = 2 + AND ws_sold_date_sk = d_date_sk + AND ws_item_sk = item_sk + AND ws_bill_customer_sk = best_ss_customer.c_customer_sk + AND ws_bill_customer_sk = customer.c_customer_sk + GROUP BY c_last_name, + c_first_name +), +channel1 AS ( +SELECT world, c_last_name, c_first_name, sales[world+1] AS sales +FROM channel1_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +answers AS (SELECT * FROM channel0 UNION ALL SELECT * FROM channel1) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY c_last_name NULLS FIRST,c_first_name NULLS FIRST,sales NULLS FIRST)<=100 ORDER BY world,c_last_name NULLS FIRST,c_first_name NULLS FIRST,sales NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q24.sql b/benchmark/tpcds/reference_queries/q24.sql new file mode 100644 index 00000000..d58fe980 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q24.sql @@ -0,0 +1,58 @@ +-- Sale and return ownership masks are intersected before the shared inner aggregation. +WITH ssales_stats AS ( +SELECT c_last_name, + c_first_name, + s_store_name, + ca_state, + s_state, + i_color, + i_current_price, + i_manager_id, + i_units, + i_size, + tpcds_sum((priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk))), ss_net_paid) netpaid, tpcds_count((priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk))),1) AS presence +FROM main.store_sales, + main.store_returns, + main.store, + main.item, + main.customer, + main.customer_address, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_return_owner +WHERE sr_customer_sk=asa_return_owner.asa_key AND ss_ticket_number = sr_ticket_number + AND ss_item_sk = sr_item_sk + AND ss_customer_sk = c_customer_sk + AND ss_item_sk = i_item_sk + AND ss_store_sk = s_store_sk + AND c_current_addr_sk = ca_address_sk + AND c_birth_country <> upper(ca_country) + AND s_zip = ca_zip + AND s_market_id=8 + GROUP BY c_last_name, + c_first_name, + s_store_name, + ca_state, + s_state, + i_color, + i_current_price, + i_manager_id, + i_units, + i_size +), ssales AS ( +SELECT world, c_last_name, c_first_name, s_store_name, ca_state, s_state, i_color, i_current_price, i_manager_id, i_units, i_size, netpaid[world+1] AS netpaid +FROM ssales_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT outer_ss.world AS world, c_last_name, + c_first_name, + s_store_name, + sum(netpaid) paid +FROM ssales outer_ss +WHERE i_color = 'peach' +GROUP BY outer_ss.world, c_last_name, + c_first_name, + s_store_name +HAVING sum(netpaid) > + (SELECT 0.05*avg(netpaid) + FROM ssales inner_ss WHERE inner_ss.world=outer_ss.world) +ORDER BY outer_ss.world, c_last_name, + c_first_name, + s_store_name; diff --git a/benchmark/tpcds/reference_queries/q25.sql b/benchmark/tpcds/reference_queries/q25.sql new file mode 100644 index 00000000..963bf844 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q25.sql @@ -0,0 +1,54 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_item_id, + i_item_desc, + s_store_id, + s_store_name, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_net_profit) AS store_sales_profit, + tpcds_sum((priv_hash(hash(ss_customer_sk))), sr_net_loss) AS store_returns_loss, + tpcds_sum((priv_hash(hash(ss_customer_sk))), cs_net_profit) AS catalog_sales_profit, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales , + main.store_returns , + main.catalog_sales , + main.date_dim d1 , + main.date_dim d2 , + main.date_dim d3 , + main.store , + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND d1.d_moy = 4 + AND d1.d_year = 2001 + AND d1.d_date_sk = ss_sold_date_sk + AND i_item_sk = ss_item_sk + AND s_store_sk = ss_store_sk + AND ss_customer_sk = sr_customer_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND sr_returned_date_sk = d2.d_date_sk + AND d2.d_moy BETWEEN 4 AND 10 + AND d2.d_year = 2001 + AND sr_customer_sk = cs_bill_customer_sk + AND sr_item_sk = cs_item_sk + AND cs_sold_date_sk = d3.d_date_sk + AND d3.d_moy BETWEEN 4 AND 10 + AND d3.d_year = 2001 +GROUP BY i_item_id , + i_item_desc , + s_store_id , + s_store_name +), answers AS ( + SELECT world, i_item_id, + i_item_desc, + s_store_id, + s_store_name, + store_sales_profit[world+1] AS store_sales_profit, + store_returns_loss[world+1] AS store_returns_loss, + catalog_sales_profit[world+1] AS catalog_sales_profit + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY i_item_id, i_item_desc, s_store_id, s_store_name) <= 100 +ORDER BY world, i_item_id, i_item_desc, s_store_id, s_store_name; diff --git a/benchmark/tpcds/reference_queries/q26.sql b/benchmark/tpcds/reference_queries/q26.sql new file mode 100644 index 00000000..5c8055f1 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q26.sql @@ -0,0 +1,38 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_item_id, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), cs_quantity) AS agg1, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), cs_list_price) AS agg2, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), cs_coupon_amt) AS agg3, + tpcds_avg((priv_hash(hash(cs_bill_customer_sk))), cs_sales_price) AS agg4, + tpcds_count((priv_hash(hash(cs_bill_customer_sk))), 1) AS presence + FROM main.catalog_sales, + main.customer_demographics, + main.date_dim, + main.item, + main.promotion, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE cs_bill_customer_sk = asa_owner0.asa_key0 + AND cs_sold_date_sk = d_date_sk + AND cs_item_sk = i_item_sk + AND cs_bill_cdemo_sk = cd_demo_sk + AND cs_promo_sk = p_promo_sk + AND cd_gender = 'M' + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND (p_channel_email = 'N' + OR p_channel_event = 'N') + AND d_year = 2000 +GROUP BY i_item_id +), answers AS ( + SELECT world, i_item_id, + agg1[world+1] AS agg1, + agg2[world+1] AS agg2, + agg3[world+1] AS agg3, + agg4[world+1] AS agg4 + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY i_item_id) <= 100 +ORDER BY world, i_item_id; diff --git a/benchmark/tpcds/reference_queries/q27.sql b/benchmark/tpcds/reference_queries/q27.sql new file mode 100644 index 00000000..45c51b9a --- /dev/null +++ b/benchmark/tpcds/reference_queries/q27.sql @@ -0,0 +1,25 @@ +-- Explicit grouping sets reproduce all three original UNION ALL branches, including empty grand totals. +WITH input AS ( +SELECT priv_hash(hash(ss_customer_sk)) AS membership, i_item_id, + s_state, + 0 AS g_state, + ss_quantity agg1, + ss_list_price agg2, + ss_coupon_amt agg3, + ss_sales_price agg4 + FROM main.store_sales, + main.customer_demographics, + main.date_dim, + main.store, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_sold_date_sk = d_date_sk + AND ss_item_sk = i_item_sk + AND ss_store_sk = s_store_sk + AND ss_cdemo_sk = cd_demo_sk + AND cd_gender = 'M' + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND d_year = 2002 + AND s_state = 'TN' +), stats AS (SELECT i_item_id, s_state, grouping(s_state) AS g_state, grouping(i_item_id) AS grand_total, tpcds_avg(membership,agg1) AS agg1, tpcds_avg(membership,agg2) AS agg2, tpcds_avg(membership,agg3) AS agg3, tpcds_avg(membership,agg4) AS agg4, tpcds_count(membership,1) AS presence FROM input GROUP BY GROUPING SETS ((i_item_id,s_state),(i_item_id),())), answers AS (SELECT world, i_item_id, s_state, g_state, agg1[world+1] AS agg1, agg2[world+1] AS agg2, agg3[world+1] AS agg3, agg4[world+1] AS agg4 FROM stats CROSS JOIN range(64) worlds(world) WHERE presence[world+1]>0 OR grand_total=1) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY i_item_id NULLS FIRST,s_state NULLS FIRST)<=100 ORDER BY world,i_item_id NULLS FIRST,s_state NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q28.sql b/benchmark/tpcds/reference_queries/q28.sql new file mode 100644 index 00000000..6c7dd994 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q28.sql @@ -0,0 +1,9 @@ +-- Per-value membership union implements COUNT(DISTINCT) without duplicating base rows by world. +WITH input AS (SELECT CASE WHEN (ss_quantity BETWEEN 0 AND 5 AND (ss_list_price BETWEEN 8 AND 18 OR ss_coupon_amt BETWEEN 459 AND 1459 OR ss_wholesale_cost BETWEEN 57 AND 77)) THEN 1 WHEN (ss_quantity BETWEEN 6 AND 10 AND (ss_list_price BETWEEN 90 AND 100 OR ss_coupon_amt BETWEEN 2323 AND 3323 OR ss_wholesale_cost BETWEEN 31 AND 51)) THEN 2 WHEN (ss_quantity BETWEEN 11 AND 15 AND (ss_list_price BETWEEN 142 AND 152 OR ss_coupon_amt BETWEEN 12214 AND 13214 OR ss_wholesale_cost BETWEEN 79 AND 99)) THEN 3 WHEN (ss_quantity BETWEEN 16 AND 20 AND (ss_list_price BETWEEN 135 AND 145 OR ss_coupon_amt BETWEEN 6071 AND 7071 OR ss_wholesale_cost BETWEEN 38 AND 58)) THEN 4 WHEN (ss_quantity BETWEEN 21 AND 25 AND (ss_list_price BETWEEN 122 AND 132 OR ss_coupon_amt BETWEEN 836 AND 1836 OR ss_wholesale_cost BETWEEN 17 AND 37)) THEN 5 WHEN (ss_quantity BETWEEN 26 AND 30 AND (ss_list_price BETWEEN 154 AND 164 OR ss_coupon_amt BETWEEN 7326 AND 8326 OR ss_wholesale_cost BETWEEN 7 AND 27)) THEN 6 END AS bucket, ss_list_price AS price, priv_hash(hash(ss_customer_sk)) AS membership +FROM main.store_sales JOIN main.customer ON ss_customer_sk=c_customer_sk WHERE (ss_quantity BETWEEN 0 AND 5 AND (ss_list_price BETWEEN 8 AND 18 OR ss_coupon_amt BETWEEN 459 AND 1459 OR ss_wholesale_cost BETWEEN 57 AND 77)) OR (ss_quantity BETWEEN 6 AND 10 AND (ss_list_price BETWEEN 90 AND 100 OR ss_coupon_amt BETWEEN 2323 AND 3323 OR ss_wholesale_cost BETWEEN 31 AND 51)) OR (ss_quantity BETWEEN 11 AND 15 AND (ss_list_price BETWEEN 142 AND 152 OR ss_coupon_amt BETWEEN 12214 AND 13214 OR ss_wholesale_cost BETWEEN 79 AND 99)) OR (ss_quantity BETWEEN 16 AND 20 AND (ss_list_price BETWEEN 135 AND 145 OR ss_coupon_amt BETWEEN 6071 AND 7071 OR ss_wholesale_cost BETWEEN 38 AND 58)) OR (ss_quantity BETWEEN 21 AND 25 AND (ss_list_price BETWEEN 122 AND 132 OR ss_coupon_amt BETWEEN 836 AND 1836 OR ss_wholesale_cost BETWEEN 17 AND 37)) OR (ss_quantity BETWEEN 26 AND 30 AND (ss_list_price BETWEEN 154 AND 164 OR ss_coupon_amt BETWEEN 7326 AND 8326 OR ss_wholesale_cost BETWEEN 7 AND 27))), +stats AS (SELECT bucket,tpcds_avg(membership,price) AS average,tpcds_count(membership,price) AS n FROM input GROUP BY bucket), +unique_prices AS (SELECT bucket,price,bit_or(membership) AS membership FROM input WHERE price IS NOT NULL GROUP BY bucket,price), +unique_counts AS (SELECT bucket,tpcds_count(membership,1) AS n FROM unique_prices GROUP BY bucket), +expanded AS (SELECT world,bucket,average[world+1] AS average,coalesce(stats.n[world+1],0) AS n,coalesce(unique_counts.n[world+1],0) AS nd +FROM (VALUES(1),(2),(3),(4),(5),(6)) b(bucket) CROSS JOIN range(64) worlds(world) LEFT JOIN stats USING(bucket) LEFT JOIN unique_counts USING(bucket)) +SELECT world,max(average) FILTER (WHERE bucket=1) AS b1_lp, max(n) FILTER (WHERE bucket=1) AS b1_cnt, max(nd) FILTER (WHERE bucket=1) AS b1_cntd, max(average) FILTER (WHERE bucket=2) AS b2_lp, max(n) FILTER (WHERE bucket=2) AS b2_cnt, max(nd) FILTER (WHERE bucket=2) AS b2_cntd, max(average) FILTER (WHERE bucket=3) AS b3_lp, max(n) FILTER (WHERE bucket=3) AS b3_cnt, max(nd) FILTER (WHERE bucket=3) AS b3_cntd, max(average) FILTER (WHERE bucket=4) AS b4_lp, max(n) FILTER (WHERE bucket=4) AS b4_cnt, max(nd) FILTER (WHERE bucket=4) AS b4_cntd, max(average) FILTER (WHERE bucket=5) AS b5_lp, max(n) FILTER (WHERE bucket=5) AS b5_cnt, max(nd) FILTER (WHERE bucket=5) AS b5_cntd, max(average) FILTER (WHERE bucket=6) AS b6_lp, max(n) FILTER (WHERE bucket=6) AS b6_cnt, max(nd) FILTER (WHERE bucket=6) AS b6_cntd FROM expanded GROUP BY world ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q29.sql b/benchmark/tpcds/reference_queries/q29.sql new file mode 100644 index 00000000..17f70177 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q29.sql @@ -0,0 +1,55 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_item_id, + i_item_desc, + s_store_id, + s_store_name, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_quantity) AS store_sales_quantity, + tpcds_sum((priv_hash(hash(ss_customer_sk))), sr_return_quantity) AS store_returns_quantity, + tpcds_sum((priv_hash(hash(ss_customer_sk))), cs_quantity) AS catalog_sales_quantity, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales, + main.store_returns, + main.catalog_sales, + main.date_dim d1, + main.date_dim d2, + main.date_dim d3, + main.store, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND d1.d_moy = 9 + AND d1.d_year = 1999 + AND d1.d_date_sk = ss_sold_date_sk + AND i_item_sk = ss_item_sk + AND s_store_sk = ss_store_sk + AND ss_customer_sk = sr_customer_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND sr_returned_date_sk = d2.d_date_sk + AND d2.d_moy BETWEEN 9 AND 9 + 3 + AND d2.d_year = 1999 + AND sr_customer_sk = cs_bill_customer_sk + AND sr_item_sk = cs_item_sk + AND cs_sold_date_sk = d3.d_date_sk + AND d3.d_year IN (1999, + 1999+1, + 1999+2) +GROUP BY i_item_id, + i_item_desc, + s_store_id, + s_store_name +), answers AS ( + SELECT world, i_item_id, + i_item_desc, + s_store_id, + s_store_name, + store_sales_quantity[world+1] AS store_sales_quantity, + store_returns_quantity[world+1] AS store_returns_quantity, + catalog_sales_quantity[world+1] AS catalog_sales_quantity + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY i_item_id, i_item_desc, s_store_id, s_store_name) <= 100 +ORDER BY world, i_item_id, i_item_desc, s_store_id, s_store_name; diff --git a/benchmark/tpcds/reference_queries/q30.sql b/benchmark/tpcds/reference_queries/q30.sql new file mode 100644 index 00000000..625a01f6 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q30.sql @@ -0,0 +1,68 @@ +-- Correlated thresholds use only the matching world of the reduced return aggregates. +WITH return_stats AS ( +SELECT wr_returning_customer_sk AS ctr_customer_sk, + ca_state AS ctr_state, + tpcds_sum(priv_hash(hash(wr_returning_customer_sk)), wr_return_amt) AS ctr_total_return, + tpcds_count(priv_hash(hash(wr_returning_customer_sk)),1) AS presence +FROM main.web_returns, + main.date_dim, + main.customer_address, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE wr_returning_customer_sk=asa_owner.asa_key AND wr_returned_date_sk = d_date_sk + AND d_year = 2002 + AND wr_returning_addr_sk = ca_address_sk + GROUP BY wr_returning_customer_sk, + ca_state +), customer_total_return AS ( +SELECT world, ctr_customer_sk, ctr_state, ctr_total_return[world+1] AS ctr_total_return +FROM return_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT ctr1.world AS world, c_customer_id, + c_salutation, + c_first_name, + c_last_name, + c_preferred_cust_flag, + c_birth_day, + c_birth_month, + c_birth_year, + c_birth_country, + c_login, + c_email_address, + c_last_review_date_sk, + ctr_total_return +FROM customer_total_return ctr1, + main.customer_address, + main.customer +WHERE ctr1.ctr_total_return > + (SELECT avg(ctr_total_return)*1.2 + FROM customer_total_return ctr2 + WHERE ctr1.world=ctr2.world AND ctr1.ctr_state = ctr2.ctr_state) + AND ca_address_sk = c_current_addr_sk + AND ca_state = 'GA' + AND ctr1.ctr_customer_sk = c_customer_sk +QUALIFY row_number() OVER (PARTITION BY ctr1.world ORDER BY c_customer_id NULLS FIRST, + c_salutation NULLS FIRST, + c_first_name NULLS FIRST, + c_last_name NULLS FIRST, + c_preferred_cust_flag NULLS FIRST, + c_birth_day NULLS FIRST, + c_birth_month NULLS FIRST, + c_birth_year NULLS FIRST, + c_birth_country NULLS FIRST, + c_login NULLS FIRST, + c_email_address NULLS FIRST, + c_last_review_date_sk NULLS FIRST, + ctr_total_return NULLS FIRST) <= 100 +ORDER BY ctr1.world, c_customer_id NULLS FIRST, + c_salutation NULLS FIRST, + c_first_name NULLS FIRST, + c_last_name NULLS FIRST, + c_preferred_cust_flag NULLS FIRST, + c_birth_day NULLS FIRST, + c_birth_month NULLS FIRST, + c_birth_year NULLS FIRST, + c_birth_country NULLS FIRST, + c_login NULLS FIRST, + c_email_address NULLS FIRST, + c_last_review_date_sk NULLS FIRST, + ctr_total_return NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q31.sql b/benchmark/tpcds/reference_queries/q31.sql new file mode 100644 index 00000000..cdaf8c82 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q31.sql @@ -0,0 +1,85 @@ +-- Fact scans feed AS once; subsequent processing is over reduced aggregate results. +WITH ss_stats AS ( +SELECT ca_county, + d_qoy, + d_year, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS store_sales, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.date_dim, + main.customer_address, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_sold_date_sk = d_date_sk + AND ss_addr_sk=ca_address_sk + GROUP BY ca_county, + d_qoy, + d_year +), +ss AS ( +SELECT world, ca_county, d_qoy, d_year, store_sales[world+1] AS store_sales +FROM ss_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +ws_stats AS ( +SELECT ca_county, + d_qoy, + d_year, + tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) AS web_sales, + tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) AS presence +FROM main.web_sales, + main.date_dim, + main.customer_address, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND ws_sold_date_sk = d_date_sk + AND ws_bill_addr_sk=ca_address_sk + GROUP BY ca_county, + d_qoy, + d_year +), +ws AS ( +SELECT world, ca_county, d_qoy, d_year, web_sales[world+1] AS web_sales +FROM ws_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT ss1.world AS world, ss1.ca_county , + ss1.d_year , + (ws2.web_sales*1.0000)/ws1.web_sales web_q1_q2_increase , + (ss2.store_sales*1.0000)/ss1.store_sales store_q1_q2_increase , + (ws3.web_sales*1.0000)/ws2.web_sales web_q2_q3_increase , + (ss3.store_sales*1.0000)/ss2.store_sales store_q2_q3_increase +FROM ss ss1 , + ss ss2 , + ss ss3 , + ws ws1 , + ws ws2 , + ws ws3 +WHERE ss1.world=ss2.world AND ss1.world=ss3.world AND ss1.world=ws1.world AND ss1.world=ws2.world AND ss1.world=ws3.world AND ss1.d_qoy = 1 + AND ss1.d_year = 2000 + AND ss1.ca_county = ss2.ca_county + AND ss2.d_qoy = 2 + AND ss2.d_year = 2000 + AND ss2.ca_county = ss3.ca_county + AND ss3.d_qoy = 3 + AND ss3.d_year = 2000 + AND ss1.ca_county = ws1.ca_county + AND ws1.d_qoy = 1 + AND ws1.d_year = 2000 + AND ws1.ca_county = ws2.ca_county + AND ws2.d_qoy = 2 + AND ws2.d_year = 2000 + AND ws1.ca_county = ws3.ca_county + AND ws3.d_qoy = 3 + AND ws3.d_year = 2000 + AND CASE + WHEN ws1.web_sales > 0 THEN (ws2.web_sales*1.0000)/ws1.web_sales + ELSE NULL + END > CASE + WHEN ss1.store_sales > 0 THEN (ss2.store_sales*1.0000)/ss1.store_sales + ELSE NULL + END + AND CASE + WHEN ws2.web_sales > 0 THEN (ws3.web_sales*1.0000)/ws2.web_sales + ELSE NULL + END > CASE + WHEN ss2.store_sales > 0 THEN (ss3.store_sales*1.0000)/ss2.store_sales + ELSE NULL + END +ORDER BY ss1.world, ss1.ca_county; diff --git a/benchmark/tpcds/reference_queries/q32.sql b/benchmark/tpcds/reference_queries/q32.sql new file mode 100644 index 00000000..46f64028 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q32.sql @@ -0,0 +1,14 @@ +-- Correlated aggregate predicates update the mask before the outer AS SUM. +WITH thresholds AS ( + SELECT cs_item_sk, tpcds_avg(priv_hash(hash(cs_bill_customer_sk)),cs_ext_discount_amt) AS averages + FROM main.catalog_sales JOIN main.customer ON cs_bill_customer_sk=c_customer_sk JOIN main.date_dim ON cs_sold_date_sk=d_date_sk + WHERE d_date BETWEEN DATE '2000-01-27' AND DATE '2000-04-26' GROUP BY cs_item_sk +), filtered AS ( + SELECT s.cs_ext_discount_amt AS discount, + priv_select(priv_hash(hash(cs_bill_customer_sk)),list_transform(averages, lambda average: s.cs_ext_discount_amt>1.3*average)) AS membership + FROM main.catalog_sales s JOIN main.customer ON cs_bill_customer_sk=c_customer_sk + JOIN main.item ON s.cs_item_sk=i_item_sk JOIN main.date_dim ON s.cs_sold_date_sk=d_date_sk + JOIN thresholds t ON s.cs_item_sk=t.cs_item_sk + WHERE i_manufact_id=977 AND d_date BETWEEN DATE '2000-01-27' AND DATE '2000-04-26' +), stats AS (SELECT tpcds_sum(membership,discount) AS total FROM filtered) +SELECT world,total[world+1] AS excess_discount_amount FROM stats CROSS JOIN range(64) worlds(world) ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q33.sql b/benchmark/tpcds/reference_queries/q33.sql new file mode 100644 index 00000000..b260140b --- /dev/null +++ b/benchmark/tpcds/reference_queries/q33.sql @@ -0,0 +1,90 @@ +-- Fact scans feed AS once; subsequent processing is over reduced aggregate results. +WITH ss_stats AS ( +SELECT i_manufact_id, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND i_manufact_id IN + (SELECT i_manufact_id + FROM main.item + WHERE i_category IN ('Electronics')) + AND ss_item_sk = i_item_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 5 + AND ss_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_manufact_id +), +ss AS ( +SELECT world, i_manufact_id, total_sales[world+1] AS total_sales +FROM ss_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cs_stats AS ( +SELECT i_manufact_id, + tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(cs_bill_customer_sk)),1) AS presence +FROM main.catalog_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND i_manufact_id IN + (SELECT i_manufact_id + FROM main.item + WHERE i_category IN ('Electronics')) + AND cs_item_sk = i_item_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 5 + AND cs_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_manufact_id +), +cs AS ( +SELECT world, i_manufact_id, total_sales[world+1] AS total_sales +FROM cs_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +ws_stats AS ( +SELECT i_manufact_id, + tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) AS presence +FROM main.web_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND i_manufact_id IN + (SELECT i_manufact_id + FROM main.item + WHERE i_category IN ('Electronics')) + AND ws_item_sk = i_item_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 5 + AND ws_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_manufact_id +), +ws AS ( +SELECT world, i_manufact_id, total_sales[world+1] AS total_sales +FROM ws_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +combined AS ( +SELECT world, i_manufact_id, + sum(total_sales) total_sales +FROM + (SELECT * + FROM ss + UNION ALL SELECT * + FROM cs + UNION ALL SELECT * + FROM ws) tmp1 +GROUP BY world, i_manufact_id +) +SELECT * FROM combined QUALIFY row_number() OVER (PARTITION BY world ORDER BY total_sales) <= 100 +ORDER BY world, total_sales; diff --git a/benchmark/tpcds/reference_queries/q34.sql b/benchmark/tpcds/reference_queries/q34.sql new file mode 100644 index 00000000..97109eb0 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q34.sql @@ -0,0 +1,51 @@ +-- AS aggregation is shared; only the reduced per-ticket results are expanded by world. +WITH stats AS ( + SELECT ss_ticket_number, + ss_customer_sk, + tpcds_count(priv_hash(hash(ss_customer_sk)), 1) AS cnt, + tpcds_count(priv_hash(hash(ss_customer_sk)), 1) AS presence + FROM main.store_sales, + main.date_dim, + main.store, + main.household_demographics, + (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key + AND store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND (date_dim.d_dom BETWEEN 1 AND 3 + OR date_dim.d_dom BETWEEN 25 AND 28) + AND (household_demographics.hd_buy_potential = '>10000' + OR household_demographics.hd_buy_potential = 'Unknown') + AND household_demographics.hd_vehicle_count > 0 + AND (CASE + WHEN household_demographics.hd_vehicle_count > 0 THEN (household_demographics.hd_dep_count*1.000)/ household_demographics.hd_vehicle_count + ELSE NULL + END) > 1.2 + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_county = 'Williamson County' + GROUP BY ss_ticket_number, + ss_customer_sk +), expanded AS ( + SELECT world, ss_ticket_number, ss_customer_sk, cnt[world+1] AS cnt + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1]>0 +) +SELECT world, c_last_name , + c_first_name , + c_salutation , + c_preferred_cust_flag , + ss_ticket_number , + cnt +FROM + expanded dn, + main.customer +WHERE ss_customer_sk = c_customer_sk + AND cnt BETWEEN 15 AND 20 +ORDER BY world, c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + c_salutation NULLS FIRST, + c_preferred_cust_flag DESC NULLS FIRST, + ss_ticket_number NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q35.sql b/benchmark/tpcds/reference_queries/q35.sql new file mode 100644 index 00000000..0b217580 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q35.sql @@ -0,0 +1,111 @@ +-- Same-owner EXISTS is static after entity inclusion; shipping-customer EXISTS needs the bill-owner mask. +WITH catalog_presence AS ( +SELECT cs_ship_customer_sk,bit_or(priv_hash(hash(cs_bill_customer_sk))) AS membership + FROM main.catalog_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND cs_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4 +GROUP BY cs_ship_customer_sk +), stats AS (SELECT ca_state, +cd_gender, +cd_marital_status, +cd_dep_count, +cd_dep_employed_count, +cd_dep_college_count, +tpcds_count((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),1) AS n, +tpcds_min((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_count) AS min1, +tpcds_max((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_count) AS max1, +tpcds_avg((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_count) AS avg1, +tpcds_min((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_employed_count) AS min2, +tpcds_max((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_employed_count) AS max2, +tpcds_avg((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_employed_count) AS avg2, +tpcds_min((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_college_count) AS min3, +tpcds_max((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_college_count) AS max3, +tpcds_avg((priv_hash(hash(c.c_customer_sk)) & ((CASE WHEN EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) THEN 18446744073709551615::UBIGINT ELSE 0::UBIGINT END) | coalesce(catalog_presence.membership,0::UBIGINT))),cd_dep_college_count) AS avg3 +FROM main.customer c CROSS JOIN + main.customer_address ca CROSS JOIN + main.customer_demographics LEFT JOIN catalog_presence ON c.c_customer_sk=cs_ship_customer_sk +WHERE c.c_current_addr_sk = ca.ca_address_sk + AND cd_demo_sk = c.c_current_cdemo_sk + +AND EXISTS(SELECT * + FROM main.store_sales, + main.date_dim + WHERE c.c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2002 + AND d_qoy < 4) +GROUP BY ca_state, cd_gender, cd_marital_status, cd_dep_count, cd_dep_employed_count, cd_dep_college_count +), answers AS (SELECT world, ca_state, cd_gender, cd_marital_status, cd_dep_count, n[world+1] AS cnt1, min1[world+1] AS min1, max1[world+1] AS max1, avg1[world+1] AS avg1, cd_dep_employed_count, n[world+1] AS cnt2, min2[world+1] AS min2, max2[world+1] AS max2, avg2[world+1] AS avg2, cd_dep_college_count, n[world+1] AS cnt3, min3[world+1] AS min3, max3[world+1] AS max3, avg3[world+1] AS avg3 FROM stats CROSS JOIN range(64) worlds(world) WHERE n[world+1]>0) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY ca_state NULLS FIRST, + cd_gender NULLS FIRST, + cd_marital_status NULLS FIRST, + cd_dep_count NULLS FIRST, + cd_dep_employed_count NULLS FIRST, + cd_dep_college_count NULLS FIRST)<=100 ORDER BY world,ca_state NULLS FIRST, + cd_gender NULLS FIRST, + cd_marital_status NULLS FIRST, + cd_dep_count NULLS FIRST, + cd_dep_employed_count NULLS FIRST, + cd_dep_college_count NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q40.sql b/benchmark/tpcds/reference_queries/q40.sql new file mode 100644 index 00000000..38eeb67c --- /dev/null +++ b/benchmark/tpcds/reference_queries/q40.sql @@ -0,0 +1,16 @@ +-- Matched and NULL-extended memberships are disjoint; NULL extension is evaluated separately in each world. +WITH left_input AS ( +SELECT w_state,i_item_id,d_date,cs_sales_price,cs_order_number,cs_item_sk,priv_hash(hash(cs_bill_customer_sk)) AS membership +FROM main.catalog_sales JOIN main.customer ON cs_bill_customer_sk=c_customer_sk +JOIN main.warehouse ON cs_warehouse_sk=w_warehouse_sk JOIN main.item ON i_item_sk=cs_item_sk +JOIN main.date_dim ON cs_sold_date_sk=d_date_sk +WHERE i_current_price BETWEEN 0.99 AND 1.49 AND d_date BETWEEN DATE '2000-02-10' AND DATE '2000-04-10' +), valid_returns AS (SELECT r.*,priv_hash(hash(cr_returning_customer_sk)) AS membership FROM main.catalog_returns r JOIN main.customer ON cr_returning_customer_sk=c_customer_sk), +return_presence AS (SELECT cr_order_number,cr_item_sk,bit_or(membership) AS membership FROM valid_returns GROUP BY cr_order_number,cr_item_sk), +joined AS ( + SELECT l.w_state,l.i_item_id,l.d_date,l.cs_sales_price,coalesce(r.cr_refunded_cash,0) AS refund,(l.membership & r.membership) AS membership FROM left_input l JOIN valid_returns r ON l.cs_order_number=r.cr_order_number AND l.cs_item_sk=r.cr_item_sk + UNION ALL + SELECT l.w_state,l.i_item_id,l.d_date,l.cs_sales_price,0 AS refund,(l.membership & ~coalesce(r.membership,0::UBIGINT)) AS membership FROM left_input l LEFT JOIN return_presence r ON l.cs_order_number=r.cr_order_number AND l.cs_item_sk=r.cr_item_sk +), stats AS (SELECT w_state,i_item_id,tpcds_sum(membership,CASE WHEN d_date=DATE '2000-03-11' THEN cs_sales_price-refund ELSE 0 END) AS sales_after,tpcds_count(membership,1) AS presence FROM joined GROUP BY w_state,i_item_id), +answers AS (SELECT world,w_state,i_item_id,sales_before[world+1] AS sales_before,sales_after[world+1] AS sales_after FROM stats CROSS JOIN range(64) worlds(world) WHERE presence[world+1]>0) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY w_state,i_item_id)<=100 ORDER BY world,w_state,i_item_id; diff --git a/benchmark/tpcds/reference_queries/q42.sql b/benchmark/tpcds/reference_queries/q42.sql new file mode 100644 index 00000000..3b28dcd2 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q42.sql @@ -0,0 +1,31 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT dt.d_year AS d_year, + item.i_category_id AS i_category_id, + item.i_category AS i_category, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_ext_sales_price) AS total, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.date_dim dt, + main.store_sales, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND dt.d_date_sk = store_sales.ss_sold_date_sk + AND store_sales.ss_item_sk = item.i_item_sk + AND item.i_manager_id = 1 + AND dt.d_moy=11 + AND dt.d_year=2000 +GROUP BY dt.d_year, + main.item.i_category_id, + main.item.i_category +), answers AS ( + SELECT world, d_year, + i_category_id, + i_category, + total[world+1] AS total + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY total DESC, d_year, i_category_id, i_category) <= 100 +ORDER BY world, total DESC, d_year, i_category_id, i_category; diff --git a/benchmark/tpcds/reference_queries/q43.sql b/benchmark/tpcds/reference_queries/q43.sql new file mode 100644 index 00000000..63cc41c9 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q43.sql @@ -0,0 +1,39 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT s_store_name, + s_store_id, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN d_day_name='Sunday' THEN ss_sales_price ELSE NULL END) AS sun_sales, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN d_day_name='Monday' THEN ss_sales_price ELSE NULL END) AS mon_sales, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN d_day_name='Tuesday' THEN ss_sales_price ELSE NULL END) AS tue_sales, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN d_day_name='Wednesday' THEN ss_sales_price ELSE NULL END) AS wed_sales, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN d_day_name='Thursday' THEN ss_sales_price ELSE NULL END) AS thu_sales, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN d_day_name='Friday' THEN ss_sales_price ELSE NULL END) AS fri_sales, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN d_day_name='Saturday' THEN ss_sales_price ELSE NULL END) AS sat_sales, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.date_dim, + main.store_sales, + main.store, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND d_date_sk = ss_sold_date_sk + AND s_store_sk = ss_store_sk + AND s_gmt_offset = -5 + AND d_year = 2000 +GROUP BY s_store_name, + s_store_id +), answers AS ( + SELECT world, s_store_name, + s_store_id, + sun_sales[world+1] AS sun_sales, + mon_sales[world+1] AS mon_sales, + tue_sales[world+1] AS tue_sales, + wed_sales[world+1] AS wed_sales, + thu_sales[world+1] AS thu_sales, + fri_sales[world+1] AS fri_sales, + sat_sales[world+1] AS sat_sales + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY s_store_name, s_store_id, sun_sales, mon_sales, tue_sales, wed_sales, thu_sales, fri_sales, sat_sales) <= 100 +ORDER BY world, s_store_name, s_store_id, sun_sales, mon_sales, tue_sales, wed_sales, thu_sales, fri_sales, sat_sales; diff --git a/benchmark/tpcds/reference_queries/q45.sql b/benchmark/tpcds/reference_queries/q45.sql new file mode 100644 index 00000000..f6f4d573 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q45.sql @@ -0,0 +1,53 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT ca_zip, + ca_city, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk))), ws_sales_price) AS total, + tpcds_count((priv_hash(hash(ws_bill_customer_sk))), 1) AS presence + FROM main.web_sales, + main.customer, + main.customer_address, + main.date_dim, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ws_bill_customer_sk = asa_owner0.asa_key0 + AND ws_bill_customer_sk = c_customer_sk + AND c_current_addr_sk = ca_address_sk + AND ws_item_sk = i_item_sk + AND (SUBSTRING(ca_zip,1,5) IN ('85669', + '86197', + '88274', + '83405', + '86475', + '85392', + '85460', + '80348', + '81792') + OR i_item_id IN + (SELECT i_item_id + FROM main.item + WHERE i_item_sk IN (2, + 3, + 5, + 7, + 11, + 13, + 17, + 19, + 23, + 29) )) + AND ws_sold_date_sk = d_date_sk + AND d_qoy = 2 + AND d_year = 2001 +GROUP BY ca_zip, + ca_city +), answers AS ( + SELECT world, ca_zip, + ca_city, + total[world+1] AS total + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY ca_zip, ca_city) <= 100 +ORDER BY world, ca_zip, ca_city; diff --git a/benchmark/tpcds/reference_queries/q46.sql b/benchmark/tpcds/reference_queries/q46.sql new file mode 100644 index 00000000..3d95ef46 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q46.sql @@ -0,0 +1,61 @@ +-- AS aggregation is shared; only the reduced per-ticket results are expanded by world. +WITH stats AS ( + SELECT ss_ticket_number, + ss_customer_sk, + ca_city AS bought_city, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_coupon_amt) AS amt, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit) AS profit, + tpcds_count(priv_hash(hash(ss_customer_sk)), 1) AS presence + FROM main.store_sales, + main.date_dim, + main.store, + main.household_demographics, + main.customer_address, + (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key + AND store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND store_sales.ss_addr_sk = customer_address.ca_address_sk + AND (household_demographics.hd_dep_count = 4 + OR household_demographics.hd_vehicle_count= 3) + AND date_dim.d_dow IN (6, + 0) + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_city IN ('Fairview', + 'Midway') + GROUP BY ss_ticket_number, + ss_customer_sk, + ss_addr_sk, + ca_city +), expanded AS ( + SELECT world, ss_ticket_number, ss_customer_sk, bought_city, amt[world+1] AS amt, profit[world+1] AS profit + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1]>0 +) +SELECT world, c_last_name, + c_first_name, + ca_city, + bought_city, + ss_ticket_number, + amt, + profit +FROM + expanded dn, + main.customer, + main.customer_address current_addr +WHERE ss_customer_sk = c_customer_sk + AND customer.c_current_addr_sk = current_addr.ca_address_sk + AND current_addr.ca_city <> bought_city +QUALIFY row_number() OVER (PARTITION BY world ORDER BY c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + ca_city NULLS FIRST, + bought_city NULLS FIRST, + ss_ticket_number NULLS FIRST) <= 100 +ORDER BY world, c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + ca_city NULLS FIRST, + bought_city NULLS FIRST, + ss_ticket_number NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q48.sql b/benchmark/tpcds/reference_queries/q48.sql new file mode 100644 index 00000000..ebf74011 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q48.sql @@ -0,0 +1,50 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_quantity) AS total, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales, + main.store, + main.customer_demographics, + main.customer_address, + main.date_dim, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND s_store_sk = ss_store_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2000 + AND ((cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'M' + AND cd_education_status = '4 yr Degree' + AND ss_sales_price BETWEEN 100.00 AND 150.00) + OR (cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'D' + AND cd_education_status = '2 yr Degree' + AND ss_sales_price BETWEEN 50.00 AND 100.00) + OR (cd_demo_sk = ss_cdemo_sk + AND cd_marital_status = 'S' + AND cd_education_status = 'College' + AND ss_sales_price BETWEEN 150.00 AND 200.00)) + AND ((ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('CO', + 'OH', + 'TX') + AND ss_net_profit BETWEEN 0 AND 2000) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('OR', + 'MN', + 'KY') + AND ss_net_profit BETWEEN 150 AND 3000) + OR (ss_addr_sk = ca_address_sk + AND ca_country = 'United States' + AND ca_state IN ('VA', + 'CA', + 'MS') + AND ss_net_profit BETWEEN 50 AND 25000)) +), answers AS ( + SELECT world, total[world+1] AS total + FROM stats CROSS JOIN range(64) worlds(world) +) +SELECT * FROM answers +ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q50.sql b/benchmark/tpcds/reference_queries/q50.sql new file mode 100644 index 00000000..4a699354 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q50.sql @@ -0,0 +1,65 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT s_store_name, + s_company_id, + s_street_number, + s_street_name, + s_street_type, + s_suite_number, + s_city, + s_county, + s_state, + s_zip, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN sr_returned_date_sk - ss_sold_date_sk <= 30 THEN 1 ELSE 0 END) AS bucket0, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN sr_returned_date_sk - ss_sold_date_sk > 30 AND sr_returned_date_sk - ss_sold_date_sk <= 60 THEN 1 ELSE 0 END) AS bucket1, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN sr_returned_date_sk - ss_sold_date_sk > 60 AND sr_returned_date_sk - ss_sold_date_sk <= 90 THEN 1 ELSE 0 END) AS bucket2, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN sr_returned_date_sk - ss_sold_date_sk > 90 AND sr_returned_date_sk - ss_sold_date_sk <= 120 THEN 1 ELSE 0 END) AS bucket3, + tpcds_sum((priv_hash(hash(ss_customer_sk))), CASE WHEN sr_returned_date_sk - ss_sold_date_sk > 120 THEN 1 ELSE 0 END) AS bucket4, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales, + main.store_returns, + main.store, + main.date_dim d1, + main.date_dim d2, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND d2.d_year = 2001 + AND d2.d_moy = 8 + AND ss_ticket_number = sr_ticket_number + AND ss_item_sk = sr_item_sk + AND ss_sold_date_sk = d1.d_date_sk + AND sr_returned_date_sk = d2.d_date_sk + AND ss_customer_sk = sr_customer_sk + AND ss_store_sk = s_store_sk +GROUP BY s_store_name, + s_company_id, + s_street_number, + s_street_name, + s_street_type, + s_suite_number, + s_city, + s_county, + s_state, + s_zip +), answers AS ( + SELECT world, s_store_name, + s_company_id, + s_street_number, + s_street_name, + s_street_type, + s_suite_number, + s_city, + s_county, + s_state, + s_zip, + bucket0[world+1] AS bucket0, + bucket1[world+1] AS bucket1, + bucket2[world+1] AS bucket2, + bucket3[world+1] AS bucket3, + bucket4[world+1] AS bucket4 + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY s_store_name, s_company_id, s_street_number, s_street_name, s_street_type, s_suite_number, s_city, s_county, s_state, s_zip) <= 100 +ORDER BY world, s_store_name, s_company_id, s_street_number, s_street_name, s_street_type, s_suite_number, s_city, s_county, s_state, s_zip; diff --git a/benchmark/tpcds/reference_queries/q52.sql b/benchmark/tpcds/reference_queries/q52.sql new file mode 100644 index 00000000..dbbc5c6c --- /dev/null +++ b/benchmark/tpcds/reference_queries/q52.sql @@ -0,0 +1,31 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT dt.d_year AS d_year, + item.i_brand_id AS brand_id, + item.i_brand AS brand, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_ext_sales_price) AS ext_price, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.date_dim dt, + main.store_sales, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND dt.d_date_sk = store_sales.ss_sold_date_sk + AND store_sales.ss_item_sk = item.i_item_sk + AND item.i_manager_id = 1 + AND dt.d_moy=11 + AND dt.d_year=2000 +GROUP BY dt.d_year, + main.item.i_brand, + main.item.i_brand_id +), answers AS ( + SELECT world, d_year, + brand_id, + brand, + ext_price[world+1] AS ext_price + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY d_year, ext_price DESC, brand_id) <= 100 +ORDER BY world, d_year, ext_price DESC, brand_id; diff --git a/benchmark/tpcds/reference_queries/q55.sql b/benchmark/tpcds/reference_queries/q55.sql new file mode 100644 index 00000000..14f28825 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q55.sql @@ -0,0 +1,28 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT i_brand_id AS brand_id, + i_brand AS brand, + tpcds_sum((priv_hash(hash(ss_customer_sk))), ss_ext_sales_price) AS ext_price, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.date_dim, + main.store_sales, + main.item, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND d_date_sk = ss_sold_date_sk + AND ss_item_sk = i_item_sk + AND i_manager_id=28 + AND d_moy=11 + AND d_year=1999 +GROUP BY i_brand, + i_brand_id +), answers AS ( + SELECT world, brand_id, + brand, + ext_price[world+1] AS ext_price + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY ext_price DESC, brand_id) <= 100 +ORDER BY world, ext_price DESC, brand_id; diff --git a/benchmark/tpcds/reference_queries/q56.sql b/benchmark/tpcds/reference_queries/q56.sql new file mode 100644 index 00000000..267dc3fd --- /dev/null +++ b/benchmark/tpcds/reference_queries/q56.sql @@ -0,0 +1,98 @@ +-- Fact scans feed AS once; subsequent processing is over reduced aggregate results. +WITH ss_stats AS ( +SELECT i_item_id, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND i_item_id IN + (SELECT i_item_id + FROM main.item + WHERE i_color IN ('slate', + 'blanched', + 'burnished')) + AND ss_item_sk = i_item_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy = 2 + AND ss_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id +), +ss AS ( +SELECT world, i_item_id, total_sales[world+1] AS total_sales +FROM ss_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cs_stats AS ( +SELECT i_item_id, + tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(cs_bill_customer_sk)),1) AS presence +FROM main.catalog_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND i_item_id IN + (SELECT i_item_id + FROM main.item + WHERE i_color IN ('slate', + 'blanched', + 'burnished')) + AND cs_item_sk = i_item_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy = 2 + AND cs_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id +), +cs AS ( +SELECT world, i_item_id, total_sales[world+1] AS total_sales +FROM cs_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +ws_stats AS ( +SELECT i_item_id, + tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) AS presence +FROM main.web_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND i_item_id IN + (SELECT i_item_id + FROM main.item + WHERE i_color IN ('slate', + 'blanched', + 'burnished')) + AND ws_item_sk = i_item_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy = 2 + AND ws_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id +), +ws AS ( +SELECT world, i_item_id, total_sales[world+1] AS total_sales +FROM ws_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +combined AS ( +SELECT world, i_item_id, + sum(total_sales) total_sales +FROM + (SELECT * + FROM ss + UNION ALL SELECT * + FROM cs + UNION ALL SELECT * + FROM ws) tmp1 +GROUP BY world, i_item_id +) +SELECT * FROM combined QUALIFY row_number() OVER (PARTITION BY world ORDER BY total_sales NULLS FIRST, + i_item_id NULLS FIRST) <= 100 +ORDER BY world, total_sales NULLS FIRST, + i_item_id NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q58.sql b/benchmark/tpcds/reference_queries/q58.sql new file mode 100644 index 00000000..3396ad99 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q58.sql @@ -0,0 +1,93 @@ +-- Fact scans feed AS once; subsequent processing is over reduced aggregate results. +WITH ss_items_stats AS ( +SELECT i_item_id item_id, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) ss_item_rev, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.item, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM main.date_dim + WHERE d_week_seq = + (SELECT d_week_seq + FROM main.date_dim + WHERE d_date = '2000-01-03')) + AND ss_sold_date_sk = d_date_sk + GROUP BY i_item_id +), +ss_items AS ( +SELECT world, item_id, ss_item_rev[world+1] AS ss_item_rev +FROM ss_items_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cs_items_stats AS ( +SELECT i_item_id item_id, + tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) cs_item_rev, + tpcds_count(priv_hash(hash(cs_bill_customer_sk)),1) AS presence +FROM main.catalog_sales, + main.item, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND cs_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM main.date_dim + WHERE d_week_seq = + (SELECT d_week_seq + FROM main.date_dim + WHERE d_date = '2000-01-03')) + AND cs_sold_date_sk = d_date_sk + GROUP BY i_item_id +), +cs_items AS ( +SELECT world, item_id, cs_item_rev[world+1] AS cs_item_rev +FROM cs_items_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +ws_items_stats AS ( +SELECT i_item_id item_id, + tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) ws_item_rev, + tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) AS presence +FROM main.web_sales, + main.item, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND ws_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM main.date_dim + WHERE d_week_seq = + (SELECT d_week_seq + FROM main.date_dim + WHERE d_date = '2000-01-03')) + AND ws_sold_date_sk = d_date_sk + GROUP BY i_item_id +), +ws_items AS ( +SELECT world, item_id, ws_item_rev[world+1] AS ws_item_rev +FROM ws_items_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT ss_items.world AS world, ss_items.item_id, + ss_item_rev, + ss_item_rev/((ss_item_rev+cs_item_rev+ws_item_rev)/3) * 100 ss_dev, + cs_item_rev, + cs_item_rev/((ss_item_rev+cs_item_rev+ws_item_rev)/3) * 100 cs_dev, + ws_item_rev, + ws_item_rev/((ss_item_rev+cs_item_rev+ws_item_rev)/3) * 100 ws_dev, + (ss_item_rev+cs_item_rev+ws_item_rev)/3 average +FROM ss_items, + cs_items, + ws_items +WHERE ss_items.world=cs_items.world AND ss_items.world=ws_items.world AND ss_items.item_id=cs_items.item_id + AND ss_items.item_id=ws_items.item_id + AND ss_item_rev BETWEEN 0.9 * cs_item_rev AND 1.1 * cs_item_rev + AND ss_item_rev BETWEEN 0.9 * ws_item_rev AND 1.1 * ws_item_rev + AND cs_item_rev BETWEEN 0.9 * ss_item_rev AND 1.1 * ss_item_rev + AND cs_item_rev BETWEEN 0.9 * ws_item_rev AND 1.1 * ws_item_rev + AND ws_item_rev BETWEEN 0.9 * ss_item_rev AND 1.1 * ss_item_rev + AND ws_item_rev BETWEEN 0.9 * cs_item_rev AND 1.1 * cs_item_rev +QUALIFY row_number() OVER (PARTITION BY ss_items.world ORDER BY ss_items.item_id NULLS FIRST, + ss_item_rev NULLS FIRST) <= 100 +ORDER BY ss_items.world, ss_items.item_id NULLS FIRST, + ss_item_rev NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q59.sql b/benchmark/tpcds/reference_queries/q59.sql new file mode 100644 index 00000000..e2695b7c --- /dev/null +++ b/benchmark/tpcds/reference_queries/q59.sql @@ -0,0 +1,94 @@ +-- A shared per-store/week AS result is reused across both years. +WITH wss_stats AS ( +SELECT d_week_seq, + ss_store_sk, + tpcds_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Sunday') THEN ss_sales_price + ELSE NULL + END) sun_sales, + tpcds_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Monday') THEN ss_sales_price + ELSE NULL + END) mon_sales, + tpcds_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Tuesday') THEN ss_sales_price + ELSE NULL + END) tue_sales, + tpcds_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Wednesday') THEN ss_sales_price + ELSE NULL + END) wed_sales, + tpcds_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Thursday') THEN ss_sales_price + ELSE NULL + END) thu_sales, + tpcds_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Friday') THEN ss_sales_price + ELSE NULL + END) fri_sales, + tpcds_sum(priv_hash(hash(ss_customer_sk)), CASE + WHEN (d_day_name='Saturday') THEN ss_sales_price + ELSE NULL + END) sat_sales, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND d_date_sk = ss_sold_date_sk + GROUP BY d_week_seq, + ss_store_sk +), wss AS ( +SELECT world, d_week_seq, ss_store_sk, sun_sales[world+1] AS sun_sales, mon_sales[world+1] AS mon_sales, tue_sales[world+1] AS tue_sales, wed_sales[world+1] AS wed_sales, thu_sales[world+1] AS thu_sales, fri_sales[world+1] AS fri_sales, sat_sales[world+1] AS sat_sales +FROM wss_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT y.world AS world, s_store_name1, + s_store_id1, + d_week_seq1, + sun_sales1/sun_sales2 AS sun_sales_ratio, + mon_sales1/mon_sales2 AS mon_sales_ratio, + tue_sales1/tue_sales2 AS tue_sales_ratio, + wed_sales1/wed_sales2 AS wed_sales_ratio, + thu_sales1/thu_sales2 AS thu_sales_ratio, + fri_sales1/fri_sales2 AS fri_sales_ratio, + sat_sales1/sat_sales2 AS sat_sales_ratio +FROM + (SELECT wss.world, s_store_name s_store_name1, + wss.d_week_seq d_week_seq1, + s_store_id s_store_id1, + sun_sales sun_sales1, + mon_sales mon_sales1, + tue_sales tue_sales1, + wed_sales wed_sales1, + thu_sales thu_sales1, + fri_sales fri_sales1, + sat_sales sat_sales1 + FROM wss, + main.store, + main.date_dim d + WHERE d.d_week_seq = wss.d_week_seq + AND ss_store_sk = s_store_sk + AND d_month_seq BETWEEN 1212 AND 1212 + 11) y, + (SELECT wss.world, s_store_name s_store_name2, + wss.d_week_seq d_week_seq2, + s_store_id s_store_id2, + sun_sales sun_sales2, + mon_sales mon_sales2, + tue_sales tue_sales2, + wed_sales wed_sales2, + thu_sales thu_sales2, + fri_sales fri_sales2, + sat_sales sat_sales2 + FROM wss, + main.store, + main.date_dim d + WHERE d.d_week_seq = wss.d_week_seq + AND ss_store_sk = s_store_sk + AND d_month_seq BETWEEN 1212 + 12 AND 1212 + 23) x +WHERE y.world=x.world AND s_store_id1=s_store_id2 + AND d_week_seq1=d_week_seq2-52 +QUALIFY row_number() OVER (PARTITION BY y.world ORDER BY s_store_name1 NULLS FIRST, + s_store_id1 NULLS FIRST, + d_week_seq1 NULLS FIRST) <= 100 +ORDER BY y.world, s_store_name1 NULLS FIRST, + s_store_id1 NULLS FIRST, + d_week_seq1 NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q60.sql b/benchmark/tpcds/reference_queries/q60.sql new file mode 100644 index 00000000..86f4a209 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q60.sql @@ -0,0 +1,92 @@ +-- Fact scans feed AS once; subsequent processing is over reduced aggregate results. +WITH ss_stats AS ( +SELECT i_item_id, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND i_item_id IN + (SELECT i_item_id + FROM main.item + WHERE i_category ='Music') + AND ss_item_sk = i_item_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 9 + AND ss_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id +), +ss AS ( +SELECT world, i_item_id, total_sales[world+1] AS total_sales +FROM ss_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cs_stats AS ( +SELECT i_item_id, + tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(cs_bill_customer_sk)),1) AS presence +FROM main.catalog_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND i_item_id IN + (SELECT i_item_id + FROM main.item + WHERE i_category ='Music') + AND cs_item_sk = i_item_sk + AND cs_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 9 + AND cs_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id +), +cs AS ( +SELECT world, i_item_id, total_sales[world+1] AS total_sales +FROM cs_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +ws_stats AS ( +SELECT i_item_id, + tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) total_sales, + tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) AS presence +FROM main.web_sales, + main.date_dim, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND i_item_id IN + (SELECT i_item_id + FROM main.item + WHERE i_category = 'Music') + AND ws_item_sk = i_item_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 1998 + AND d_moy = 9 + AND ws_bill_addr_sk = ca_address_sk + AND ca_gmt_offset = -5 + GROUP BY i_item_id +), +ws AS ( +SELECT world, i_item_id, total_sales[world+1] AS total_sales +FROM ws_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +combined AS ( +SELECT world, i_item_id, + sum(total_sales) total_sales +FROM + (SELECT * + FROM ss + UNION ALL SELECT * + FROM cs + UNION ALL SELECT * + FROM ws) tmp1 +GROUP BY world, i_item_id +) +SELECT * FROM combined QUALIFY row_number() OVER (PARTITION BY world ORDER BY i_item_id, + total_sales) <= 100 +ORDER BY world, i_item_id, + total_sales; diff --git a/benchmark/tpcds/reference_queries/q61.sql b/benchmark/tpcds/reference_queries/q61.sql new file mode 100644 index 00000000..737d3390 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q61.sql @@ -0,0 +1,49 @@ +-- Scalar AS arrays are combined only after their independent shared scans. +WITH raw0 AS ( +SELECT tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) promotions + FROM main.store_sales, + main.store, + main.promotion, + main.date_dim, + main.customer, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_sold_date_sk = d_date_sk + AND ss_store_sk = s_store_sk + AND ss_promo_sk = p_promo_sk + AND ss_customer_sk= c_customer_sk + AND ca_address_sk = c_current_addr_sk + AND ss_item_sk = i_item_sk + AND ca_gmt_offset = -5 + AND i_category = 'Jewelry' + AND (p_channel_dmail = 'Y' + OR p_channel_email = 'Y' + OR p_channel_tv = 'Y') + AND s_gmt_offset = -5 + AND d_year = 1998 + AND d_moy = 11 +), +raw1 AS ( +SELECT tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) total + FROM main.store_sales, + main.store, + main.date_dim, + main.customer, + main.customer_address, + main.item, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_sold_date_sk = d_date_sk + AND ss_store_sk = s_store_sk + AND ss_customer_sk= c_customer_sk + AND ca_address_sk = c_current_addr_sk + AND ss_item_sk = i_item_sk + AND ca_gmt_offset = -5 + AND i_category = 'Jewelry' + AND s_gmt_offset = -5 + AND d_year = 1998 + AND d_moy = 11 +), +p AS (SELECT world, raw0.promotions[world+1] AS promotions, raw1.total[world+1] AS total FROM raw0 CROSS JOIN raw1 CROSS JOIN range(64) worlds(world)) +SELECT world, p.promotions, + p.total, + cast(p.promotions AS decimal(15,4))/cast(p.total AS decimal(15,4))*100 + FROM p ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q62.sql b/benchmark/tpcds/reference_queries/q62.sql new file mode 100644 index 00000000..b247bb7f --- /dev/null +++ b/benchmark/tpcds/reference_queries/q62.sql @@ -0,0 +1,43 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT w_substr, + sm_type, + web_name, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk))), CASE WHEN ws_ship_date_sk - ws_sold_date_sk <= 30 THEN 1 ELSE 0 END) AS bucket0, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk))), CASE WHEN ws_ship_date_sk - ws_sold_date_sk > 30 AND ws_ship_date_sk - ws_sold_date_sk <= 60 THEN 1 ELSE 0 END) AS bucket1, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk))), CASE WHEN ws_ship_date_sk - ws_sold_date_sk > 60 AND ws_ship_date_sk - ws_sold_date_sk <= 90 THEN 1 ELSE 0 END) AS bucket2, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk))), CASE WHEN ws_ship_date_sk - ws_sold_date_sk > 90 AND ws_ship_date_sk - ws_sold_date_sk <= 120 THEN 1 ELSE 0 END) AS bucket3, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk))), CASE WHEN ws_ship_date_sk - ws_sold_date_sk > 120 THEN 1 ELSE 0 END) AS bucket4, + tpcds_count((priv_hash(hash(ws_bill_customer_sk))), 1) AS presence + FROM main.web_sales, + (SELECT SUBSTRING(w_warehouse_name,1,20) w_substr, + * + FROM main.warehouse) sq1, + main.ship_mode, + main.web_site, + main.date_dim, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ws_bill_customer_sk = asa_owner0.asa_key0 + AND d_month_seq BETWEEN 1200 AND 1200 + 11 + AND ws_ship_date_sk = d_date_sk + AND ws_warehouse_sk = w_warehouse_sk + AND ws_ship_mode_sk = sm_ship_mode_sk + AND ws_web_site_sk = web_site_sk +GROUP BY w_substr, + sm_type, + web_name +), answers AS ( + SELECT world, w_substr, + sm_type, + web_name, + bucket0[world+1] AS bucket0, + bucket1[world+1] AS bucket1, + bucket2[world+1] AS bucket2, + bucket3[world+1] AS bucket3, + bucket4[world+1] AS bucket4 + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY w_substr NULLS FIRST, sm_type NULLS FIRST, web_name NULLS FIRST) <= 100 +ORDER BY world, w_substr NULLS FIRST, sm_type NULLS FIRST, web_name NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q64.sql b/benchmark/tpcds/reference_queries/q64.sql new file mode 100644 index 00000000..7bdc54b3 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q64.sql @@ -0,0 +1,133 @@ +-- The first stochastic HAVING is folded into membership before the cross-sales aggregate. +WITH cs_ui_stats AS ( +SELECT cs_item_sk, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk)) & priv_hash(hash(cr_returning_customer_sk))), cs_ext_list_price) AS sale, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk)) & priv_hash(hash(cr_returning_customer_sk))), cr_refunded_cash+cr_reversed_charge+cr_store_credit) AS refund, tpcds_count((priv_hash(hash(cs_bill_customer_sk)) & priv_hash(hash(cr_returning_customer_sk))),1) AS presence +FROM main.catalog_sales, + main.catalog_returns, (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0, (SELECT c_customer_sk AS asa_key1 FROM main.customer) asa_owner1 +WHERE cs_bill_customer_sk=asa_owner0.asa_key0 AND cr_returning_customer_sk=asa_owner1.asa_key1 AND cs_item_sk = cr_item_sk + AND cs_order_number = cr_order_number + GROUP BY cs_item_sk + +), +cs_ui AS (SELECT cs_item_sk,priv_select(18446744073709551615::UBIGINT,list_transform(list_zip(sale,refund),lambda x: x[1]>2*x[2])) AS membership FROM cs_ui_stats), +cross_sales_stats AS ( +SELECT i_product_name product_name, + i_item_sk item_sk, + s_store_name store_name, + s_zip store_zip, + ad1.ca_street_number b_street_number, + ad1.ca_street_name b_street_name, + ad1.ca_city b_city, + ad1.ca_zip b_zip, + ad2.ca_street_number c_street_number, + ad2.ca_street_name c_street_name, + ad2.ca_city c_city, + ad2.ca_zip c_zip, + d1.d_year AS syear, + d2.d_year AS fsyear, + d3.d_year s2year, + tpcds_count((priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk)) & cs_ui.membership),1) cnt, + tpcds_sum((priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk)) & cs_ui.membership), ss_wholesale_cost) s1, + tpcds_sum((priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk)) & cs_ui.membership), ss_list_price) s2, + tpcds_sum((priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk)) & cs_ui.membership), ss_coupon_amt) s3, tpcds_count((priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk)) & cs_ui.membership),1) AS presence +FROM main.store_sales, + main.store_returns, + cs_ui, + main.date_dim d1, + main.date_dim d2, + main.date_dim d3, + main.store, + main.customer, + main.customer_demographics cd1, + main.customer_demographics cd2, + main.promotion, + main.household_demographics hd1, + main.household_demographics hd2, + main.customer_address ad1, + main.customer_address ad2, + main.income_band ib1, + main.income_band ib2, + main.item, (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE sr_customer_sk=asa_owner0.asa_key0 AND ss_store_sk = s_store_sk + AND ss_sold_date_sk = d1.d_date_sk + AND ss_customer_sk = c_customer_sk + AND ss_cdemo_sk= cd1.cd_demo_sk + AND ss_hdemo_sk = hd1.hd_demo_sk + AND ss_addr_sk = ad1.ca_address_sk + AND ss_item_sk = i_item_sk + AND ss_item_sk = sr_item_sk + AND ss_ticket_number = sr_ticket_number + AND ss_item_sk = cs_ui.cs_item_sk + AND c_current_cdemo_sk = cd2.cd_demo_sk + AND c_current_hdemo_sk = hd2.hd_demo_sk + AND c_current_addr_sk = ad2.ca_address_sk + AND c_first_sales_date_sk = d2.d_date_sk + AND c_first_shipto_date_sk = d3.d_date_sk + AND ss_promo_sk = p_promo_sk + AND hd1.hd_income_band_sk = ib1.ib_income_band_sk + AND hd2.hd_income_band_sk = ib2.ib_income_band_sk + AND cd1.cd_marital_status <> cd2.cd_marital_status + AND i_color IN ('purple', + 'burlywood', + 'indian', + 'spring', + 'floral', + 'medium') + AND i_current_price BETWEEN 64 AND 64 + 10 + AND i_current_price BETWEEN 64 + 1 AND 64 + 15 + GROUP BY i_product_name, + i_item_sk, + s_store_name, + s_zip, + ad1.ca_street_number, + ad1.ca_street_name, + ad1.ca_city, + ad1.ca_zip, + ad2.ca_street_number, + ad2.ca_street_name, + ad2.ca_city, + ad2.ca_zip, + d1.d_year, + d2.d_year, + d3.d_year +), +cross_sales AS ( +SELECT world, product_name, item_sk, store_name, store_zip, b_street_number, b_street_name, b_city, b_zip, c_street_number, c_street_name, c_city, c_zip, syear, fsyear, s2year, cnt[world+1] AS cnt, s1[world+1] AS s1, s2[world+1] AS s2, s3[world+1] AS s3 +FROM cross_sales_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT cs1.world AS world, cs1.product_name, + cs1.store_name, + cs1.store_zip, + cs1.b_street_number, + cs1.b_street_name, + cs1.b_city, + cs1.b_zip, + cs1.c_street_number, + cs1.c_street_name, + cs1.c_city, + cs1.c_zip, + cs1.syear cs1syear, + cs1.cnt cs1cnt, + cs1.s1 AS s11, + cs1.s2 AS s21, + cs1.s3 AS s31, + cs2.s1 AS s12, + cs2.s2 AS s22, + cs2.s3 AS s32, + cs2.syear, + cs2.cnt +FROM cross_sales cs1, + cross_sales cs2 +WHERE cs1.world=cs2.world AND cs1.item_sk=cs2.item_sk + AND cs1.syear = 1999 + AND cs2.syear = 1999 + 1 + AND cs2.cnt <= cs1.cnt + AND cs1.store_name = cs2.store_name + AND cs1.store_zip = cs2.store_zip +ORDER BY cs1.world, cs1.product_name, + cs1.store_name, + cs2.cnt, + cs1.s1, + cs2.s1; diff --git a/benchmark/tpcds/reference_queries/q65.sql b/benchmark/tpcds/reference_queries/q65.sql new file mode 100644 index 00000000..f3d32ffe --- /dev/null +++ b/benchmark/tpcds/reference_queries/q65.sql @@ -0,0 +1,17 @@ +-- Inner item revenues are shared across both outer uses; AVG remains world-specific. +WITH revenue_stats AS ( +SELECT ss_store_sk, ss_item_sk, tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_sales_price) AS revenue, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_sold_date_sk=d_date_sk AND d_month_seq BETWEEN 1176 AND 1176+11 +GROUP BY ss_store_sk, ss_item_sk +), sc AS ( +SELECT world, ss_store_sk, ss_item_sk, revenue[world+1] AS revenue +FROM revenue_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), sb AS (SELECT world, ss_store_sk, avg(revenue) AS ave FROM sc GROUP BY world, ss_store_sk) +SELECT sc.world AS world, s_store_name, i_item_desc, sc.revenue, i_current_price, i_wholesale_cost, i_brand +FROM main.store, main.item, sb, sc +WHERE sc.world=sb.world AND sb.ss_store_sk=sc.ss_store_sk AND sc.revenue<=0.1*sb.ave AND s_store_sk=sc.ss_store_sk AND i_item_sk=sc.ss_item_sk +QUALIFY row_number() OVER (PARTITION BY sc.world ORDER BY s_store_name NULLS FIRST, i_item_desc NULLS FIRST) <= 100 +ORDER BY sc.world, s_store_name NULLS FIRST, i_item_desc NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q66.sql b/benchmark/tpcds/reference_queries/q66.sql new file mode 100644 index 00000000..4e4993d8 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q66.sql @@ -0,0 +1,227 @@ +-- Shared monthly AS aggregates retain each channel's original price/profit expression. +WITH stats AS ( + + select + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,'DHL,BARIAN' as ship_carriers + ,d_year as year_ + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 1 + then ws_ext_sales_price* ws_quantity else 0 end) as jan_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 2 + then ws_ext_sales_price* ws_quantity else 0 end) as feb_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 3 + then ws_ext_sales_price* ws_quantity else 0 end) as mar_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 4 + then ws_ext_sales_price* ws_quantity else 0 end) as apr_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 5 + then ws_ext_sales_price* ws_quantity else 0 end) as may_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 6 + then ws_ext_sales_price* ws_quantity else 0 end) as jun_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 7 + then ws_ext_sales_price* ws_quantity else 0 end) as jul_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 8 + then ws_ext_sales_price* ws_quantity else 0 end) as aug_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 9 + then ws_ext_sales_price* ws_quantity else 0 end) as sep_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 10 + then ws_ext_sales_price* ws_quantity else 0 end) as oct_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 11 + then ws_ext_sales_price* ws_quantity else 0 end) as nov_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 12 + then ws_ext_sales_price* ws_quantity else 0 end) as dec_sales + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 1 + then ws_net_paid * ws_quantity else 0 end) as jan_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 2 + then ws_net_paid * ws_quantity else 0 end) as feb_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 3 + then ws_net_paid * ws_quantity else 0 end) as mar_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 4 + then ws_net_paid * ws_quantity else 0 end) as apr_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 5 + then ws_net_paid * ws_quantity else 0 end) as may_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 6 + then ws_net_paid * ws_quantity else 0 end) as jun_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 7 + then ws_net_paid * ws_quantity else 0 end) as jul_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 8 + then ws_net_paid * ws_quantity else 0 end) as aug_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 9 + then ws_net_paid * ws_quantity else 0 end) as sep_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 10 + then ws_net_paid * ws_quantity else 0 end) as oct_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 11 + then ws_net_paid * ws_quantity else 0 end) as nov_net + ,tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), case when d_moy = 12 + then ws_net_paid * ws_quantity else 0 end) as dec_net, + tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) AS presence +from + main.web_sales + ,main.warehouse + ,main.date_dim + ,main.time_dim + ,main.ship_mode, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND ws_warehouse_sk = w_warehouse_sk + and ws_sold_date_sk = d_date_sk + and ws_sold_time_sk = t_time_sk + and ws_ship_mode_sk = sm_ship_mode_sk + and d_year = 2001 + and t_time between 30838 and 30838+28800 + and sm_carrier in ('DHL','BARIAN') + group by + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,d_year + +UNION ALL + + select + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,'DHL,BARIAN' as ship_carriers + ,d_year as year_ + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 1 + then cs_sales_price* cs_quantity else 0 end) as jan_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 2 + then cs_sales_price* cs_quantity else 0 end) as feb_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 3 + then cs_sales_price* cs_quantity else 0 end) as mar_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 4 + then cs_sales_price* cs_quantity else 0 end) as apr_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 5 + then cs_sales_price* cs_quantity else 0 end) as may_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 6 + then cs_sales_price* cs_quantity else 0 end) as jun_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 7 + then cs_sales_price* cs_quantity else 0 end) as jul_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 8 + then cs_sales_price* cs_quantity else 0 end) as aug_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 9 + then cs_sales_price* cs_quantity else 0 end) as sep_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 10 + then cs_sales_price* cs_quantity else 0 end) as oct_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 11 + then cs_sales_price* cs_quantity else 0 end) as nov_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 12 + then cs_sales_price* cs_quantity else 0 end) as dec_sales + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 1 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as jan_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 2 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as feb_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 3 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as mar_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 4 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as apr_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 5 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as may_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 6 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as jun_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 7 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as jul_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 8 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as aug_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 9 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as sep_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 10 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as oct_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 11 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as nov_net + ,tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), case when d_moy = 12 + then cs_net_paid_inc_tax * cs_quantity else 0 end) as dec_net, + tpcds_count(priv_hash(hash(cs_bill_customer_sk)),1) AS presence +from + main.catalog_sales + ,main.warehouse + ,main.date_dim + ,main.time_dim + ,main.ship_mode, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND cs_warehouse_sk = w_warehouse_sk + and cs_sold_date_sk = d_date_sk + and cs_sold_time_sk = t_time_sk + and cs_ship_mode_sk = sm_ship_mode_sk + and d_year = 2001 + and t_time between 30838 AND 30838+28800 + and sm_carrier in ('DHL','BARIAN') + group by + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,d_year + +), expanded AS ( +SELECT world, w_warehouse_name, w_warehouse_sq_ft, w_city, w_county, w_state, w_country, ship_carriers, year_, jan_sales[world+1] AS jan_sales, feb_sales[world+1] AS feb_sales, mar_sales[world+1] AS mar_sales, apr_sales[world+1] AS apr_sales, may_sales[world+1] AS may_sales, jun_sales[world+1] AS jun_sales, jul_sales[world+1] AS jul_sales, aug_sales[world+1] AS aug_sales, sep_sales[world+1] AS sep_sales, oct_sales[world+1] AS oct_sales, nov_sales[world+1] AS nov_sales, dec_sales[world+1] AS dec_sales, jan_net[world+1] AS jan_net, feb_net[world+1] AS feb_net, mar_net[world+1] AS mar_net, apr_net[world+1] AS apr_net, may_net[world+1] AS may_net, jun_net[world+1] AS jun_net, jul_net[world+1] AS jul_net, aug_net[world+1] AS aug_net, sep_net[world+1] AS sep_net, oct_net[world+1] AS oct_net, nov_net[world+1] AS nov_net, dec_net[world+1] AS dec_net +FROM stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), answers AS ( +select world, + w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,ship_carriers + ,year_ + ,sum(jan_sales) as jan_sales + ,sum(feb_sales) as feb_sales + ,sum(mar_sales) as mar_sales + ,sum(apr_sales) as apr_sales + ,sum(may_sales) as may_sales + ,sum(jun_sales) as jun_sales + ,sum(jul_sales) as jul_sales + ,sum(aug_sales) as aug_sales + ,sum(sep_sales) as sep_sales + ,sum(oct_sales) as oct_sales + ,sum(nov_sales) as nov_sales + ,sum(dec_sales) as dec_sales + ,sum(jan_sales/w_warehouse_sq_ft) as jan_sales_per_sq_foot + ,sum(feb_sales/w_warehouse_sq_ft) as feb_sales_per_sq_foot + ,sum(mar_sales/w_warehouse_sq_ft) as mar_sales_per_sq_foot + ,sum(apr_sales/w_warehouse_sq_ft) as apr_sales_per_sq_foot + ,sum(may_sales/w_warehouse_sq_ft) as may_sales_per_sq_foot + ,sum(jun_sales/w_warehouse_sq_ft) as jun_sales_per_sq_foot + ,sum(jul_sales/w_warehouse_sq_ft) as jul_sales_per_sq_foot + ,sum(aug_sales/w_warehouse_sq_ft) as aug_sales_per_sq_foot + ,sum(sep_sales/w_warehouse_sq_ft) as sep_sales_per_sq_foot + ,sum(oct_sales/w_warehouse_sq_ft) as oct_sales_per_sq_foot + ,sum(nov_sales/w_warehouse_sq_ft) as nov_sales_per_sq_foot + ,sum(dec_sales/w_warehouse_sq_ft) as dec_sales_per_sq_foot + ,sum(jan_net) as jan_net + ,sum(feb_net) as feb_net + ,sum(mar_net) as mar_net + ,sum(apr_net) as apr_net + ,sum(may_net) as may_net + ,sum(jun_net) as jun_net + ,sum(jul_net) as jul_net + ,sum(aug_net) as aug_net + ,sum(sep_net) as sep_net + ,sum(oct_net) as oct_net + ,sum(nov_net) as nov_net + ,sum(dec_net) as dec_net + from expanded x + GROUP BY world, w_warehouse_name + ,w_warehouse_sq_ft + ,w_city + ,w_county + ,w_state + ,w_country + ,ship_carriers + ,year_ + +) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY w_warehouse_name NULLS FIRST)<=100 ORDER BY world,w_warehouse_name NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q68.sql b/benchmark/tpcds/reference_queries/q68.sql new file mode 100644 index 00000000..cd722de8 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q68.sql @@ -0,0 +1,56 @@ +-- AS aggregation is shared; only the reduced per-ticket results are expanded by world. +WITH stats AS ( + SELECT ss_ticket_number, + ss_customer_sk, + ca_city AS bought_city, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS extended_price, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_list_price) AS list_price, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_tax) AS extended_tax, + tpcds_count(priv_hash(hash(ss_customer_sk)), 1) AS presence + FROM main.store_sales, + main.date_dim, + main.store, + main.household_demographics, + main.customer_address, + (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key + AND store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND store_sales.ss_addr_sk = customer_address.ca_address_sk + AND date_dim.d_dom BETWEEN 1 AND 2 + AND (household_demographics.hd_dep_count = 4 + OR household_demographics.hd_vehicle_count= 3) + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_city IN ('Fairview', + 'Midway') + GROUP BY ss_ticket_number, + ss_customer_sk, + ss_addr_sk, + ca_city +), expanded AS ( + SELECT world, ss_ticket_number, ss_customer_sk, bought_city, extended_price[world+1] AS extended_price, list_price[world+1] AS list_price, extended_tax[world+1] AS extended_tax + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1]>0 +) +SELECT world, c_last_name, + c_first_name, + ca_city, + bought_city, + ss_ticket_number, + extended_price, + extended_tax, + list_price +FROM + expanded dn, + main.customer, + main.customer_address current_addr +WHERE ss_customer_sk = c_customer_sk + AND customer.c_current_addr_sk = current_addr.ca_address_sk + AND current_addr.ca_city <> bought_city +QUALIFY row_number() OVER (PARTITION BY world ORDER BY c_last_name NULLS FIRST, + ss_ticket_number NULLS FIRST) <= 100 +ORDER BY world, c_last_name NULLS FIRST, + ss_ticket_number NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q69.sql b/benchmark/tpcds/reference_queries/q69.sql new file mode 100644 index 00000000..a13757fe --- /dev/null +++ b/benchmark/tpcds/reference_queries/q69.sql @@ -0,0 +1,49 @@ +-- Same-owner EXISTS is static after entity inclusion; shipping-customer EXISTS needs the bill-owner mask. +WITH catalog_presence AS ( +SELECT cs_ship_customer_sk,bit_or(priv_hash(hash(cs_bill_customer_sk))) AS membership + FROM main.catalog_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND cs_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy BETWEEN 4 AND 4+2 +GROUP BY cs_ship_customer_sk +), stats AS (SELECT cd_gender, +cd_marital_status, +cd_education_status, +cd_purchase_estimate, +cd_credit_rating, +tpcds_count((priv_hash(hash(c.c_customer_sk)) & ~coalesce(catalog_presence.membership,0::UBIGINT)),1) AS n +FROM main.customer c CROSS JOIN + main.customer_address ca CROSS JOIN + main.customer_demographics LEFT JOIN catalog_presence ON c.c_customer_sk=cs_ship_customer_sk +WHERE c.c_current_addr_sk = ca.ca_address_sk + AND ca_state IN ('KY', + 'GA', + 'NM') + AND cd_demo_sk = c.c_current_cdemo_sk + +AND EXISTS(SELECT * + FROM main.store_sales, + main.date_dim + WHERE c.c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy BETWEEN 4 AND 4+2) +AND NOT EXISTS(SELECT * + FROM main.web_sales, + main.date_dim + WHERE c.c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year = 2001 + AND d_moy BETWEEN 4 AND 4+2) +GROUP BY cd_gender, cd_marital_status, cd_education_status, cd_purchase_estimate, cd_credit_rating +), answers AS (SELECT world, cd_gender, cd_marital_status, cd_education_status, n[world+1] AS cnt1, cd_purchase_estimate, n[world+1] AS cnt2, cd_credit_rating, n[world+1] AS cnt3 FROM stats CROSS JOIN range(64) worlds(world) WHERE n[world+1]>0) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating)<=100 ORDER BY world,cd_gender, + cd_marital_status, + cd_education_status, + cd_purchase_estimate, + cd_credit_rating; diff --git a/benchmark/tpcds/reference_queries/q72.sql b/benchmark/tpcds/reference_queries/q72.sql new file mode 100644 index 00000000..dec14f2a --- /dev/null +++ b/benchmark/tpcds/reference_queries/q72.sql @@ -0,0 +1,20 @@ +-- Matched and NULL-extended memberships are disjoint; NULL extension is evaluated separately in each world. +WITH left_input AS ( +SELECT i_item_desc,w_warehouse_name,d1.d_week_seq,p_promo_sk,cs_order_number,cs_item_sk,priv_hash(hash(cs_bill_customer_sk)) AS membership +FROM main.catalog_sales JOIN main.customer ON cs_bill_customer_sk=c_customer_sk +JOIN main.inventory ON cs_item_sk=inv_item_sk JOIN main.warehouse ON w_warehouse_sk=inv_warehouse_sk +JOIN main.item ON i_item_sk=cs_item_sk JOIN main.customer_demographics ON cs_bill_cdemo_sk=cd_demo_sk +JOIN main.household_demographics ON cs_bill_hdemo_sk=hd_demo_sk +JOIN main.date_dim d1 ON cs_sold_date_sk=d1.d_date_sk JOIN main.date_dim d2 ON inv_date_sk=d2.d_date_sk JOIN main.date_dim d3 ON cs_ship_date_sk=d3.d_date_sk +LEFT JOIN main.promotion ON cs_promo_sk=p_promo_sk +WHERE d1.d_week_seq=d2.d_week_seq AND inv_quantity_on_handd1.d_date+5 +AND hd_buy_potential='>10000' AND d1.d_year=1999 AND cd_marital_status='D' +), valid_returns AS (SELECT r.*,priv_hash(hash(cr_returning_customer_sk)) AS membership FROM main.catalog_returns r JOIN main.customer ON cr_returning_customer_sk=c_customer_sk), +return_presence AS (SELECT cr_order_number,cr_item_sk,bit_or(membership) AS membership FROM valid_returns GROUP BY cr_order_number,cr_item_sk), +joined AS ( + SELECT l.i_item_desc,l.w_warehouse_name,l.d_week_seq,l.p_promo_sk,(l.membership & r.membership) AS membership FROM left_input l JOIN valid_returns r ON l.cs_order_number=r.cr_order_number AND l.cs_item_sk=r.cr_item_sk + UNION ALL + SELECT l.i_item_desc,l.w_warehouse_name,l.d_week_seq,l.p_promo_sk,(l.membership & ~coalesce(r.membership,0::UBIGINT)) AS membership FROM left_input l LEFT JOIN return_presence r ON l.cs_order_number=r.cr_order_number AND l.cs_item_sk=r.cr_item_sk +), stats AS (SELECT i_item_desc,w_warehouse_name,d_week_seq,tpcds_sum(membership,CASE WHEN p_promo_sk IS NULL THEN 1 ELSE 0 END) AS no_promo,tpcds_sum(membership,CASE WHEN p_promo_sk IS NOT NULL THEN 1 ELSE 0 END) AS promo,tpcds_count(membership,1) AS total_cnt,tpcds_count(membership,1) AS presence FROM joined GROUP BY i_item_desc,w_warehouse_name,d_week_seq), +answers AS (SELECT world,i_item_desc,w_warehouse_name,d_week_seq,no_promo[world+1] AS no_promo,promo[world+1] AS promo,total_cnt[world+1] AS total_cnt FROM stats CROSS JOIN range(64) worlds(world) WHERE presence[world+1]>0) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY total_cnt DESC NULLS FIRST,i_item_desc NULLS FIRST,w_warehouse_name NULLS FIRST,d_week_seq NULLS FIRST)<=100 ORDER BY world,total_cnt DESC NULLS FIRST,i_item_desc NULLS FIRST,w_warehouse_name NULLS FIRST,d_week_seq NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q73.sql b/benchmark/tpcds/reference_queries/q73.sql new file mode 100644 index 00000000..b4e01e9b --- /dev/null +++ b/benchmark/tpcds/reference_queries/q73.sql @@ -0,0 +1,50 @@ +-- AS aggregation is shared; only the reduced per-ticket results are expanded by world. +WITH stats AS ( + SELECT ss_ticket_number, + ss_customer_sk, + tpcds_count(priv_hash(hash(ss_customer_sk)), 1) AS cnt, + tpcds_count(priv_hash(hash(ss_customer_sk)), 1) AS presence + FROM main.store_sales, + main.date_dim, + main.store, + main.household_demographics, + (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key + AND store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND date_dim.d_dom BETWEEN 1 AND 2 + AND (household_demographics.hd_buy_potential = 'Unknown' + OR household_demographics.hd_buy_potential = '>10000') + AND household_demographics.hd_vehicle_count > 0 + AND CASE + WHEN household_demographics.hd_vehicle_count > 0 THEN (household_demographics.hd_dep_count*1.000)/ household_demographics.hd_vehicle_count + ELSE NULL + END > 1 + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_county IN ('Orange County', + 'Bronx County', + 'Franklin Parish', + 'Williamson County') + GROUP BY ss_ticket_number, + ss_customer_sk +), expanded AS ( + SELECT world, ss_ticket_number, ss_customer_sk, cnt[world+1] AS cnt + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1]>0 +) +SELECT world, c_last_name, + c_first_name, + c_salutation, + c_preferred_cust_flag, + ss_ticket_number, + cnt +FROM + expanded dj, + main.customer +WHERE ss_customer_sk = c_customer_sk + AND cnt BETWEEN 1 AND 5 +ORDER BY world, cnt DESC, + c_last_name ASC; diff --git a/benchmark/tpcds/reference_queries/q74.sql b/benchmark/tpcds/reference_queries/q74.sql new file mode 100644 index 00000000..fa6b48b4 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q74.sql @@ -0,0 +1,74 @@ +-- Shared AS states per channel/customer/year; joins align the world index. +WITH year_total_stats AS ( +SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + d_year AS year_, + tpcds_sum(priv_hash(hash(c_customer_sk)), ss_net_paid) year_total, + 's' sale_type, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.customer, + main.store_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND c_customer_sk = ss_customer_sk + AND ss_sold_date_sk = d_date_sk + AND d_year IN (2001, + 2001+1) + GROUP BY c_customer_id, + c_first_name, + c_last_name, + d_year + +UNION ALL + SELECT c_customer_id customer_id, + c_first_name customer_first_name, + c_last_name customer_last_name, + d_year AS year_, + tpcds_sum(priv_hash(hash(c_customer_sk)), ws_net_paid) year_total, + 'w' sale_type, + tpcds_count(priv_hash(hash(c_customer_sk)),1) AS presence +FROM main.customer, + main.web_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE c_customer_sk=asa_owner.asa_key AND c_customer_sk = ws_bill_customer_sk + AND ws_sold_date_sk = d_date_sk + AND d_year IN (2001, + 2001+1) + GROUP BY c_customer_id, + c_first_name, + c_last_name, + d_year +), year_total AS ( +SELECT world, customer_id, customer_first_name, customer_last_name, year_, year_total[world+1] AS year_total, sale_type +FROM year_total_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT t_s_firstyear.world AS world, t_s_secyear.customer_id, + t_s_secyear.customer_first_name, + t_s_secyear.customer_last_name +FROM year_total t_s_firstyear, + year_total t_s_secyear, + year_total t_w_firstyear, + year_total t_w_secyear +WHERE t_s_firstyear.world=t_s_secyear.world AND t_s_firstyear.world=t_w_firstyear.world AND t_s_firstyear.world=t_w_secyear.world AND t_s_secyear.customer_id = t_s_firstyear.customer_id + AND t_s_firstyear.customer_id = t_w_secyear.customer_id + AND t_s_firstyear.customer_id = t_w_firstyear.customer_id + AND t_s_firstyear.sale_type = 's' + AND t_w_firstyear.sale_type = 'w' + AND t_s_secyear.sale_type = 's' + AND t_w_secyear.sale_type = 'w' + AND t_s_firstyear.year_ = 2001 + AND t_s_secyear.year_ = 2001+1 + AND t_w_firstyear.year_ = 2001 + AND t_w_secyear.year_ = 2001+1 + AND t_s_firstyear.year_total > 0 + AND t_w_firstyear.year_total > 0 + AND CASE + WHEN t_w_firstyear.year_total > 0 THEN t_w_secyear.year_total / t_w_firstyear.year_total + ELSE NULL + END > CASE + WHEN t_s_firstyear.year_total > 0 THEN t_s_secyear.year_total / t_s_firstyear.year_total + ELSE NULL + END +QUALIFY row_number() OVER (PARTITION BY t_s_firstyear.world ORDER BY t_s_secyear.customer_id NULLS FIRST) <= 100 +ORDER BY t_s_firstyear.world, t_s_secyear.customer_id NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q77.sql b/benchmark/tpcds/reference_queries/q77.sql new file mode 100644 index 00000000..23ef4544 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q77.sql @@ -0,0 +1,114 @@ +-- Grouped channel results retain world-local LEFT JOIN semantics and empty-world ROLLUP totals. +WITH ss_stats AS ( +SELECT s_store_sk, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_ext_sales_price) AS sales, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit) AS profit, + tpcds_count(priv_hash(hash(ss_customer_sk)),1) AS presence +FROM main.store_sales, + main.date_dim, + main.store, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND ss_store_sk = s_store_sk + GROUP BY s_store_sk +), +ss AS ( +SELECT world, s_store_sk, sales[world+1] AS sales, profit[world+1] AS profit +FROM ss_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +sr_stats AS ( +SELECT s_store_sk, + tpcds_sum(priv_hash(hash(sr_customer_sk)), sr_return_amt) AS returns_, + tpcds_sum(priv_hash(hash(sr_customer_sk)), sr_net_loss) AS profit_loss, + tpcds_count(priv_hash(hash(sr_customer_sk)),1) AS presence +FROM main.store_returns, + main.date_dim, + main.store, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE sr_customer_sk=asa_owner.asa_key AND sr_returned_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND sr_store_sk = s_store_sk + GROUP BY s_store_sk +), +sr AS ( +SELECT world, s_store_sk, returns_[world+1] AS returns_, profit_loss[world+1] AS profit_loss +FROM sr_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cs_stats AS ( +SELECT cs_call_center_sk, + tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), cs_ext_sales_price) AS sales, + tpcds_sum(priv_hash(hash(cs_bill_customer_sk)), cs_net_profit) AS profit, + tpcds_count(priv_hash(hash(cs_bill_customer_sk)),1) AS presence +FROM main.catalog_sales, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cs_bill_customer_sk=asa_owner.asa_key AND cs_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + GROUP BY cs_call_center_sk +), +cs AS ( +SELECT world, cs_call_center_sk, sales[world+1] AS sales, profit[world+1] AS profit +FROM cs_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cr_stats AS ( +SELECT cr_call_center_sk, + tpcds_sum(priv_hash(hash(cr_returning_customer_sk)), cr_return_amount) AS returns_, + tpcds_sum(priv_hash(hash(cr_returning_customer_sk)), cr_net_loss) AS profit_loss, + tpcds_count(priv_hash(hash(cr_returning_customer_sk)),1) AS presence +FROM main.catalog_returns, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cr_returning_customer_sk=asa_owner.asa_key AND cr_returned_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + GROUP BY cr_call_center_sk +), +cr AS ( +SELECT world, cr_call_center_sk, returns_[world+1] AS returns_, profit_loss[world+1] AS profit_loss +FROM cr_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +ws_stats AS ( +SELECT wp_web_page_sk, + tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), ws_ext_sales_price) AS sales, + tpcds_sum(priv_hash(hash(ws_bill_customer_sk)), ws_net_profit) AS profit, + tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) AS presence +FROM main.web_sales, + main.date_dim, + main.web_page, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND ws_sold_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND ws_web_page_sk = wp_web_page_sk + GROUP BY wp_web_page_sk +), +ws AS ( +SELECT world, wp_web_page_sk, sales[world+1] AS sales, profit[world+1] AS profit +FROM ws_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +wr_stats AS ( +SELECT wp_web_page_sk, + tpcds_sum(priv_hash(hash(wr_returning_customer_sk)), wr_return_amt) AS returns_, + tpcds_sum(priv_hash(hash(wr_returning_customer_sk)), wr_net_loss) AS profit_loss, + tpcds_count(priv_hash(hash(wr_returning_customer_sk)),1) AS presence +FROM main.web_returns, + main.date_dim, + main.web_page, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE wr_returning_customer_sk=asa_owner.asa_key AND wr_returned_date_sk = d_date_sk + AND d_date BETWEEN cast('2000-08-23' AS date) AND cast('2000-09-22' AS date) + AND wr_web_page_sk = wp_web_page_sk + GROUP BY wp_web_page_sk +), +wr AS ( +SELECT world, wp_web_page_sk, returns_[world+1] AS returns_, profit_loss[world+1] AS profit_loss +FROM wr_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +channels AS ( +SELECT ss.world,'store channel' AS channel,ss.s_store_sk AS id,sales,coalesce(returns_,0) AS returns_,profit-coalesce(profit_loss,0) AS profit FROM ss LEFT JOIN sr ON ss.world=sr.world AND ss.s_store_sk=sr.s_store_sk +UNION ALL SELECT cs.world,'catalog channel',cs_call_center_sk,sales,returns_,profit-profit_loss FROM cs JOIN cr ON cs.world=cr.world +UNION ALL SELECT ws.world,'web channel',ws.wp_web_page_sk,sales,coalesce(returns_,0),profit-coalesce(profit_loss,0) FROM ws LEFT JOIN wr ON ws.world=wr.world AND ws.wp_web_page_sk=wr.wp_web_page_sk +), +answers AS ( +SELECT w.world,g.* FROM range(64) w(world) CROSS JOIN LATERAL (SELECT channel,id,sum(sales) AS sales,sum(returns_) AS returns_,sum(profit) AS profit FROM channels WHERE channels.world=w.world GROUP BY ROLLUP(channel,id)) g +) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY channel NULLS FIRST,id NULLS FIRST,returns_ DESC)<=100 ORDER BY world,channel NULLS FIRST,id NULLS FIRST,returns_ DESC; diff --git a/benchmark/tpcds/reference_queries/q78.sql b/benchmark/tpcds/reference_queries/q78.sql new file mode 100644 index 00000000..0efa3403 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q78.sql @@ -0,0 +1,80 @@ +-- Return anti-memberships feed the per-customer/item/year AS sums before channel joins. +WITH ws_return_presence AS (SELECT wr_order_number AS order_number,wr_item_sk AS item_sk,bit_or(priv_hash(hash(wr_returning_customer_sk))) AS membership FROM main.web_returns JOIN main.customer ON wr_returning_customer_sk=c_customer_sk GROUP BY wr_order_number,wr_item_sk), +ws_stats AS ( +SELECT d_year AS ws_sold_year,ws_item_sk,ws_bill_customer_sk AS ws_customer_sk, + tpcds_sum((priv_hash(hash(ws_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),ws_quantity) AS ws_qty,tpcds_sum((priv_hash(hash(ws_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),ws_wholesale_cost) AS ws_wc,tpcds_sum((priv_hash(hash(ws_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),ws_sales_price) AS ws_sp,tpcds_count((priv_hash(hash(ws_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),1) AS presence +FROM main.web_sales JOIN main.customer ON ws_bill_customer_sk=c_customer_sk JOIN main.date_dim ON ws_sold_date_sk=d_date_sk +LEFT JOIN ws_return_presence ret ON ws_order_number=ret.order_number AND ws_item_sk=ret.item_sk +GROUP BY d_year,ws_item_sk,ws_bill_customer_sk +), +ws AS ( +SELECT world, ws_sold_year, ws_item_sk, ws_customer_sk, ws_qty[world+1] AS ws_qty, ws_wc[world+1] AS ws_wc, ws_sp[world+1] AS ws_sp +FROM ws_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cs_return_presence AS (SELECT cr_order_number AS order_number,cr_item_sk AS item_sk,bit_or(priv_hash(hash(cr_returning_customer_sk))) AS membership FROM main.catalog_returns JOIN main.customer ON cr_returning_customer_sk=c_customer_sk GROUP BY cr_order_number,cr_item_sk), +cs_stats AS ( +SELECT d_year AS cs_sold_year,cs_item_sk,cs_bill_customer_sk AS cs_customer_sk, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),cs_quantity) AS cs_qty,tpcds_sum((priv_hash(hash(cs_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),cs_wholesale_cost) AS cs_wc,tpcds_sum((priv_hash(hash(cs_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),cs_sales_price) AS cs_sp,tpcds_count((priv_hash(hash(cs_bill_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),1) AS presence +FROM main.catalog_sales JOIN main.customer ON cs_bill_customer_sk=c_customer_sk JOIN main.date_dim ON cs_sold_date_sk=d_date_sk +LEFT JOIN cs_return_presence ret ON cs_order_number=ret.order_number AND cs_item_sk=ret.item_sk +GROUP BY d_year,cs_item_sk,cs_bill_customer_sk +), +cs AS ( +SELECT world, cs_sold_year, cs_item_sk, cs_customer_sk, cs_qty[world+1] AS cs_qty, cs_wc[world+1] AS cs_wc, cs_sp[world+1] AS cs_sp +FROM cs_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +ss_return_presence AS (SELECT sr_ticket_number AS order_number,sr_item_sk AS item_sk,bit_or(priv_hash(hash(sr_customer_sk))) AS membership FROM main.store_returns JOIN main.customer ON sr_customer_sk=c_customer_sk GROUP BY sr_ticket_number,sr_item_sk), +ss_stats AS ( +SELECT d_year AS ss_sold_year,ss_item_sk,ss_customer_sk AS ss_customer_sk, + tpcds_sum((priv_hash(hash(ss_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),ss_quantity) AS ss_qty,tpcds_sum((priv_hash(hash(ss_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),ss_wholesale_cost) AS ss_wc,tpcds_sum((priv_hash(hash(ss_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),ss_sales_price) AS ss_sp,tpcds_count((priv_hash(hash(ss_customer_sk)) & ~coalesce(ret.membership,0::UBIGINT)),1) AS presence +FROM main.store_sales JOIN main.customer ON ss_customer_sk=c_customer_sk JOIN main.date_dim ON ss_sold_date_sk=d_date_sk +LEFT JOIN ss_return_presence ret ON ss_ticket_number=ret.order_number AND ss_item_sk=ret.item_sk +GROUP BY d_year,ss_item_sk,ss_customer_sk +), +ss AS ( +SELECT world, ss_sold_year, ss_item_sk, ss_customer_sk, ss_qty[world+1] AS ss_qty, ss_wc[world+1] AS ss_wc, ss_sp[world+1] AS ss_sp +FROM ss_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT ss.world AS world, ss_sold_year, + ss_item_sk, + ss_customer_sk, + round((ss_qty*1.00)/(coalesce(ws_qty,0)+coalesce(cs_qty,0)),2) ratio, + ss_qty store_qty, + ss_wc store_wholesale_cost, + ss_sp store_sales_price, + coalesce(ws_qty,0)+coalesce(cs_qty,0) other_chan_qty, + coalesce(ws_wc,0)+coalesce(cs_wc,0) other_chan_wholesale_cost, + coalesce(ws_sp,0)+coalesce(cs_sp,0) other_chan_sales_price +FROM ss +LEFT JOIN ws ON (ss.world=ws.world AND ws_sold_year=ss_sold_year + AND ws_item_sk=ss_item_sk + AND ws_customer_sk=ss_customer_sk) +LEFT JOIN cs ON (ss.world=cs.world AND cs_sold_year=ss_sold_year + AND cs_item_sk=ss_item_sk + AND cs_customer_sk=ss_customer_sk) +WHERE (coalesce(ws_qty,0)>0 + OR coalesce(cs_qty, 0)>0) + AND ss_sold_year=2000 +QUALIFY row_number() OVER (PARTITION BY ss.world ORDER BY ss_sold_year, + ss_item_sk, + ss_customer_sk, + ss_qty DESC, + ss_wc DESC, + ss_sp DESC, + other_chan_qty, + other_chan_wholesale_cost, + other_chan_sales_price, + ratio)<=100 +ORDER BY ss.world,ss_sold_year, + ss_item_sk, + ss_customer_sk, + ss_qty DESC, + ss_wc DESC, + ss_sp DESC, + other_chan_qty, + other_chan_wholesale_cost, + other_chan_sales_price, + ratio; diff --git a/benchmark/tpcds/reference_queries/q79.sql b/benchmark/tpcds/reference_queries/q79.sql new file mode 100644 index 00000000..a22b04be --- /dev/null +++ b/benchmark/tpcds/reference_queries/q79.sql @@ -0,0 +1,53 @@ +-- AS aggregation is shared; only the reduced per-ticket results are expanded by world. +WITH stats AS ( + SELECT ss_ticket_number, + ss_customer_sk, + store.s_city AS s_city, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_coupon_amt) AS amt, + tpcds_sum(priv_hash(hash(ss_customer_sk)), ss_net_profit) AS profit, + tpcds_count(priv_hash(hash(ss_customer_sk)), 1) AS presence + FROM main.store_sales, + main.date_dim, + main.store, + main.household_demographics, + (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key + AND store_sales.ss_sold_date_sk = date_dim.d_date_sk + AND store_sales.ss_store_sk = store.s_store_sk + AND store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk + AND (household_demographics.hd_dep_count = 6 + OR household_demographics.hd_vehicle_count > 2) + AND date_dim.d_dow = 1 + AND date_dim.d_year IN (1999, + 1999+1, + 1999+2) + AND store.s_number_employees BETWEEN 200 AND 295 + GROUP BY ss_ticket_number, + ss_customer_sk, + ss_addr_sk, + main.store.s_city +), expanded AS ( + SELECT world, ss_ticket_number, ss_customer_sk, s_city, amt[world+1] AS amt, profit[world+1] AS profit + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1]>0 +) +SELECT world, c_last_name, + c_first_name, + SUBSTRING(s_city,1,30), + ss_ticket_number, + amt, + profit +FROM + expanded ms, + main.customer +WHERE ss_customer_sk = c_customer_sk +QUALIFY row_number() OVER (PARTITION BY world ORDER BY c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + SUBSTRING(s_city,1,30) NULLS FIRST, + profit NULLS FIRST, + ss_ticket_number) <= 100 +ORDER BY world, c_last_name NULLS FIRST, + c_first_name NULLS FIRST, + SUBSTRING(s_city,1,30) NULLS FIRST, + profit NULLS FIRST, + ss_ticket_number; diff --git a/benchmark/tpcds/reference_queries/q80.sql b/benchmark/tpcds/reference_queries/q80.sql new file mode 100644 index 00000000..cc6e5bfb --- /dev/null +++ b/benchmark/tpcds/reference_queries/q80.sql @@ -0,0 +1,58 @@ +-- Matched/fallback row masks preserve sampled outer joins before each channel's AS aggregates. +WITH ssr_left AS ( +SELECT s_store_id AS store_id,ss_ticket_number AS order_number,ss_item_sk AS item_sk,ss_ext_sales_price AS sales_price,ss_net_profit AS net_profit,priv_hash(hash(ss_customer_sk)) AS membership +FROM main.store_sales JOIN main.customer ON ss_customer_sk=c_customer_sk JOIN main.date_dim ON ss_sold_date_sk=d_date_sk +JOIN main.store ON ss_store_sk=s_store_sk JOIN main.item ON ss_item_sk=i_item_sk JOIN main.promotion ON ss_promo_sk=p_promo_sk +WHERE d_date BETWEEN DATE '2000-08-23' AND DATE '2000-09-22' AND i_current_price>50 AND p_channel_tv='N' +), +ssr_returns AS (SELECT sr_ticket_number AS order_number,sr_item_sk AS item_sk,sr_return_amt AS amount,sr_net_loss AS loss,priv_hash(hash(sr_customer_sk)) AS membership FROM main.store_returns JOIN main.customer ON sr_customer_sk=c_customer_sk), +ssr_return_presence AS (SELECT order_number,item_sk,bit_or(membership) AS membership FROM ssr_returns GROUP BY order_number,item_sk), +ssr_joined AS ( +SELECT l.store_id,l.sales_price,l.net_profit,r.amount,r.loss,(l.membership & r.membership) AS membership FROM ssr_left l JOIN ssr_returns r ON l.order_number=r.order_number AND l.item_sk=r.item_sk +UNION ALL SELECT l.store_id,l.sales_price,l.net_profit,0 AS amount,0 AS loss,(l.membership & ~coalesce(r.membership,0::UBIGINT)) AS membership FROM ssr_left l LEFT JOIN ssr_return_presence r ON l.order_number=r.order_number AND l.item_sk=r.item_sk +), +ssr_stats AS (SELECT store_id,tpcds_sum(membership,sales_price) AS sales,tpcds_sum(membership,coalesce(amount,0)) AS returns_,tpcds_sum(membership,net_profit-coalesce(loss,0)) AS profit,tpcds_count(membership,1) AS presence FROM ssr_joined GROUP BY store_id), +ssr AS ( +SELECT world, store_id, sales[world+1] AS sales, returns_[world+1] AS returns_, profit[world+1] AS profit +FROM ssr_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +csr_left AS ( +SELECT cp_catalog_page_id AS catalog_page_id,cs_order_number AS order_number,cs_item_sk AS item_sk,cs_ext_sales_price AS sales_price,cs_net_profit AS net_profit,priv_hash(hash(cs_bill_customer_sk)) AS membership +FROM main.catalog_sales JOIN main.customer ON cs_bill_customer_sk=c_customer_sk JOIN main.date_dim ON cs_sold_date_sk=d_date_sk +JOIN main.catalog_page ON cs_catalog_page_sk=cp_catalog_page_sk JOIN main.item ON cs_item_sk=i_item_sk JOIN main.promotion ON cs_promo_sk=p_promo_sk +WHERE d_date BETWEEN DATE '2000-08-23' AND DATE '2000-09-22' AND i_current_price>50 AND p_channel_tv='N' +), +csr_returns AS (SELECT cr_order_number AS order_number,cr_item_sk AS item_sk,cr_return_amount AS amount,cr_net_loss AS loss,priv_hash(hash(cr_returning_customer_sk)) AS membership FROM main.catalog_returns JOIN main.customer ON cr_returning_customer_sk=c_customer_sk), +csr_return_presence AS (SELECT order_number,item_sk,bit_or(membership) AS membership FROM csr_returns GROUP BY order_number,item_sk), +csr_joined AS ( +SELECT l.catalog_page_id,l.sales_price,l.net_profit,r.amount,r.loss,(l.membership & r.membership) AS membership FROM csr_left l JOIN csr_returns r ON l.order_number=r.order_number AND l.item_sk=r.item_sk +UNION ALL SELECT l.catalog_page_id,l.sales_price,l.net_profit,0 AS amount,0 AS loss,(l.membership & ~coalesce(r.membership,0::UBIGINT)) AS membership FROM csr_left l LEFT JOIN csr_return_presence r ON l.order_number=r.order_number AND l.item_sk=r.item_sk +), +csr_stats AS (SELECT catalog_page_id,tpcds_sum(membership,sales_price) AS sales,tpcds_sum(membership,coalesce(amount,0)) AS returns_,tpcds_sum(membership,net_profit-coalesce(loss,0)) AS profit,tpcds_count(membership,1) AS presence FROM csr_joined GROUP BY catalog_page_id), +csr AS ( +SELECT world, catalog_page_id, sales[world+1] AS sales, returns_[world+1] AS returns_, profit[world+1] AS profit +FROM csr_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +wsr_left AS ( +SELECT web_site_id AS web_site_id,ws_order_number AS order_number,ws_item_sk AS item_sk,ws_ext_sales_price AS sales_price,ws_net_profit AS net_profit,priv_hash(hash(ws_bill_customer_sk)) AS membership +FROM main.web_sales JOIN main.customer ON ws_bill_customer_sk=c_customer_sk JOIN main.date_dim ON ws_sold_date_sk=d_date_sk +JOIN main.web_site ON ws_web_site_sk=web_site_sk JOIN main.item ON ws_item_sk=i_item_sk JOIN main.promotion ON ws_promo_sk=p_promo_sk +WHERE d_date BETWEEN DATE '2000-08-23' AND DATE '2000-09-22' AND i_current_price>50 AND p_channel_tv='N' +), +wsr_returns AS (SELECT wr_order_number AS order_number,wr_item_sk AS item_sk,wr_return_amt AS amount,wr_net_loss AS loss,priv_hash(hash(wr_returning_customer_sk)) AS membership FROM main.web_returns JOIN main.customer ON wr_returning_customer_sk=c_customer_sk), +wsr_return_presence AS (SELECT order_number,item_sk,bit_or(membership) AS membership FROM wsr_returns GROUP BY order_number,item_sk), +wsr_joined AS ( +SELECT l.web_site_id,l.sales_price,l.net_profit,r.amount,r.loss,(l.membership & r.membership) AS membership FROM wsr_left l JOIN wsr_returns r ON l.order_number=r.order_number AND l.item_sk=r.item_sk +UNION ALL SELECT l.web_site_id,l.sales_price,l.net_profit,0 AS amount,0 AS loss,(l.membership & ~coalesce(r.membership,0::UBIGINT)) AS membership FROM wsr_left l LEFT JOIN wsr_return_presence r ON l.order_number=r.order_number AND l.item_sk=r.item_sk +), +wsr_stats AS (SELECT web_site_id,tpcds_sum(membership,sales_price) AS sales,tpcds_sum(membership,coalesce(amount,0)) AS returns_,tpcds_sum(membership,net_profit-coalesce(loss,0)) AS profit,tpcds_count(membership,1) AS presence FROM wsr_joined GROUP BY web_site_id), +wsr AS ( +SELECT world, web_site_id, sales[world+1] AS sales, returns_[world+1] AS returns_, profit[world+1] AS profit +FROM wsr_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +channels AS (SELECT world,'store channel' AS channel,concat('store',store_id) AS id,sales,returns_,profit FROM ssr UNION ALL SELECT world,'catalog channel',concat('catalog_page',catalog_page_id),sales,returns_,profit FROM csr UNION ALL SELECT world,'web channel',concat('web_site',web_site_id),sales,returns_,profit FROM wsr), +answers AS (SELECT w.world,g.* FROM range(64) w(world) CROSS JOIN LATERAL (SELECT channel,id,sum(sales) AS sales,sum(returns_) AS returns_,sum(profit) AS profit FROM channels WHERE channels.world=w.world GROUP BY ROLLUP(channel,id)) g) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY channel NULLS FIRST,id NULLS FIRST)<=100 ORDER BY world,channel NULLS FIRST,id NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q81.sql b/benchmark/tpcds/reference_queries/q81.sql new file mode 100644 index 00000000..ffe67f71 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q81.sql @@ -0,0 +1,77 @@ +-- Correlated thresholds use only the matching world of the reduced return aggregates. +WITH return_stats AS ( +SELECT cr_returning_customer_sk AS ctr_customer_sk , + ca_state AS ctr_state, + tpcds_sum(priv_hash(hash(cr_returning_customer_sk)), cr_return_amt_inc_tax) AS ctr_total_return, + tpcds_count(priv_hash(hash(cr_returning_customer_sk)),1) AS presence +FROM main.catalog_returns , + main.date_dim , + main.customer_address, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cr_returning_customer_sk=asa_owner.asa_key AND cr_returned_date_sk = d_date_sk + AND d_year = 2000 + AND cr_returning_addr_sk = ca_address_sk + GROUP BY cr_returning_customer_sk , + ca_state +), customer_total_return AS ( +SELECT world, ctr_customer_sk, ctr_state, ctr_total_return[world+1] AS ctr_total_return +FROM return_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT ctr1.world AS world, c_customer_id, + c_salutation, + c_first_name, + c_last_name, + ca_street_number, + ca_street_name , + ca_street_type, + ca_suite_number, + ca_city, + ca_county, + ca_state, + ca_zip, + ca_country, + ca_gmt_offset , + ca_location_type, + ctr_total_return +FROM customer_total_return ctr1 , + main.customer_address , + main.customer +WHERE ctr1.ctr_total_return > + (SELECT avg(ctr_total_return)*1.2 + FROM customer_total_return ctr2 + WHERE ctr1.world=ctr2.world AND ctr1.ctr_state = ctr2.ctr_state) + AND ca_address_sk = c_current_addr_sk + AND ca_state = 'GA' + AND ctr1.ctr_customer_sk = c_customer_sk +QUALIFY row_number() OVER (PARTITION BY ctr1.world ORDER BY c_customer_id, + c_salutation, + c_first_name, + c_last_name, + ca_street_number, + ca_street_name , + ca_street_type, + ca_suite_number, + ca_city, + ca_county, + ca_state, + ca_zip, + ca_country, + ca_gmt_offset , + ca_location_type, + ctr_total_return) <= 100 +ORDER BY ctr1.world, c_customer_id, + c_salutation, + c_first_name, + c_last_name, + ca_street_number, + ca_street_name , + ca_street_type, + ca_suite_number, + ca_city, + ca_county, + ca_state, + ca_zip, + ca_country, + ca_gmt_offset , + ca_location_type, + ctr_total_return; diff --git a/benchmark/tpcds/reference_queries/q83.sql b/benchmark/tpcds/reference_queries/q83.sql new file mode 100644 index 00000000..ba388e54 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q83.sql @@ -0,0 +1,93 @@ +-- Each return channel is aggregated once, then joined on item and world. +WITH sr_items_stats AS ( +SELECT i_item_id item_id, + tpcds_sum(priv_hash(hash(sr_customer_sk)), sr_return_quantity) sr_item_qty, + tpcds_count(priv_hash(hash(sr_customer_sk)),1) AS presence +FROM main.store_returns, + main.item, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE sr_customer_sk=asa_owner.asa_key AND sr_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM main.date_dim + WHERE d_week_seq IN + (SELECT d_week_seq + FROM main.date_dim + WHERE d_date IN ('2000-06-30', + '2000-09-27', + '2000-11-17'))) + AND sr_returned_date_sk = d_date_sk + GROUP BY i_item_id +), +sr_items AS ( +SELECT world, item_id, sr_item_qty[world+1] AS sr_item_qty +FROM sr_items_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +cr_items_stats AS ( +SELECT i_item_id item_id, + tpcds_sum(priv_hash(hash(cr_returning_customer_sk)), cr_return_quantity) cr_item_qty, + tpcds_count(priv_hash(hash(cr_returning_customer_sk)),1) AS presence +FROM main.catalog_returns, + main.item, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE cr_returning_customer_sk=asa_owner.asa_key AND cr_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM main.date_dim + WHERE d_week_seq IN + (SELECT d_week_seq + FROM main.date_dim + WHERE d_date IN ('2000-06-30', + '2000-09-27', + '2000-11-17'))) + AND cr_returned_date_sk = d_date_sk + GROUP BY i_item_id +), +cr_items AS ( +SELECT world, item_id, cr_item_qty[world+1] AS cr_item_qty +FROM cr_items_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +), +wr_items_stats AS ( +SELECT i_item_id item_id, + tpcds_sum(priv_hash(hash(wr_returning_customer_sk)), wr_return_quantity) wr_item_qty, + tpcds_count(priv_hash(hash(wr_returning_customer_sk)),1) AS presence +FROM main.web_returns, + main.item, + main.date_dim, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE wr_returning_customer_sk=asa_owner.asa_key AND wr_item_sk = i_item_sk + AND d_date IN + (SELECT d_date + FROM main.date_dim + WHERE d_week_seq IN + (SELECT d_week_seq + FROM main.date_dim + WHERE d_date IN ('2000-06-30', + '2000-09-27', + '2000-11-17'))) + AND wr_returned_date_sk = d_date_sk + GROUP BY i_item_id +), +wr_items AS ( +SELECT world, item_id, wr_item_qty[world+1] AS wr_item_qty +FROM wr_items_stats CROSS JOIN range(64) worlds(world) +WHERE presence[world+1]>0 +) +SELECT sr_items.world AS world, sr_items.item_id , + sr_item_qty , + (sr_item_qty*1.0000)/(sr_item_qty+cr_item_qty+wr_item_qty)/3.0000 * 100 sr_dev , + cr_item_qty , + (cr_item_qty*1.0000)/(sr_item_qty+cr_item_qty+wr_item_qty)/3.0000 * 100 cr_dev , + wr_item_qty , + (wr_item_qty*1.0000)/(sr_item_qty+cr_item_qty+wr_item_qty)/3.0000 * 100 wr_dev , + (sr_item_qty+cr_item_qty+wr_item_qty)/3.0 average +FROM sr_items , + cr_items , + wr_items +WHERE sr_items.world=cr_items.world AND sr_items.world=wr_items.world AND sr_items.item_id=cr_items.item_id + AND sr_items.item_id=wr_items.item_id +QUALIFY row_number() OVER (PARTITION BY sr_items.world ORDER BY sr_items.item_id NULLS FIRST, + sr_item_qty NULLS FIRST) <= 100 +ORDER BY sr_items.world, sr_items.item_id NULLS FIRST, + sr_item_qty NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q85.sql b/benchmark/tpcds/reference_queries/q85.sql new file mode 100644 index 00000000..746882d7 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q85.sql @@ -0,0 +1,68 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT SUBSTRING(r_reason_desc,1,20) AS reason, + tpcds_avg((priv_hash(hash(ws_bill_customer_sk)) & priv_hash(hash(wr_returning_customer_sk))), ws_quantity) AS avg1, + tpcds_avg((priv_hash(hash(ws_bill_customer_sk)) & priv_hash(hash(wr_returning_customer_sk))), wr_refunded_cash) AS avg2, + tpcds_avg((priv_hash(hash(ws_bill_customer_sk)) & priv_hash(hash(wr_returning_customer_sk))), wr_fee) AS avg3, + tpcds_count((priv_hash(hash(ws_bill_customer_sk)) & priv_hash(hash(wr_returning_customer_sk))), 1) AS presence + FROM main.web_sales, + main.web_returns, + main.web_page, + main.customer_demographics cd1, + main.customer_demographics cd2, + main.customer_address, + main.date_dim, + main.reason, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0, (SELECT c_customer_sk AS asa_key1 FROM main.customer) asa_owner1 +WHERE ws_bill_customer_sk = asa_owner0.asa_key0 AND wr_returning_customer_sk = asa_owner1.asa_key1 + AND ws_web_page_sk = wp_web_page_sk + AND ws_item_sk = wr_item_sk + AND ws_order_number = wr_order_number + AND ws_sold_date_sk = d_date_sk + AND d_year = 2000 + AND cd1.cd_demo_sk = wr_refunded_cdemo_sk + AND cd2.cd_demo_sk = wr_returning_cdemo_sk + AND ca_address_sk = wr_refunded_addr_sk + AND r_reason_sk = wr_reason_sk + AND ( ( cd1.cd_marital_status = 'M' + AND cd1.cd_marital_status = cd2.cd_marital_status + AND cd1.cd_education_status = 'Advanced Degree' + AND cd1.cd_education_status = cd2.cd_education_status + AND ws_sales_price BETWEEN 100.00 AND 150.00 ) + OR ( cd1.cd_marital_status = 'S' + AND cd1.cd_marital_status = cd2.cd_marital_status + AND cd1.cd_education_status = 'College' + AND cd1.cd_education_status = cd2.cd_education_status + AND ws_sales_price BETWEEN 50.00 AND 100.00 ) + OR ( cd1.cd_marital_status = 'W' + AND cd1.cd_marital_status = cd2.cd_marital_status + AND cd1.cd_education_status = '2 yr Degree' + AND cd1.cd_education_status = cd2.cd_education_status + AND ws_sales_price BETWEEN 150.00 AND 200.00 ) ) + AND ( ( ca_country = 'United States' + AND ca_state IN ('IN', + 'OH', + 'NJ') + AND ws_net_profit BETWEEN 100 AND 200) + OR ( ca_country = 'United States' + AND ca_state IN ('WI', + 'CT', + 'KY') + AND ws_net_profit BETWEEN 150 AND 300) + OR ( ca_country = 'United States' + AND ca_state IN ('LA', + 'IA', + 'AR') + AND ws_net_profit BETWEEN 50 AND 250) ) +GROUP BY r_reason_desc +), answers AS ( + SELECT world, reason, + avg1[world+1] AS avg1, + avg2[world+1] AS avg2, + avg3[world+1] AS avg3 + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY reason, avg1, avg2, avg3) <= 100 +ORDER BY world, reason, avg1, avg2, avg3; diff --git a/benchmark/tpcds/reference_queries/q88.sql b/benchmark/tpcds/reference_queries/q88.sql new file mode 100644 index 00000000..4cd5e384 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q88.sql @@ -0,0 +1,25 @@ +-- All time-bucket counters share the fact/dimension joins. +WITH stats AS (SELECT tpcds_count(CASE WHEN t_hour=8 AND t_minute >= 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h8_30_to_9, +tpcds_count(CASE WHEN t_hour=9 AND t_minute < 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h9_to_9_30, +tpcds_count(CASE WHEN t_hour=9 AND t_minute >= 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h9_30_to_10, +tpcds_count(CASE WHEN t_hour=10 AND t_minute < 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h10_to_10_30, +tpcds_count(CASE WHEN t_hour=10 AND t_minute >= 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h10_30_to_11, +tpcds_count(CASE WHEN t_hour=11 AND t_minute < 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h11_to_11_30, +tpcds_count(CASE WHEN t_hour=11 AND t_minute >= 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h11_30_to_12, +tpcds_count(CASE WHEN t_hour=12 AND t_minute < 30 THEN priv_hash(hash(ss_customer_sk)) ELSE 0::UBIGINT END,1) AS h12_to_12_30 +FROM main.store_sales, + main.household_demographics, + main.time_dim, + main.store, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ss_customer_sk=asa_owner.asa_key AND ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND ((household_demographics.hd_dep_count = 4 + AND household_demographics.hd_vehicle_count<=4+2) + OR (household_demographics.hd_dep_count = 2 + AND household_demographics.hd_vehicle_count<=2+2) + OR (household_demographics.hd_dep_count = 0 + AND household_demographics.hd_vehicle_count<=0+2)) + AND store.s_store_name = 'ese' +) +SELECT world,h8_30_to_9[world+1] AS h8_30_to_9, h9_to_9_30[world+1] AS h9_to_9_30, h9_30_to_10[world+1] AS h9_30_to_10, h10_to_10_30[world+1] AS h10_to_10_30, h10_30_to_11[world+1] AS h10_30_to_11, h11_to_11_30[world+1] AS h11_to_11_30, h11_30_to_12[world+1] AS h11_30_to_12, h12_to_12_30[world+1] AS h12_to_12_30 FROM stats CROSS JOIN range(64) worlds(world) ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q90.sql b/benchmark/tpcds/reference_queries/q90.sql new file mode 100644 index 00000000..6e279282 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q90.sql @@ -0,0 +1,30 @@ +-- Scalar AS arrays are combined only after their independent shared scans. +WITH raw0 AS ( +SELECT tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) amc + FROM main.web_sales, + main.household_demographics, + main.time_dim, + main.web_page, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND ws_sold_time_sk = time_dim.t_time_sk + AND ws_ship_hdemo_sk = household_demographics.hd_demo_sk + AND ws_web_page_sk = web_page.wp_web_page_sk + AND time_dim.t_hour BETWEEN 8 AND 8+1 + AND household_demographics.hd_dep_count = 6 + AND web_page.wp_char_count BETWEEN 5000 AND 5200 +), +raw1 AS ( +SELECT tpcds_count(priv_hash(hash(ws_bill_customer_sk)),1) pmc + FROM main.web_sales, + main.household_demographics, + main.time_dim, + main.web_page, (SELECT c_customer_sk AS asa_key FROM main.customer) asa_owner +WHERE ws_bill_customer_sk=asa_owner.asa_key AND ws_sold_time_sk = time_dim.t_time_sk + AND ws_ship_hdemo_sk = household_demographics.hd_demo_sk + AND ws_web_page_sk = web_page.wp_web_page_sk + AND time_dim.t_hour BETWEEN 19 AND 19+1 + AND household_demographics.hd_dep_count = 6 + AND web_page.wp_char_count BETWEEN 5000 AND 5200 +), +p AS (SELECT world, raw0.amc[world+1] AS amc, raw1.pmc[world+1] AS pmc FROM raw0 CROSS JOIN raw1 CROSS JOIN range(64) worlds(world)) +SELECT world, case when p.pmc=0 then null else cast(p.amc AS decimal(15,4))/cast(p.pmc AS decimal(15,4)) end am_pm_ratio + FROM p ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q91.sql b/benchmark/tpcds/reference_queries/q91.sql new file mode 100644 index 00000000..d3c9ad21 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q91.sql @@ -0,0 +1,44 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT cc_call_center_id AS call_center, + cc_name AS call_center_name, + cc_manager AS manager, + tpcds_sum((priv_hash(hash(cr_returning_customer_sk))), cr_net_loss) AS returns_loss, + tpcds_count((priv_hash(hash(cr_returning_customer_sk))), 1) AS presence + FROM main.call_center, + main.catalog_returns, + main.date_dim, + main.customer, + main.customer_address, + main.customer_demographics, + main.household_demographics, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE cr_returning_customer_sk = asa_owner0.asa_key0 + AND cr_call_center_sk = cc_call_center_sk + AND cr_returned_date_sk = d_date_sk + AND cr_returning_customer_sk= c_customer_sk + AND cd_demo_sk = c_current_cdemo_sk + AND hd_demo_sk = c_current_hdemo_sk + AND ca_address_sk = c_current_addr_sk + AND d_year = 1998 + AND d_moy = 11 + AND ((cd_marital_status = 'M' + AND cd_education_status = 'Unknown') or(cd_marital_status = 'W' + AND cd_education_status = 'Advanced Degree')) + AND hd_buy_potential LIKE 'Unknown%' + AND ca_gmt_offset = -7 +GROUP BY cc_call_center_id, + cc_name, + cc_manager, + cd_marital_status, + cd_education_status +), answers AS ( + SELECT world, call_center, + call_center_name, + manager, + returns_loss[world+1] AS returns_loss + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +ORDER BY world, returns_loss DESC; diff --git a/benchmark/tpcds/reference_queries/q92.sql b/benchmark/tpcds/reference_queries/q92.sql new file mode 100644 index 00000000..f8fc761b --- /dev/null +++ b/benchmark/tpcds/reference_queries/q92.sql @@ -0,0 +1,14 @@ +-- Correlated aggregate predicates update the mask before the outer AS SUM. +WITH thresholds AS ( + SELECT ws_item_sk, tpcds_avg(priv_hash(hash(ws_bill_customer_sk)),ws_ext_discount_amt) AS averages + FROM main.web_sales JOIN main.customer ON ws_bill_customer_sk=c_customer_sk JOIN main.date_dim ON ws_sold_date_sk=d_date_sk + WHERE d_date BETWEEN DATE '2000-01-27' AND DATE '2000-04-26' GROUP BY ws_item_sk +), filtered AS ( + SELECT s.ws_ext_discount_amt AS discount, + priv_select(priv_hash(hash(ws_bill_customer_sk)),list_transform(averages, lambda average: s.ws_ext_discount_amt>1.3*average)) AS membership + FROM main.web_sales s JOIN main.customer ON ws_bill_customer_sk=c_customer_sk + JOIN main.item ON s.ws_item_sk=i_item_sk JOIN main.date_dim ON s.ws_sold_date_sk=d_date_sk + JOIN thresholds t ON s.ws_item_sk=t.ws_item_sk + WHERE i_manufact_id=350 AND d_date BETWEEN DATE '2000-01-27' AND DATE '2000-04-26' +), stats AS (SELECT tpcds_sum(membership,discount) AS total FROM filtered) +SELECT world,total[world+1] AS excess_discount_amount FROM stats CROSS JOIN range(64) worlds(world) ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q93.sql b/benchmark/tpcds/reference_queries/q93.sql new file mode 100644 index 00000000..3a14d36b --- /dev/null +++ b/benchmark/tpcds/reference_queries/q93.sql @@ -0,0 +1,12 @@ +-- The reason predicate rejects unmatched returns; both owners must be present. +WITH input AS ( + SELECT ss_customer_sk,CASE WHEN sr_return_quantity IS NOT NULL THEN (ss_quantity-sr_return_quantity)*ss_sales_price ELSE ss_quantity*ss_sales_price END AS act_sales, + (priv_hash(hash(ss_customer_sk)) & priv_hash(hash(sr_customer_sk))) AS membership + FROM main.store_sales JOIN main.store_returns ON sr_item_sk=ss_item_sk AND sr_ticket_number=ss_ticket_number + JOIN main.reason ON sr_reason_sk=r_reason_sk + JOIN main.customer sale_owner ON ss_customer_sk=sale_owner.c_customer_sk + JOIN main.customer return_owner ON sr_customer_sk=return_owner.c_customer_sk + WHERE r_reason_desc='reason 28' +), stats AS (SELECT ss_customer_sk,tpcds_sum(membership,act_sales) AS sumsales,tpcds_count(membership,1) AS presence FROM input GROUP BY ss_customer_sk), +answers AS (SELECT world,ss_customer_sk,sumsales[world+1] AS sumsales FROM stats CROSS JOIN range(64) worlds(world) WHERE presence[world+1]>0) +SELECT * FROM answers QUALIFY row_number() OVER (PARTITION BY world ORDER BY sumsales NULLS FIRST,ss_customer_sk NULLS FIRST)<=100 ORDER BY world,sumsales NULLS FIRST,ss_customer_sk NULLS FIRST; diff --git a/benchmark/tpcds/reference_queries/q94.sql b/benchmark/tpcds/reference_queries/q94.sql new file mode 100644 index 00000000..708051dc --- /dev/null +++ b/benchmark/tpcds/reference_queries/q94.sql @@ -0,0 +1,10 @@ +-- Order-level existence masks are combined before AS; DISTINCT unions memberships by order. +WITH warehouses AS (SELECT ws_order_number AS order_number,ws_warehouse_sk AS warehouse,bit_or(priv_hash(hash(ws_bill_customer_sk))) AS membership FROM main.web_sales JOIN main.customer ON ws_bill_customer_sk=c_customer_sk GROUP BY ws_order_number,ws_warehouse_sk), +other_warehouses AS (SELECT a.order_number,a.warehouse,bit_or(b.membership) AS membership FROM warehouses a JOIN warehouses b ON a.order_number=b.order_number AND a.warehouse<>b.warehouse GROUP BY a.order_number,a.warehouse), +return_orders AS (SELECT wr_order_number AS order_number,bit_or(priv_hash(hash(wr_returning_customer_sk))) AS membership FROM main.web_returns JOIN main.customer ON wr_returning_customer_sk=c_customer_sk GROUP BY wr_order_number), +input AS (SELECT ws_order_number AS order_number,ws_ext_ship_cost AS shipping,ws_net_profit AS profit,(priv_hash(hash(ws_bill_customer_sk)) & other.membership & ~coalesce(ret.membership,0::UBIGINT)) AS membership +FROM main.web_sales JOIN main.customer ON ws_bill_customer_sk=c_customer_sk JOIN main.date_dim ON ws_ship_date_sk=d_date_sk JOIN main.customer_address ON ws_ship_addr_sk=ca_address_sk JOIN main.web_site ON ws_web_site_sk=web_site_sk JOIN other_warehouses other ON ws_order_number=other.order_number AND ws_warehouse_sk=other.warehouse LEFT JOIN return_orders ret ON ws_order_number=ret.order_number WHERE d_date BETWEEN DATE '1999-02-01' AND DATE '1999-04-02' AND ca_state='IL' AND web_company_name='pri'), +totals AS (SELECT tpcds_sum(membership,shipping) AS shipping,tpcds_sum(membership,profit) AS profit FROM input), +unique_orders AS (SELECT order_number,bit_or(membership) AS membership FROM input GROUP BY order_number), +counts AS (SELECT tpcds_count(membership,1) AS n FROM unique_orders) +SELECT world,n[world+1] AS order_count,shipping[world+1] AS total_shipping_cost,profit[world+1] AS total_net_profit FROM totals CROSS JOIN counts CROSS JOIN range(64) worlds(world) ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q95.sql b/benchmark/tpcds/reference_queries/q95.sql new file mode 100644 index 00000000..7eb87985 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q95.sql @@ -0,0 +1,10 @@ +-- Order-level existence masks are combined before AS; DISTINCT unions memberships by order. +WITH warehouses AS (SELECT ws_order_number AS order_number,ws_warehouse_sk AS warehouse,bit_or(priv_hash(hash(ws_bill_customer_sk))) AS membership FROM main.web_sales JOIN main.customer ON ws_bill_customer_sk=c_customer_sk GROUP BY ws_order_number,ws_warehouse_sk), +pair_orders AS (SELECT a.order_number,bit_or(a.membership & b.membership) AS membership FROM warehouses a JOIN warehouses b ON a.order_number=b.order_number AND a.warehouse<>b.warehouse GROUP BY a.order_number), +return_orders AS (SELECT wr_order_number AS order_number,bit_or(priv_hash(hash(wr_returning_customer_sk))) AS membership FROM main.web_returns JOIN main.customer ON wr_returning_customer_sk=c_customer_sk GROUP BY wr_order_number), +input AS (SELECT ws_order_number AS order_number,ws_ext_ship_cost AS shipping,ws_net_profit AS profit,(priv_hash(hash(ws_bill_customer_sk)) & other.membership & coalesce(ret.membership,0::UBIGINT)) AS membership +FROM main.web_sales JOIN main.customer ON ws_bill_customer_sk=c_customer_sk JOIN main.date_dim ON ws_ship_date_sk=d_date_sk JOIN main.customer_address ON ws_ship_addr_sk=ca_address_sk JOIN main.web_site ON ws_web_site_sk=web_site_sk JOIN pair_orders other ON ws_order_number=other.order_number LEFT JOIN return_orders ret ON ws_order_number=ret.order_number WHERE d_date BETWEEN DATE '1999-02-01' AND DATE '1999-04-02' AND ca_state='IL' AND web_company_name='pri'), +totals AS (SELECT tpcds_sum(membership,shipping) AS shipping,tpcds_sum(membership,profit) AS profit FROM input), +unique_orders AS (SELECT order_number,bit_or(membership) AS membership FROM input GROUP BY order_number), +counts AS (SELECT tpcds_count(membership,1) AS n FROM unique_orders) +SELECT world,n[world+1] AS order_count,shipping[world+1] AS total_shipping_cost,profit[world+1] AS total_net_profit FROM totals CROSS JOIN counts CROSS JOIN range(64) worlds(world) ORDER BY world; diff --git a/benchmark/tpcds/reference_queries/q96.sql b/benchmark/tpcds/reference_queries/q96.sql new file mode 100644 index 00000000..f14f19b0 --- /dev/null +++ b/benchmark/tpcds/reference_queries/q96.sql @@ -0,0 +1,24 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS total, + tpcds_count((priv_hash(hash(ss_customer_sk))), 1) AS presence + FROM main.store_sales , + main.household_demographics, + main.time_dim, + main.store, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE ss_customer_sk = asa_owner0.asa_key0 + AND ss_sold_time_sk = time_dim.t_time_sk + AND ss_hdemo_sk = household_demographics.hd_demo_sk + AND ss_store_sk = s_store_sk + AND time_dim.t_hour = 20 + AND time_dim.t_minute >= 30 + AND household_demographics.hd_dep_count = 7 + AND store.s_store_name = 'ese' +), answers AS ( + SELECT world, total[world+1] AS total + FROM stats CROSS JOIN range(64) worlds(world) +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY total) <= 100 +ORDER BY world, total; diff --git a/benchmark/tpcds/reference_queries/q99.sql b/benchmark/tpcds/reference_queries/q99.sql new file mode 100644 index 00000000..2366503a --- /dev/null +++ b/benchmark/tpcds/reference_queries/q99.sql @@ -0,0 +1,42 @@ +-- Explicit AS query; tpcds_* macros normalize the public aggregate scaling and NULL semantics. +WITH stats AS ( + SELECT w_substr, + sm_type, + LOWER(cc_name) AS cc_name_lower, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk))), CASE WHEN cs_ship_date_sk - cs_sold_date_sk <= 30 THEN 1 ELSE 0 END) AS bucket0, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk))), CASE WHEN cs_ship_date_sk - cs_sold_date_sk > 30 AND cs_ship_date_sk - cs_sold_date_sk <= 60 THEN 1 ELSE 0 END) AS bucket1, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk))), CASE WHEN cs_ship_date_sk - cs_sold_date_sk > 60 AND cs_ship_date_sk - cs_sold_date_sk <= 90 THEN 1 ELSE 0 END) AS bucket2, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk))), CASE WHEN cs_ship_date_sk - cs_sold_date_sk > 90 AND cs_ship_date_sk - cs_sold_date_sk <= 120 THEN 1 ELSE 0 END) AS bucket3, + tpcds_sum((priv_hash(hash(cs_bill_customer_sk))), CASE WHEN cs_ship_date_sk - cs_sold_date_sk > 120 THEN 1 ELSE 0 END) AS bucket4, + tpcds_count((priv_hash(hash(cs_bill_customer_sk))), 1) AS presence + FROM main.catalog_sales , + (SELECT SUBSTRING(w_warehouse_name,1,20) w_substr, * + FROM main.warehouse) AS sq1 , + main.ship_mode , + main.call_center , + main.date_dim, + (SELECT c_customer_sk AS asa_key0 FROM main.customer) asa_owner0 +WHERE cs_bill_customer_sk = asa_owner0.asa_key0 + AND d_month_seq BETWEEN 1200 AND 1200 + 11 + AND cs_ship_date_sk = d_date_sk + AND cs_warehouse_sk = w_warehouse_sk + AND cs_ship_mode_sk = sm_ship_mode_sk + AND cs_call_center_sk = cc_call_center_sk +GROUP BY w_substr , + sm_type , + cc_name +), answers AS ( + SELECT world, w_substr, + sm_type, + cc_name_lower, + bucket0[world+1] AS bucket0, + bucket1[world+1] AS bucket1, + bucket2[world+1] AS bucket2, + bucket3[world+1] AS bucket3, + bucket4[world+1] AS bucket4 + FROM stats CROSS JOIN range(64) worlds(world) + WHERE presence[world+1] > 0 +) +SELECT * FROM answers +QUALIFY row_number() OVER (PARTITION BY world ORDER BY w_substr NULLS FIRST, sm_type NULLS FIRST, cc_name_lower NULLS FIRST) <= 100 +ORDER BY world, w_substr NULLS FIRST, sm_type NULLS FIRST, cc_name_lower NULLS FIRST; diff --git a/benchmark/tpcds/run.py b/benchmark/tpcds/run.py index 6901c4d6..19bab0f8 100644 --- a/benchmark/tpcds/run.py +++ b/benchmark/tpcds/run.py @@ -2,58 +2,98 @@ """Isolate TPC-DS queries in processes; all reported timings come from C++.""" import argparse import csv +import hashlib import json import pathlib import statistics import subprocess +def digest_file(path): + digest = hashlib.sha256() + with pathlib.Path(path).open("rb") as file: + for block in iter(lambda: file.read(1024 * 1024), b""): + digest.update(block) + return digest.hexdigest() + + def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--config", required=True) parser.add_argument("--runner", default="build/release/extension/privacy/as_tpcds_benchmark") parser.add_argument("--queries", help="Comma-separated query numbers; default: all 99") parser.add_argument("--resume", action="store_true") + validation = parser.add_mutually_exclusive_group() + validation.add_argument("--validate", action="store_true", help="Compare handwritten PAC SQL to automatic compilation") + validation.add_argument("--validate-compiled", action="store_true", help="Compare PAC output to world-zero SQL (semantics diagnostic, not compiler correctness)") + validation.add_argument("--validate-worlds", action="store_true", help="Run the separate 64-world AS reference checks") args = parser.parse_args() + if args.validate_compiled or args.validate_worlds: + args.validate = True config = json.loads(pathlib.Path(args.config).read_text()) - query_ids = [int(q) for q in args.queries.split(",")] if args.queries else list(range(1, 100)) + handwritten_dir = pathlib.Path(config.get("reference_queries_dir", "benchmark/tpcds/reference_queries") if args.validate_worlds else config.get("as_queries_dir", "benchmark/tpcds/as_queries")) + default_ids = sorted(int(p.stem[1:]) for p in handwritten_dir.glob("q[0-9][0-9].sql")) if args.validate else list(range(1, 100)) + query_ids = [int(q) for q in args.queries.split(",")] if args.queries else default_ids + suffix = "_compiled_validation" if args.validate_compiled else "_validation" if args.validate_worlds else "_pac_validation" if args.validate else "" if not query_ids or any(q < 1 or q > 99 for q in query_ids) or len(set(query_ids)) != len(query_ids): parser.error("Query numbers must be unique and between 1 and 99") output = pathlib.Path(config["out_dir"]) manifest_path = output / "run_config.json" if manifest_path.exists() and json.loads(manifest_path.read_text()) != config: parser.error("Configuration changed: use a fresh out_dir to avoid mixing experiments") - if not args.resume and any((output / f"q{q:02}.csv").exists() for q in query_ids): + if not args.resume and any((output / f"q{q:02}{suffix}.csv").exists() for q in query_ids): parser.error("Results already exist: use a fresh out_dir or --resume") subprocess.run([args.runner, args.config, "--prepare"], check=True) manifest_path.write_text(json.dumps(config, indent=2) + "\n") summary = [] + runner_digest = digest_file(args.runner) for query in query_ids: name = f"q{query:02}" - path = output / f"{name}.csv" + path = output / f"{name}{suffix}.csv" process_status = "completed" process_error = "" - process_path = output / f"{name}_process.json" - if args.resume and process_path.exists(): - state = json.loads(process_path.read_text()) + process_path = output / f"{name}{suffix}_process.json" + inputs = (runner_digest + digest_file(pathlib.Path(config["queries_dir"]) / f"{name}.sql") + + digest_file(config.get("schema", "benchmark/tpcds/schema.sql"))) + hand_sql = handwritten_dir / f"{name}.sql" + if not args.validate_compiled and hand_sql.exists(): + inputs += digest_file(hand_sql) + inputs_digest = hashlib.sha256(inputs.encode()).hexdigest() + state = json.loads(process_path.read_text()) if process_path.exists() else {} + if args.resume and state and state.get("inputs_sha256") == inputs_digest: process_status, process_error = state["status"], state["error"] else: print(f"Running {name}", flush=True) - with (output / f"{name}.log").open("w") as log: + with (output / f"{name}{suffix}.log").open("w") as log: try: result = subprocess.run( - [args.runner, args.config, str(query)], stdout=log, stderr=subprocess.STDOUT, + [args.runner, args.config, str(query)] + (["--validate-compiled"] if args.validate_compiled else ["--validate-worlds"] if args.validate_worlds else ["--validate"] if args.validate else []), stdout=log, stderr=subprocess.STDOUT, timeout=config.get("timeout_seconds", 120), ) if result.returncode: process_status = "process_error" - process_error = f"exit code {result.returncode}; see {name}.log" + process_error = f"exit code {result.returncode}; see {name}{suffix}.log" except subprocess.TimeoutExpired: process_status = "timeout" process_error = "Whole-query process timeout (both modes and all repetitions)" - process_path.write_text(json.dumps(dict(status=process_status, error=process_error))) + process_path.write_text(json.dumps(dict(status=process_status, error=process_error, inputs_sha256=inputs_digest))) rows = list(csv.DictReader(path.open())) if path.exists() else [] - for mode in ("duckdb", "simd_asa_auto"): + if args.validate: + if not args.validate_worlds: + for row in rows: + row["method"] = "world_zero_diagnostic" if args.validate_compiled else "pac_equivalence" + if rows: + summary.extend(rows) + else: + summary.append(dict(query=name, method="validation", status=process_status if process_status != "completed" else "incomplete", error=process_error)) + fields = list(dict.fromkeys(key for row in summary for key in row)) + with (output / ("compiled_validation_summary.csv" if args.validate_compiled else "validation_summary.csv" if args.validate_worlds else "pac_validation_summary.csv")).open("w", newline="") as file: + writer = csv.DictWriter(file, fieldnames=fields) + writer.writeheader() + writer.writerows(summary) + print(f"{name}: " + (", ".join(f"{r['method']}={r['status']}" for r in rows) if rows else process_status + ": " + process_error), flush=True) + continue + for mode in ("duckdb", "simd_asa_handwritten", "simd_asa_auto", "naive_as"): entries = [row for row in rows if row["mode"] == mode] measured = [row for row in entries if row["status"] == "ok"] complete = len(measured) == config.get("repetitions", 5) @@ -65,6 +105,7 @@ def main(): query=name, mode=mode, status=status, rewritten=entries[-1]["rewritten"] if entries else "", measured_runs=len(measured), + world_multiplier=entries[-1].get("world_multiplier", "") if entries else "", median_ms=statistics.median(float(row["runtime_ms"]) for row in measured) if complete else "", empty_result=all(row["rows"] == "0" for row in measured) if complete else "", correctness="not_validated", @@ -74,8 +115,8 @@ def main(): writer = csv.DictWriter(file, fieldnames=list(summary[0])) writer.writeheader() writer.writerows(summary) - print(f"{name}: " + ", ".join(f"{r['mode']}={r['status']}" for r in summary[-2:]), flush=True) - print(f"Results: {output / 'summary.csv'}") + print(f"{name}: " + ", ".join(f"{r['mode']}={r['status']}" for r in summary[-4:]), flush=True) + print(f"Results: {output / ('compiled_validation_summary.csv' if args.validate_compiled else 'validation_summary.csv' if args.validate_worlds else 'pac_validation_summary.csv' if args.validate else 'summary.csv')}") if __name__ == "__main__": diff --git a/docs/benchmark/microbenchmarks.md b/docs/benchmark/microbenchmarks.md index 463279f4..213c6557 100644 --- a/docs/benchmark/microbenchmarks.md +++ b/docs/benchmark/microbenchmarks.md @@ -172,3 +172,21 @@ Rscript --vanilla benchmark/microbench/plot_microbenchmark.R benchmark/microbench/approx_sum_stability.sql # run with duckdb_default and duckdb_exactsum benchmark/microbench/binomial.sql # generate hash-distribution validation data ``` + + +## SUM accuracy + +`benchmark/microbench/approx_sum_stability.sql` compares ten value distributions against 64 independent sampled +sums. The approximate counters are divided by two before both errors and variances are computed, so all statistics +use the same sample-total units. Run the same setup for each binary variant: + +```sh +benchmark/microbench/binaries/duckdb_default -batch <<'SQL' +SET threads=4; +SET memory_limit='30GB'; +SET priv_rewrite=false; +SET privacy_seed=42; +SELECT setseed(0.42); +.read benchmark/microbench/approx_sum_stability.sql +SQL +``` diff --git a/docs/benchmark/tpcds.md b/docs/benchmark/tpcds.md index d84386c9..e0e50210 100644 --- a/docs/benchmark/tpcds.md +++ b/docs/benchmark/tpcds.md @@ -1,20 +1,21 @@ # TPC-DS coverage and performance -This benchmark submits all 99 original DuckDB TPC-DS queries to the automatic rewriter. Unlike the handwritten AS SQL -timed by the TPC-H and ClickBench runners, it measures the compiler's current coverage as well as execution time. -It does not rewrite query text to remove unsupported constructs. No membership masks or ownership joins are -prematerialized. +The benchmark submits all 99 original DuckDB TPC-DS queries to the automatic rewriter and times the available +handwritten AS queries. It reports four modes: ordinary DuckDB, handwritten SIMD-ASA, automatically compiled +SIMD-ASA, and repeated sampled-world execution. The handwritten queries and the separate per-world references +are in `benchmark/tpcds/as_queries/` and `benchmark/tpcds/reference_queries/`. ```bash cmake --build build/release --target as_tpcds_benchmark python3 benchmark/tpcds/run.py --config benchmark/configs/sanity/as_tpcds_smoke.json -python3 benchmark/tpcds/run.py --config benchmark/configs/utility/as_tpcds_sf1.json +python3 benchmark/tpcds/run.py --config benchmark/configs/utility/as_tpcds_sf30.json ``` Run from the repository root. The C++ runner loads DuckDB's version-matched TPC-DS extension, generates data with `dsdgen`, and exports all 99 original SQL files into the configured output directory. `extension_directory` controls where the generator extension is installed; choose a writable directory. Use a fresh database/output directory for -each scale factor or build. `--queries 19,52` runs a subset; `--resume` reuses completed per-query process records. +each scale factor or build. `--queries 19,52` runs a subset; `--resume` reuses completed process records only when +the configuration, runner, schema, and relevant SQL inputs still match. ## Sampling model @@ -22,24 +23,37 @@ each scale factor or build. `--queries 19,52` runs a subset; `--resume` reuses c customer keys declared in `benchmark/tpcds/schema.sql`: bill customer for catalog/web sales, returning customer for catalog/web returns, and the direct customer key for store sales/returns. Other dimensions remain shared. These choices define the experiment's ownership semantics; billing and shipping customers are not treated as independent -sampling entities. Fact rows with no matching owner are absent from sampled worlds. Original SQL is not modified. +sampling entities. Fact rows with no matching owner are absent from sampled worlds. The original query text is retained. ## Timing and coverage -Each query runs plain DuckDB and the automatic SIMD-ASA rewrite at 64 worlds. Noise and the sample-diversity check -are disabled (`pac_mi=0`, `pac_sample_diversity_check=false`), the seed is 42, and conservative compatibility checking -is enabled. `privacy_noise=true` is retained because setting it false bypasses PAC compilation in this version. -The noised/scalar output path is -used with noise disabled; this is not a measurement of releasing all 64 results to the client. Each mode receives -one untimed warmup and five measured executions. C++ times planning, execution, and result materialization using a -steady clock; process startup, generation, metadata setup, EXPLAIN, and Python orchestration are excluded. - -Each original query runs in its own process. A crash or whole-query timeout does not prevent later queries from -running. Raw CSV rows are flushed after every measurement. The wrapper reports median runtime only after all -configured repetitions complete. `summary.csv` records baseline/rewritten status, whether EXPLAIN showed a stochastic -operator, empty results, and the original error message. Physical plans and process logs are retained per query. - -An accepted execution is labelled `executed_not_validated`: it is not proof of per-world semantic correctness. -Unsupported queries, compilation/runtime failures, timeouts, and queries without a visible stochastic operator are -reported separately. Small-scale results may be empty and are preliminary coverage diagnostics, not paper-scale -performance evidence. Independent sampled-world validation must precede a correctness/coverage claim in the paper. +The experiment uses 64 worlds, `privacy_seed=42`, `pac_mi=0`, and `pac_sample_diversity_check=false`. +`privacy_noise=true` retains the automatic compilation path while `pac_mi=0` suppresses additive noise. Compatibility +checking remains conservative, with `priv_check=false` allowing this AS benchmark to use protected columns. + +Each mode receives one untimed warmup and five measured executions. C++ times planning, execution, and result +materialization using a steady clock. Preparation, EXPLAIN, process startup, and Python orchestration are outside +the timed interval. The handwritten and compiled paths return scalar/categorical outputs, as in TPC-H. Naive-AS +prepares ordinary SQL over customer-sampled views, times one world, and reports its runtime multiplied by 64. +The CSV retains this multiplier explicitly. + +Each original query runs in its own process so a crash or timeout does not prevent later queries from running. +Raw CSV rows are flushed after every measurement; `summary.csv` reports medians only after all configured runs +complete. It retains execution status, stochastic-operator detection, empty results, and error text. Physical plans +and process logs are saved per query. A completed timing is labelled `executed_not_validated`; correctness is +checked separately. + +## Validation + +Use the same configuration with one of these mutually exclusive modes: + +- `--validate` compares handwritten scalar/categorical SQL with the automatically compiled original query. +- `--validate-worlds` compares the separate per-world AS references with independent sampled-world SQL and with + conditional-aggregate references. +- `--validate-compiled` compares the compiled output with ordinary world-zero SQL as a semantics diagnostic. + These outputs need not agree when categorical filters use majority decisions, so this is not a compiler-equivalence test. + +Validation summaries record exact and floating-point mismatches and maximum absolute/relative error. Missing +handwritten queries, unsupported constructs, compilation/runtime errors, timeouts, and absent stochastic operators +are reported explicitly. `q17_fixture.sql` supplies a small nonempty correctness fixture for Q17; it is not a +performance dataset. Small-scale or empty results remain preliminary diagnostics rather than paper-scale evidence.