diff --git a/core/wren/src/wren/memory/schema_indexer.py b/core/wren/src/wren/memory/schema_indexer.py index 7e28cd44fa..80ff0339c6 100644 --- a/core/wren/src/wren/memory/schema_indexer.py +++ b/core/wren/src/wren/memory/schema_indexer.py @@ -50,14 +50,23 @@ def describe_schema(manifest: dict) -> str: lines.append(f"Catalog: {catalog}, Schema: {schema}") lines.append("") - for model in manifest.get("models", []): - _describe_model(model, lines) - - for rel in manifest.get("relationships", []): - _describe_relationship(rel, lines) - - for view in manifest.get("views", []): - _describe_view(view, lines) + models = manifest.get("models", []) or [] + if isinstance(models, list): + for model in models: + if isinstance(model, dict) and model.get("name") is not None: + _describe_model(model, lines) + + rels = manifest.get("relationships", []) or [] + if isinstance(rels, list): + for rel in rels: + if isinstance(rel, dict) and rel.get("name") is not None: + _describe_relationship(rel, lines) + + views = manifest.get("views", []) or [] + if isinstance(views, list): + for view in views: + if isinstance(view, dict) and view.get("name") is not None: + _describe_view(view, lines) cubes = manifest.get("cubes", []) or [] if isinstance(cubes, list): @@ -87,11 +96,12 @@ def _describe_model(model: dict, lines: list[str]) -> None: if data_scope: lines.append(f" Data scope: {data_scope}") - cols = model.get("columns", []) - if cols: + cols = model.get("columns", []) or [] + if isinstance(cols, list) and cols: lines.append(" Columns:") for col in cols: - _describe_column(col, lines) + if isinstance(col, dict) and col.get("name") is not None: + _describe_column(col, lines) lines.append("") diff --git a/core/wren/tests/unit/test_schema_describe_nonduct.py b/core/wren/tests/unit/test_schema_describe_nonduct.py new file mode 100644 index 0000000000..e8f5c32dfe --- /dev/null +++ b/core/wren/tests/unit/test_schema_describe_nonduct.py @@ -0,0 +1,18 @@ +from wren.memory.schema_indexer import describe_schema + + +def test_describe_schema_skips_nonduct_entries(): + text = describe_schema( + { + "models": [ + {"name": "orders", "columns": [{"name": "id", "type": "int"}, "bad"]}, + "not-a-model", + None, + ], + "relationships": ["x", {"name": "r1", "models": ["a", "b"], "joinType": "MANY_TO_ONE"}], + "views": [None, {"name": "v1", "statement": "SELECT 1"}], + } + ) + assert "orders" in text + assert "not-a-model" not in text + assert "v1" in text