|
1 | 1 | use datafusion::physical_plan::displayable;
|
2 | 2 | use pretty_assertions::assert_eq;
|
| 3 | +use regex::Regex; |
3 | 4 | use serde_json::json;
|
4 | 5 | use std::sync::Arc;
|
5 | 6 |
|
@@ -1146,6 +1147,92 @@ async fn test_case_wrapper_escaping() {
|
1146 | 1147 | .contains("\\\\\\\\\\\\`"));
|
1147 | 1148 | }
|
1148 | 1149 |
|
| 1150 | +/// Test aliases for grouped CubeScan in wrapper |
| 1151 | +/// qualifiers from join should get remapped to single from alias |
| 1152 | +/// long generated aliases from Datafusion should get shortened |
| 1153 | +#[tokio::test] |
| 1154 | +async fn test_join_wrapper_cubescan_aliasing() { |
| 1155 | + if !Rewriter::sql_push_down_enabled() { |
| 1156 | + return; |
| 1157 | + } |
| 1158 | + init_testing_logger(); |
| 1159 | + |
| 1160 | + let query_plan = convert_select_to_query_plan( |
| 1161 | + // language=PostgreSQL |
| 1162 | + r#" |
| 1163 | +WITH |
| 1164 | +-- This subquery should be represented as CubeScan(ungrouped=false) inside CubeScanWrapper |
| 1165 | +cube_scan_subq AS ( |
| 1166 | + SELECT |
| 1167 | + logs_alias.content logs_content, |
| 1168 | + DATE_TRUNC('month', kibana_alias.last_mod) last_mod_month, |
| 1169 | + CASE |
| 1170 | + WHEN sum(kibana_alias."sumPrice") IS NOT NULL |
| 1171 | + THEN sum(kibana_alias."sumPrice") |
| 1172 | + ELSE 0 |
| 1173 | + END sum_price |
| 1174 | + FROM KibanaSampleDataEcommerce kibana_alias |
| 1175 | + JOIN Logs logs_alias |
| 1176 | + ON kibana_alias.__cubeJoinField = logs_alias.__cubeJoinField |
| 1177 | + GROUP BY |
| 1178 | + logs_content, |
| 1179 | + last_mod_month |
| 1180 | +), |
| 1181 | +filter_subq AS ( |
| 1182 | + SELECT |
| 1183 | + Logs.content logs_content_filter |
| 1184 | + FROM Logs |
| 1185 | + GROUP BY |
| 1186 | + logs_content_filter |
| 1187 | +) |
| 1188 | +SELECT |
| 1189 | + logs_content |
| 1190 | +FROM cube_scan_subq |
| 1191 | +WHERE |
| 1192 | + -- This subquery filter should trigger wrapping of whole query |
| 1193 | + logs_content IN ( |
| 1194 | + SELECT |
| 1195 | + logs_content_filter |
| 1196 | + FROM filter_subq |
| 1197 | + ) |
| 1198 | +GROUP BY |
| 1199 | + logs_content |
| 1200 | +ORDER BY |
| 1201 | + logs_content ASC |
| 1202 | +; |
| 1203 | +"# |
| 1204 | + .to_string(), |
| 1205 | + DatabaseProtocol::PostgreSQL, |
| 1206 | + ) |
| 1207 | + .await; |
| 1208 | + |
| 1209 | + let physical_plan = query_plan.as_physical_plan().await.unwrap(); |
| 1210 | + println!( |
| 1211 | + "Physical plan: {}", |
| 1212 | + displayable(physical_plan.as_ref()).indent() |
| 1213 | + ); |
| 1214 | + |
| 1215 | + let logical_plan = query_plan.as_logical_plan(); |
| 1216 | + let sql = logical_plan |
| 1217 | + .find_cube_scan_wrapper() |
| 1218 | + .wrapped_sql |
| 1219 | + .unwrap() |
| 1220 | + .sql; |
| 1221 | + |
| 1222 | + // Check that all aliases from different tables have same qualifier, and that names are simple and short |
| 1223 | + // logs_content => logs_alias.content |
| 1224 | + // last_mod_month => DATE_TRUNC('month', kibana_alias.last_mod), |
| 1225 | + // sum_price => CASE WHEN sum(kibana_alias."sumPrice") ... END |
| 1226 | + let content_re = Regex::new(r#""logs_alias"."[a-zA-Z0-9_]{1,16}" "logs_content""#).unwrap(); |
| 1227 | + assert!(content_re.is_match(&sql)); |
| 1228 | + let last_mod_month_re = |
| 1229 | + Regex::new(r#""logs_alias"."[a-zA-Z0-9_]{1,16}" "last_mod_month""#).unwrap(); |
| 1230 | + assert!(last_mod_month_re.is_match(&sql)); |
| 1231 | + let sum_price_re = Regex::new(r#"CASE WHEN "logs_alias"."[a-zA-Z0-9_]{1,16}" IS NOT NULL THEN "logs_alias"."[a-zA-Z0-9_]{1,16}" ELSE 0 END "sum_price""#) |
| 1232 | + .unwrap(); |
| 1233 | + assert!(sum_price_re.is_match(&sql)); |
| 1234 | +} |
| 1235 | + |
1149 | 1236 | /// Test that WrappedSelect(... limit=Some(0) ...) will render it correctly
|
1150 | 1237 | #[tokio::test]
|
1151 | 1238 | async fn test_wrapper_limit_zero() {
|
|
0 commit comments