You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Queries can now omit GROUP BY entirely:
SEMANTIC SELECT year, region, AGGREGATE(revenue)
FROM sales_v;
Yardstick infers the grouping columns from non-AGGREGATE
expressions in the SELECT clause. This matches the paper's
semantics more closely.
let select_pos = sql_upper.find("SELECT").unwrap_or(0) + 6;
2216
+
let from_pos = sql_upper.find("FROM").unwrap_or(sql.len());
2217
+
2218
+
if select_pos >= from_pos {
2219
+
return columns;
2220
+
}
2221
+
2222
+
let select_content = &sql[select_pos..from_pos];
2223
+
2224
+
// Split by comma, but be careful about nested parens
2225
+
letmut depth = 0;
2226
+
letmut current = String::new();
2227
+
letmut items = Vec::new();
2228
+
2229
+
for c in select_content.chars(){
2230
+
match c {
2231
+
'(' => {
2232
+
depth += 1;
2233
+
current.push(c);
2234
+
}
2235
+
')' => {
2236
+
depth -= 1;
2237
+
current.push(c);
2238
+
}
2239
+
','if depth == 0 => {
2240
+
items.push(current.trim().to_string());
2241
+
current = String::new();
2242
+
}
2243
+
_ => current.push(c),
2244
+
}
2245
+
}
2246
+
if !current.trim().is_empty(){
2247
+
items.push(current.trim().to_string());
2248
+
}
2249
+
2250
+
// Filter out AGGREGATE() calls and extract column names
2251
+
for item in items {
2252
+
let item_upper = item.to_uppercase();
2253
+
if item_upper.contains("AGGREGATE("){
2254
+
continue;
2255
+
}
2256
+
// Handle "col AS alias" - use the column name, not alias
2257
+
let col = ifletSome(as_pos) = item_upper.find(" AS "){
2258
+
item[..as_pos].trim()
2259
+
}else{
2260
+
item.trim()
2261
+
};
2262
+
if !col.is_empty(){
2263
+
columns.push(col.to_string());
2264
+
}
2265
+
}
2266
+
2174
2267
columns
2175
2268
}
2176
2269
@@ -2492,6 +2585,34 @@ FROM orders"#;
2492
2585
assert!(result.expanded_sql.contains("_inner"));
2493
2586
}
2494
2587
2588
+
#[test]
2589
+
#[serial]
2590
+
fntest_expand_aggregate_no_group_by(){
2591
+
// Test that queries without GROUP BY get implicit GROUP BY with dimension columns
2592
+
clear_measure_views();
2593
+
store_measure_view(
2594
+
"sales_v",
2595
+
vec![ViewMeasure{
2596
+
column_name:"revenue".to_string(),
2597
+
expression:"SUM(amount)".to_string(),
2598
+
}],
2599
+
"SELECT year, region, SUM(amount) AS revenue FROM sales GROUP BY ALL",
2600
+
);
2601
+
2602
+
let sql = r#"SELECT year, region, AGGREGATE(revenue) AS revenue, AGGREGATE(revenue) AT (ALL region) AS year_total, AGGREGATE(revenue) / AGGREGATE(revenue) AT (ALL region) AS pct FROM sales_v"#;
0 commit comments