From fe648b74e49692615fe1d8aec4805d1e24bd7599 Mon Sep 17 00:00:00 2001 From: Marius Andra Date: Fri, 6 Oct 2023 13:26:54 +0200 Subject: [PATCH] lazy_tables tests via snapshots --- .../test/__snapshots__/test_lazy_tables.ambr | 221 ++++++++++++++++++ .../hogql/transforms/test/test_lazy_tables.py | 151 +++--------- 2 files changed, 258 insertions(+), 114 deletions(-) create mode 100644 posthog/hogql/transforms/test/__snapshots__/test_lazy_tables.ambr diff --git a/posthog/hogql/transforms/test/__snapshots__/test_lazy_tables.ambr b/posthog/hogql/transforms/test/__snapshots__/test_lazy_tables.ambr new file mode 100644 index 0000000000000..33966d3034bab --- /dev/null +++ b/posthog/hogql/transforms/test/__snapshots__/test_lazy_tables.ambr @@ -0,0 +1,221 @@ +# name: TestLazyJoins.test_resolve_lazy_table_as_select_table + ' + + SELECT persons.id, persons.properties___email, persons.`properties___$browser` + FROM ( + SELECT person.id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^"|"$', '') AS properties___email, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_1)s), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS persons + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_table_as_table_in_join + ' + + SELECT events.event, events.distinct_id, events__pdi.person_id, persons.properties___email + FROM events INNER JOIN ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) LEFT JOIN ( + SELECT person.id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^"|"$', '') AS properties___email + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, events__pdi.person_id) + WHERE equals(events.team_id, 5) + LIMIT 10 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables + ' + + SELECT events.event, events__pdi.person_id + FROM events INNER JOIN ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) + WHERE equals(events.team_id, 5) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables_one_level_properties + ' + + SELECT person_distinct_ids__person.`properties___$browser` + FROM ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS person_distinct_ids INNER JOIN ( + SELECT person.id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS person_distinct_ids__person ON equals(person_distinct_ids.person_id, person_distinct_ids__person.id) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables_one_level_properties_deep + ' + + SELECT person_distinct_ids__person.`properties___$browser___in___json` + FROM ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS person_distinct_ids INNER JOIN ( + SELECT person.id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s, %(hogql_val_1)s, %(hogql_val_2)s), ''), 'null'), '^"|"$', '') AS `properties___$browser___in___json` + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS person_distinct_ids__person ON equals(person_distinct_ids.person_id, person_distinct_ids__person.id) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables_traversed_fields + ' + + SELECT events.event, events__pdi.person_id + FROM events INNER JOIN ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) + WHERE equals(events.team_id, 5) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables_two_levels + ' + + SELECT events.event, events__pdi__person.id + FROM events INNER JOIN ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) INNER JOIN ( + SELECT person.id + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS events__pdi__person ON equals(events__pdi.person_id, events__pdi__person.id) + WHERE equals(events.team_id, 5) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables_two_levels_properties + ' + + SELECT events.event, events__pdi__person.`properties___$browser` + FROM events INNER JOIN ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) INNER JOIN ( + SELECT person.id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^"|"$', '') AS `properties___$browser` + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS events__pdi__person ON equals(events__pdi.person_id, events__pdi__person.id) + WHERE equals(events.team_id, 5) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables_two_levels_properties_duplicate + ' + + SELECT events.event, events__pdi__person.properties, events__pdi__person.properties___name + FROM events INNER JOIN ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) INNER JOIN ( + SELECT person.id, replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^"|"$', '') AS properties___name, person.properties AS properties + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS events__pdi__person ON equals(events__pdi.person_id, events__pdi__person.id) + WHERE equals(events.team_id, 5) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_resolve_lazy_tables_two_levels_traversed + ' + + SELECT events.event, events__pdi__person.id + FROM events INNER JOIN ( + SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id + FROM person_distinct_id2 + WHERE equals(person_distinct_id2.team_id, 5) + GROUP BY person_distinct_id2.distinct_id + HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) INNER JOIN ( + SELECT person.id + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS events__pdi__person ON equals(events__pdi.person_id, events__pdi__person.id) + WHERE equals(events.team_id, 5) + LIMIT 10000 + ' +--- +# name: TestLazyJoins.test_select_count_from_lazy_table + ' + + SELECT count() + FROM ( + SELECT person.id + FROM person + WHERE and(equals(person.team_id, 5), ifNull(in(tuple(person.id, person.version), ( + SELECT person.id, max(person.version) AS version + FROM person + WHERE equals(person.team_id, 5) + GROUP BY person.id + HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0))), 0)) + SETTINGS optimize_aggregation_in_order=1) AS persons + LIMIT 10000 + ' +--- diff --git a/posthog/hogql/transforms/test/test_lazy_tables.py b/posthog/hogql/transforms/test/test_lazy_tables.py index 28c4d24787242..3366fa77db376 100644 --- a/posthog/hogql/transforms/test/test_lazy_tables.py +++ b/posthog/hogql/transforms/test/test_lazy_tables.py @@ -1,3 +1,6 @@ +from typing import Any + +import pytest from django.test import override_settings from posthog.hogql.context import HogQLContext @@ -7,163 +10,83 @@ class TestLazyJoins(BaseTest): + snapshot: Any maxDiff = None + @pytest.mark.usefixtures("unittest_snapshot") def test_resolve_lazy_tables(self): printed = self._print_select("select event, pdi.person_id from events") - expected = ( - "SELECT events.event, events__pdi.person_id " - "FROM events " - "INNER JOIN " - "(SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id " - f"FROM person_distinct_id2 WHERE equals(person_distinct_id2.team_id, {self.team.pk}) GROUP BY person_distinct_id2.distinct_id " - "HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi " - "ON equals(events.distinct_id, events__pdi.distinct_id) " - f"WHERE equals(events.team_id, {self.team.pk}) " - "LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") @override_settings(PERSON_ON_EVENTS_OVERRIDE=False, PERSON_ON_EVENTS_V2_OVERRIDE=False) def test_resolve_lazy_tables_traversed_fields(self): printed = self._print_select("select event, person_id from events") - expected = ( - f"SELECT events.event, events__pdi.person_id FROM events INNER JOIN (SELECT argMax(person_distinct_id2.person_id, " - f"person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id FROM person_distinct_id2 WHERE " - f"equals(person_distinct_id2.team_id, {self.team.pk}) GROUP BY person_distinct_id2.distinct_id HAVING " - f"ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi " - f"ON equals(events.distinct_id, events__pdi.distinct_id) WHERE equals(events.team_id, {self.team.pk}) LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") def test_resolve_lazy_tables_two_levels(self): printed = self._print_select("select event, pdi.person.id from events") - expected = ( - f"SELECT events.event, events__pdi__person.id FROM events INNER JOIN (SELECT " - f"argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id " - f"FROM person_distinct_id2 WHERE equals(person_distinct_id2.team_id, {self.team.pk}) GROUP BY person_distinct_id2.distinct_id " - f"HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON " - f"equals(events.distinct_id, events__pdi.distinct_id) INNER JOIN (SELECT person.id AS id FROM person WHERE " - f"equals(person.team_id, {self.team.pk}) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) " - f"AS events__pdi__person ON equals(events__pdi.person_id, events__pdi__person.id) " - f"WHERE equals(events.team_id, {self.team.pk}) LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") @override_settings(PERSON_ON_EVENTS_OVERRIDE=False, PERSON_ON_EVENTS_V2_OVERRIDE=False) def test_resolve_lazy_tables_two_levels_traversed(self): printed = self._print_select("select event, person.id from events") - expected = ( - f"SELECT events.event, events__pdi__person.id FROM events INNER JOIN (SELECT argMax(person_distinct_id2.person_id, " - f"person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id FROM person_distinct_id2 WHERE " - f"equals(person_distinct_id2.team_id, {self.team.pk}) GROUP BY person_distinct_id2.distinct_id HAVING " - f"ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS events__pdi ON " - f"equals(events.distinct_id, events__pdi.distinct_id) INNER JOIN (SELECT person.id AS id FROM person WHERE " - f"equals(person.team_id, {self.team.pk}) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) " - f"AS events__pdi__person ON equals(events__pdi.person_id, events__pdi__person.id) " - f"WHERE equals(events.team_id, {self.team.pk}) LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") @override_settings(PERSON_ON_EVENTS_OVERRIDE=False, PERSON_ON_EVENTS_V2_OVERRIDE=False) def test_resolve_lazy_tables_one_level_properties(self): printed = self._print_select("select person.properties.$browser from person_distinct_ids") - expected = ( - f"SELECT person_distinct_ids__person.`properties___$browser` FROM " - f"(SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id " - f"FROM person_distinct_id2 WHERE equals(person_distinct_id2.team_id, {self.team.pk}) GROUP BY person_distinct_id2.distinct_id " - f"HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS person_distinct_ids " - f"INNER JOIN (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^\"|\"$', ''), person.version) " - f"AS `properties___$browser`, person.id AS id FROM person WHERE equals(person.team_id, {self.team.pk}) GROUP BY person.id " - f"HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS person_distinct_ids__person " - f"ON equals(person_distinct_ids.person_id, person_distinct_ids__person.id) LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") @override_settings(PERSON_ON_EVENTS_OVERRIDE=False, PERSON_ON_EVENTS_V2_OVERRIDE=False) def test_resolve_lazy_tables_one_level_properties_deep(self): printed = self._print_select("select person.properties.$browser.in.json from person_distinct_ids") - expected = ( - f"SELECT person_distinct_ids__person.`properties___$browser___in___json` FROM " - f"(SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, person_distinct_id2.distinct_id AS distinct_id " - f"FROM person_distinct_id2 WHERE equals(person_distinct_id2.team_id, {self.team.pk}) GROUP BY person_distinct_id2.distinct_id " - f"HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) AS person_distinct_ids " - f"INNER JOIN (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s, %(hogql_val_1)s, %(hogql_val_2)s), ''), 'null'), '^\"|\"$', ''), person.version) " - f"AS `properties___$browser___in___json`, person.id AS id FROM person WHERE equals(person.team_id, {self.team.pk}) GROUP BY person.id " - f"HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS person_distinct_ids__person " - f"ON equals(person_distinct_ids.person_id, person_distinct_ids__person.id) LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") def test_resolve_lazy_tables_two_levels_properties(self): printed = self._print_select("select event, pdi.person.properties.$browser from events") - expected = ( - f"SELECT events.event, events__pdi__person.`properties___$browser` FROM events INNER JOIN " - f"(SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, " - f"person_distinct_id2.distinct_id AS distinct_id FROM person_distinct_id2 WHERE equals(person_distinct_id2.team_id, {self.team.pk}) " - f"GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, " - f"person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) " - f"INNER JOIN (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^\"|\"$', " - f"''), person.version) AS `properties___$browser`, person.id AS id FROM person WHERE equals(person.team_id, {self.team.pk}) " - f"GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS events__pdi__person " - f"ON equals(events__pdi.person_id, events__pdi__person.id) WHERE equals(events.team_id, {self.team.pk}) LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") @override_settings(PERSON_ON_EVENTS_OVERRIDE=False, PERSON_ON_EVENTS_V2_OVERRIDE=False) def test_resolve_lazy_tables_two_levels_properties_duplicate(self): printed = self._print_select("select event, person.properties, person.properties.name from events") - expected = ( - f"SELECT events.event, events__pdi__person.properties, events__pdi__person.properties___name FROM events " - f"INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, " - f"person_distinct_id2.distinct_id AS distinct_id FROM person_distinct_id2 WHERE equals(person_distinct_id2.team_id, {self.team.pk}) " - f"GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, " - f"person_distinct_id2.version), 0), 0)) AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) " - f"INNER JOIN (SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^\"|\"$', ''), person.version) " - f"AS properties___name, argMax(person.properties, person.version) AS properties, person.id AS id FROM person " - f"WHERE equals(person.team_id, {self.team.pk}) GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) " - f"AS events__pdi__person ON equals(events__pdi.person_id, events__pdi__person.id) WHERE equals(events.team_id, {self.team.pk}) LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") @override_settings(PERSON_ON_EVENTS_OVERRIDE=False, PERSON_ON_EVENTS_V2_OVERRIDE=False) def test_resolve_lazy_table_as_select_table(self): printed = self._print_select("select id, properties.email, properties.$browser from persons") - expected = ( - f"SELECT persons.id, persons.properties___email, persons.`properties___$browser` FROM " - f"(SELECT argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^\"|\"$', ''), person.version) AS " - f"properties___email, argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_1)s), ''), 'null'), '^\"|\"$', ''), person.version) " - f"AS `properties___$browser`, person.id AS id FROM person WHERE equals(person.team_id, {self.team.pk}) GROUP BY person.id " - f"HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS persons LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") @override_settings(PERSON_ON_EVENTS_OVERRIDE=False, PERSON_ON_EVENTS_V2_OVERRIDE=False) def test_resolve_lazy_table_as_table_in_join(self): printed = self._print_select( "select event, distinct_id, events.person_id, persons.properties.email from events left join persons on persons.id = events.person_id limit 10" ) - expected = ( - f"SELECT events.event, events.distinct_id, events__pdi.person_id, persons.properties___email FROM events " - f"INNER JOIN (SELECT argMax(person_distinct_id2.person_id, person_distinct_id2.version) AS person_id, " - f"person_distinct_id2.distinct_id AS distinct_id FROM person_distinct_id2 WHERE equals(person_distinct_id2.team_id, {self.team.pk}) " - f"GROUP BY person_distinct_id2.distinct_id HAVING ifNull(equals(argMax(person_distinct_id2.is_deleted, person_distinct_id2.version), 0), 0)) " - f"AS events__pdi ON equals(events.distinct_id, events__pdi.distinct_id) LEFT JOIN (SELECT " - f"argMax(replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(person.properties, %(hogql_val_0)s), ''), 'null'), '^\"|\"$', ''), person.version) AS properties___email, " - f"person.id AS id FROM person WHERE equals(person.team_id, {self.team.pk}) GROUP BY person.id " - f"HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS persons ON equals(persons.id, events__pdi.person_id) " - f"WHERE equals(events.team_id, {self.team.pk}) LIMIT 10" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot + @pytest.mark.usefixtures("unittest_snapshot") def test_select_count_from_lazy_table(self): printed = self._print_select("select count() from persons") - expected = ( - f"SELECT count() FROM (SELECT person.id AS id FROM person WHERE equals(person.team_id, {self.team.pk}) " - f"GROUP BY person.id HAVING ifNull(equals(argMax(person.is_deleted, person.version), 0), 0) SETTINGS optimize_aggregation_in_order=1) AS persons LIMIT 10000" - ) - self.assertEqual(printed, expected) + assert printed == self.snapshot def _print_select(self, select: str): expr = parse_select(select) - return print_ast(expr, HogQLContext(team_id=self.team.pk, enable_select_queries=True), "clickhouse") + string = print_ast(expr, HogQLContext(team_id=self.team.pk, enable_select_queries=True), "clickhouse") + + return ( + string.replace("SELECT", "\nSELECT") + .replace("FROM", "\nFROM") + .replace("WHERE", "\nWHERE") + .replace("GROUP", "\nGROUP") + .replace("HAVING", "\nHAVING") + .replace("LIMIT", "\nLIMIT") + .replace("SETTINGS", "\nSETTINGS") + )