Skip to content

Commit e40902c

Browse files
committed
Fix remaining
1 parent f421d92 commit e40902c

File tree

5 files changed

+45
-23
lines changed

5 files changed

+45
-23
lines changed

datajunction-server/datajunction_server/internal/deployment/orchestrator.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
from datajunction_server.internal.impact import (
5050
compute_impact,
5151
_ExplicitDiffSpec,
52+
_ProposedColumn,
5253
_build_proposed_columns,
5354
_detect_source_column_changes,
5455
ColumnChangeType,
@@ -417,12 +418,20 @@ async def _compute_pre_deploy_diffs(
417418
if link.foreign_key_column_names & columns_removed:
418419
dim_links_removed.add(link.dimension.name)
419420

421+
if proposed_columns is None:
422+
# No query change (e.g. metadata-only update): use current columns
423+
# so the BFS sees the real column state and doesn't falsely
424+
# invalidate downstream nodes.
425+
proposed_columns = [
426+
_ProposedColumn(name=c.name, type=c.type)
427+
for c in pre_node.current.columns
428+
]
420429
specs[name] = _ExplicitDiffSpec(
421430
node_type=node_spec.node_type,
422431
explicit_columns_removed=columns_removed,
423432
explicit_columns_changed=columns_changed,
424433
dim_links_removed=dim_links_removed,
425-
explicit_proposed_columns=proposed_columns or [],
434+
explicit_proposed_columns=proposed_columns,
426435
)
427436
return specs
428437

datajunction-server/datajunction_server/internal/deployment/validation.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
from datajunction_server.api.helpers import _resolve_required_dimensions
1717
from datajunction_server.database.dimensionlink import DimensionLink
18-
from datajunction_server.internal.validation import validate_metric_query
18+
from datajunction_server.internal.validation import (
19+
update_ast_column_types,
20+
validate_metric_query,
21+
)
1922
from datajunction_server.sql.dag import get_dimensions
2023
from datajunction_server.database.node import Node, NodeRevision
2124
from datajunction_server.models.node import NodeStatus, NodeType
@@ -234,7 +237,7 @@ def _validate_dimension_link_specs(
234237
code=ErrorCode.INVALID_SQL_QUERY,
235238
message=(
236239
f"join_on for dimension link '{dim_name}' references"
237-
f" unknown table '{node_ref}' — expected"
240+
f" unknown node '{node_ref}' — expected"
238241
f" '{node_name}' or '{dim_name}'"
239242
),
240243
),
@@ -302,6 +305,7 @@ async def validate_query_node(
302305
await parsed_ast.bake_ctes().extract_dependencies(
303306
self.context.compile_context,
304307
)
308+
update_ast_column_types(parsed_ast)
305309
parsed_ast.select.add_aliases_to_unnamed_columns()
306310

307311
# If _skip_validation is set (e.g., copying from validated source),
@@ -324,6 +328,7 @@ async def validate_query_node(
324328
]
325329
if err is not None
326330
] + type_inference_errors
331+
print("parsed", spec.rendered_name, "and got", errors)
327332

328333
dep_names = self.context.node_graph.get(spec.rendered_name, [])
329334
invalid_parents = [
@@ -617,7 +622,12 @@ def _create_column_spec(
617622
if existing_spec and existing_spec.type:
618623
column_type = existing_spec.type
619624
else:
620-
column_type = str(ast_column.type)
625+
inferred = ast_column.type
626+
if inferred is None:
627+
raise TypeError(
628+
f"Cannot resolve type of column `{column_name}` in node",
629+
)
630+
column_type = str(inferred)
621631

622632
if existing_spec:
623633
return ColumnSpec(

datajunction-server/datajunction_server/internal/impact.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ async def _validate_downstream_node(
546546
# would return the existing column type for every projected column even when
547547
# the upstream column was removed via column_overrides, masking the impact.
548548
spec = spec.model_copy(update={"columns": []})
549+
print("upstream_proposed", upstream_proposed)
549550
results = await bulk_validate_node_data(
550551
[spec],
551552
session,

datajunction-server/datajunction_server/internal/validation.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@
2525
from datajunction_server.sql.parsing.types import ListType, MapType, StructType
2626

2727

28+
def update_ast_column_types(node: ast.Node) -> None:
29+
"""Recursively update AST Column._type from parsed database column types.
30+
31+
Call this after re-parsing parent column types (via parse_rule) so that
32+
type inference on the query AST sees the properly-typed objects rather than
33+
raw ColumnType strings.
34+
"""
35+
if isinstance(node, ast.Column) and node._table and hasattr(node._table, "dj_node"):
36+
for db_col in node._table.dj_node.columns:
37+
if db_col.name == node.name.name:
38+
node._type = db_col.type
39+
break
40+
for child in node.children:
41+
update_ast_column_types(child)
42+
43+
2844
@dataclass
2945
class NodeValidator:
3046
"""
@@ -135,26 +151,9 @@ async def validate_node_data(
135151
# If parsing fails, leave the original type
136152
pass
137153

138-
# Update AST Column nodes with the newly parsed types
154+
# Update AST Column nodes with the newly parsed types.
139155
# During extract_dependencies/compilation, AST Columns were created with _type from
140156
# database columns. Now that we've parsed the types, update the AST Column cache.
141-
def update_ast_column_types(node):
142-
"""Recursively update AST Column _type from parsed database columns"""
143-
if (
144-
isinstance(node, ast.Column)
145-
and node._table
146-
and hasattr(node._table, "dj_node")
147-
):
148-
# Find the corresponding database column
149-
for db_col in node._table.dj_node.columns:
150-
if db_col.name == node.name.name:
151-
# Update the cached type
152-
node._type = db_col.type
153-
break
154-
# Recursively update child nodes
155-
for child in node.children:
156-
update_ast_column_types(child)
157-
158157
update_ast_column_types(query_ast)
159158

160159
# Add aliases for any unnamed columns and confirm that all column types can be inferred

datajunction-server/datajunction_server/sql/parsing/ast.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1728,7 +1728,10 @@ async def compile(self, ctx: CompileContext):
17281728
self.set_dj_node(dj_node)
17291729
# Use proposed column overrides when available (impact preview / dryrun).
17301730
# Applied after dj_node is set so is_compiled() stays consistent.
1731-
if table_name in ctx.column_overrides:
1731+
if (
1732+
table_name in ctx.column_overrides
1733+
and ctx.column_overrides[table_name] is not None
1734+
):
17321735
self._columns = [
17331736
Column(Name(col.name), _type=col.type, _table=self)
17341737
for col in ctx.column_overrides[table_name]

0 commit comments

Comments
 (0)