Skip to content

Commit 36124b7

Browse files
rustyconoverclaude
andcommitted
Add ExtensionOption, update FunctionInfo.examples, and add bind error handling
- Add ExtensionOption dataclass for DuckDB extension configuration settings - Update FunctionInfo.examples to use list[CatalogExample | str] with structured Arrow schema (sql, description, expected_output fields) - Add _create_bind_error_batch method to Worker for bind-time exception handling - Add bind error detection to Client._initialize_stream_common() - Update CLI display to use dict(tags) instead of list(tags) - Replace hardcoded expected_functions in tests with dynamic extraction - Export CatalogExample and ExtensionOption from vgi.catalog 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6edff3b commit 36124b7

8 files changed

Lines changed: 1091 additions & 31 deletions

File tree

tests/catalog/test_catalog_interface.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,10 @@ def test_serialization_roundtrip_with_all_fields(self) -> None:
530530
# New fields
531531
assert restored.stability == info.stability
532532
assert restored.null_handling == info.null_handling
533-
assert restored.examples == info.examples
533+
# Examples are deserialized to CatalogExample objects
534+
assert [
535+
ex.sql for ex in restored.examples if hasattr(ex, "sql")
536+
] == info.examples
534537
assert restored.categories == info.categories
535538
assert restored.projection_pushdown == info.projection_pushdown
536539
assert restored.filter_pushdown == info.filter_pushdown
@@ -718,7 +721,12 @@ def test_list_fields_serialization(self) -> None:
718721
batch = deserialize_record_batch(serialized)
719722
restored = FunctionInfo.deserialize(batch)
720723

721-
assert restored.examples == ["SELECT f(1)", "SELECT f(2)", "SELECT f(3)"]
724+
# Examples are deserialized to CatalogExample objects
725+
assert [ex.sql for ex in restored.examples if hasattr(ex, "sql")] == [
726+
"SELECT f(1)",
727+
"SELECT f(2)",
728+
"SELECT f(3)",
729+
]
722730
assert restored.categories == ["a", "b"]
723731
assert restored.required_settings == ["setting1"]
724732

tests/catalog/test_example_worker_catalog.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,21 @@
88

99
from vgi.catalog import FunctionInfo, FunctionType, TableInfo, ViewInfo
1010
from vgi.client import Client
11+
from vgi.examples.worker import ExampleWorker
1112

1213
# Worker command for catalog tests
1314
EXAMPLE_WORKER = "vgi-example-worker"
1415

1516

17+
def _get_expected_function_names() -> set[str]:
18+
"""Get all function names from ExampleWorker dynamically."""
19+
names = set()
20+
for func_cls in ExampleWorker.functions:
21+
meta = func_cls.get_metadata()
22+
names.add(meta.name)
23+
return names
24+
25+
1626
def _get_functions(
1727
contents: list[TableInfo | ViewInfo | FunctionInfo],
1828
) -> list[FunctionInfo]:
@@ -69,28 +79,17 @@ def test_all_example_functions_listed(self) -> None:
6979
# Get function names
7080
function_names = {item.name for item in contents}
7181

72-
# Check for known example functions
73-
expected_functions = {
74-
# TableInOutGenerator functions
75-
"echo",
76-
"buffer_input",
77-
"repeat_inputs",
78-
"sum_all_columns",
79-
# TableFunctionGenerator functions
80-
"sequence",
81-
"range",
82-
"constant_table",
83-
"random_sample",
84-
# ScalarFunctionGenerator functions
85-
"double_column",
86-
"add_columns",
87-
"upper_case",
88-
}
82+
# Get expected functions from ExampleWorker dynamically
83+
expected_functions = _get_expected_function_names()
8984

9085
# All expected functions should be present
9186
missing = expected_functions - function_names
9287
assert not missing, f"Missing functions: {missing}"
9388

89+
# No extra functions should be present
90+
extra = function_names - expected_functions
91+
assert not extra, f"Unexpected functions: {extra}"
92+
9493
def test_function_info_has_correct_types(self) -> None:
9594
"""FunctionInfo has correct function types."""
9695
client = Client(EXAMPLE_WORKER)

0 commit comments

Comments
 (0)