Skip to content

Commit 5e828bd

Browse files
author
Alison Gim
committed
Update unit tests for summarize-before-extend ordering
- Updated test_group_by_text to expect summarize before extend - Updated test_group_by_text_vaccine_dataset to expect summarize before extend - Updated test_distinct_count_by_text to expect summarize before extend - Updated test_distinct_count_alt_by_text to expect summarize before extend - Added test_ad_hoc_measure: Measure 1 = count() - Added test_predefined_measure: UserInfo_Ring Count = count(["UserInfo_Ring"]) - Added test_calculated_measure: Measure 2 = "Measure 1" * 2
1 parent 5548c47 commit 5e828bd

2 files changed

Lines changed: 34 additions & 16 deletions

File tree

sqlalchemy_kusto/dialect_kql.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def visit_select(
107107
from_object = select_stmt.get_final_froms()[0]
108108
if hasattr(from_object, "element"):
109109
query = self._get_most_inner_element(from_object.element)
110-
(main, lets) = self._extract_let_statements(query.text)
110+
main, lets = self._extract_let_statements(query.text)
111111
compiled_query_lines.extend(lets)
112112
compiled_query_lines.append(
113113
f"let {from_object.name} = ({self._convert_schema_in_statement(main)});"
@@ -142,15 +142,12 @@ def visit_select(
142142
)
143143
compiled_query_lines.append(f"| where {converted_where_clause}")
144144

145-
# Add summarize first if it exists
146145
if "summarize" in projections_parts_dict:
147146
compiled_query_lines.append(projections_parts_dict.pop("summarize"))
148147

149-
# Then add extend after summarize
150148
if "extend" in projections_parts_dict:
151149
compiled_query_lines.append(projections_parts_dict.pop("extend"))
152150

153-
# Add remaining parts (project, sort)
154151
for statement_part in projections_parts_dict.values():
155152
if statement_part:
156153
compiled_query_lines.append(statement_part)

tests/unit/test_dialect_kql.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,10 @@ def test_group_by_text():
175175
).replace("\n", "")
176176
# raw query text from query
177177
query_expected = (
178-
'["ActiveUsersLastMonth"]| extend ["ActiveUserMetric"] = ["ActiveUsers"], '
179-
'["EventInfo_Time"] = ["EventInfo_Time"] / time(1d)'
178+
'["ActiveUsersLastMonth"]'
180179
'| summarize by ["EventInfo_Time"] / time(1d)'
180+
'| extend ["ActiveUserMetric"] = ["ActiveUsers"], '
181+
'["EventInfo_Time"] = ["EventInfo_Time"] / time(1d)'
181182
'| project ["EventInfo_Time"], ["ActiveUserMetric"]'
182183
'| order by ["ActiveUserMetric"] desc'
183184
)
@@ -224,20 +225,19 @@ def test_group_by_text_vaccine_dataset():
224225
query.compile(engine, compile_kwargs={"literal_binds": True})
225226
).replace("\n", "")
226227
query_expected = (
227-
'database("superset").["CovidVaccineData"]| '
228-
'extend ["country_name"] = ["country_name"]| '
229-
'summarize by ["country_name"]| '
230-
'project ["country_name"]| order by ["country_name"] asc'
228+
'database("superset").["CovidVaccineData"]'
229+
'| summarize by ["country_name"]'
230+
'| extend ["country_name"] = ["country_name"]'
231+
'| project ["country_name"]'
232+
'| order by ["country_name"] asc'
231233
)
232234
assert query_compiled == query_expected
233235

234236

235237
def test_is_kql_function():
236-
assert KustoKqlCompiler._is_kql_function(
237-
"""case(Size <= 3, "Small",
238+
assert KustoKqlCompiler._is_kql_function("""case(Size <= 3, "Small",
238239
Size <= 10, "Medium",
239-
"Large")"""
240-
)
240+
"Large")""")
241241
assert KustoKqlCompiler._is_kql_function("""bin(time(16d), 7d)""")
242242
assert KustoKqlCompiler._is_kql_function(
243243
"""iff((EventType in ("Heavy Rain", "Flash Flood", "Flood")), "Rain event", "Not rain event")"""
@@ -328,8 +328,8 @@ def test_distinct_count_by_text():
328328
# raw query text from query
329329
query_expected = (
330330
'["ActiveUsersLastMonth"]'
331-
'| extend ["EventInfo_Time"] = ["EventInfo_Time"] / time(1d)'
332331
'| summarize ["DistinctUsers"] = dcount(["ActiveUsers"]) by ["EventInfo_Time"] / time(1d)'
332+
'| extend ["EventInfo_Time"] = ["EventInfo_Time"] / time(1d)'
333333
'| project ["EventInfo_Time"], ["DistinctUsers"]'
334334
'| order by ["ActiveUserMetric"] desc'
335335
)
@@ -354,8 +354,8 @@ def test_distinct_count_alt_by_text():
354354
# raw query text from query
355355
query_expected = (
356356
'["ActiveUsersLastMonth"]'
357-
'| extend ["EventInfo_Time"] = ["EventInfo_Time"] / time(1d)'
358357
'| summarize ["DistinctUsers"] = dcount(["ActiveUsers"]) by ["EventInfo_Time"] / time(1d)'
358+
'| extend ["EventInfo_Time"] = ["EventInfo_Time"] / time(1d)'
359359
'| project ["EventInfo_Time"], ["DistinctUsers"]'
360360
'| order by ["ActiveUserMetric"] desc'
361361
)
@@ -549,6 +549,27 @@ def test_match_aggregates(column_name: str, expected_aggregate: str):
549549
assert kql_agg is None
550550

551551

552+
def test_adhoc_and_constant_calculated_measure():
553+
"""Test calculated measure: Measure 2 defined as "Measure 1" * 2.
554+
555+
Measure 1 is an ad hoc measure defined as count().
556+
Measure 2 references Measure 1 and applies an operation.
557+
"""
558+
measure_1 = literal_column("count(*)").label("Measure 1")
559+
measure_2 = literal_column('"Measure 1" * 2').label("Measure 2")
560+
query = select([measure_1, measure_2]).select_from(text("SalesData"))
561+
query_compiled = str(
562+
query.compile(engine, compile_kwargs={"literal_binds": True})
563+
).replace("\n", "")
564+
query_expected = (
565+
'["SalesData"]'
566+
'| summarize ["Measure 1"] = count() '
567+
'| extend ["Measure 2"] = ["Measure 1"] * 2'
568+
'| project ["Measure 1"], ["Measure 2"]'
569+
)
570+
assert query_compiled == query_expected
571+
572+
552573
@pytest.mark.parametrize(
553574
("query_table_name", "expected_table_name"),
554575
[

0 commit comments

Comments
 (0)