diff --git a/posthog/warehouse/api/test/test_view_link.py b/posthog/warehouse/api/test/test_view_link.py index 6a68514c44b01..d8de45348b370 100644 --- a/posthog/warehouse/api/test/test_view_link.py +++ b/posthog/warehouse/api/test/test_view_link.py @@ -42,6 +42,19 @@ def test_create_saved_query_key_error(self): ) self.assertEqual(response.status_code, 400, response.content) + def test_create_saved_query_join_key_function(self): + response = self.client.post( + f"/api/projects/{self.team.id}/warehouse_view_links/", + { + "source_table_name": "events", + "joining_table_name": "persons", + "source_table_key": "upper(uuid)", + "joining_table_key": "id", + "field_name": "some_field", + }, + ) + self.assertEqual(response.status_code, 400, response.content) + def test_delete(self): response = self.client.post( f"/api/projects/{self.team.id}/warehouse_view_links/", diff --git a/posthog/warehouse/api/view_link.py b/posthog/warehouse/api/view_link.py index 4d65d2c744723..e3d701bb64b99 100644 --- a/posthog/warehouse/api/view_link.py +++ b/posthog/warehouse/api/view_link.py @@ -4,7 +4,9 @@ from posthog.api.routing import TeamAndOrgViewSetMixin from posthog.api.shared import UserBasicSerializer +from posthog.hogql.ast import Field from posthog.hogql.database.database import create_hogql_database +from posthog.hogql.parser import parse_expr from posthog.warehouse.models import DataWarehouseJoin @@ -67,6 +69,10 @@ def _validate_join_key(self, join_key: Optional[str], table: Optional[str], team except Exception: raise serializers.ValidationError(f"Invalid table: {table}") + node = parse_expr(join_key) + if not isinstance(node, Field): + raise serializers.ValidationError(f"Join key {join_key} must be a table field - no function calls allowed") + return