vgi-python 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vgi/__init__.py +152 -0
- vgi/_duckdb.py +62 -0
- vgi/_storage_profile.py +132 -0
- vgi/_test_fixtures/__init__.py +20 -0
- vgi/_test_fixtures/accumulate/__init__.py +19 -0
- vgi/_test_fixtures/accumulate/worker.py +762 -0
- vgi/_test_fixtures/aggregate/__init__.py +62 -0
- vgi/_test_fixtures/aggregate/_common.py +21 -0
- vgi/_test_fixtures/aggregate/basic.py +232 -0
- vgi/_test_fixtures/aggregate/dynamic.py +409 -0
- vgi/_test_fixtures/aggregate/generic.py +86 -0
- vgi/_test_fixtures/aggregate/listagg.py +71 -0
- vgi/_test_fixtures/aggregate/percentile.py +107 -0
- vgi/_test_fixtures/aggregate/streaming.py +192 -0
- vgi/_test_fixtures/aggregate/varargs.py +75 -0
- vgi/_test_fixtures/aggregate/window.py +380 -0
- vgi/_test_fixtures/attach_options.py +308 -0
- vgi/_test_fixtures/bad_protocol.py +62 -0
- vgi/_test_fixtures/cancellable.py +336 -0
- vgi/_test_fixtures/catalog.py +813 -0
- vgi/_test_fixtures/http_server.py +394 -0
- vgi/_test_fixtures/nest_tensor.py +614 -0
- vgi/_test_fixtures/orchard_catalog.py +47 -0
- vgi/_test_fixtures/projection_repro/__init__.py +6 -0
- vgi/_test_fixtures/projection_repro/worker.py +454 -0
- vgi/_test_fixtures/scalar/__init__.py +116 -0
- vgi/_test_fixtures/scalar/_common.py +69 -0
- vgi/_test_fixtures/scalar/arithmetic.py +321 -0
- vgi/_test_fixtures/scalar/binary.py +120 -0
- vgi/_test_fixtures/scalar/formatting.py +176 -0
- vgi/_test_fixtures/scalar/geo.py +300 -0
- vgi/_test_fixtures/scalar/null_handling.py +107 -0
- vgi/_test_fixtures/scalar/random_demo.py +171 -0
- vgi/_test_fixtures/scalar/settings_secrets.py +102 -0
- vgi/_test_fixtures/scalar/type_info.py +219 -0
- vgi/_test_fixtures/schema_reconcile/__init__.py +29 -0
- vgi/_test_fixtures/schema_reconcile/worker.py +653 -0
- vgi/_test_fixtures/simple_writable.py +793 -0
- vgi/_test_fixtures/table/__init__.py +221 -0
- vgi/_test_fixtures/table/_common.py +162 -0
- vgi/_test_fixtures/table/batch_index.py +283 -0
- vgi/_test_fixtures/table/batch_index_broken.py +200 -0
- vgi/_test_fixtures/table/catalog_scans.py +162 -0
- vgi/_test_fixtures/table/filters.py +1005 -0
- vgi/_test_fixtures/table/late_materialization.py +249 -0
- vgi/_test_fixtures/table/make_series.py +273 -0
- vgi/_test_fixtures/table/misc.py +499 -0
- vgi/_test_fixtures/table/order_modes.py +164 -0
- vgi/_test_fixtures/table/pairs.py +437 -0
- vgi/_test_fixtures/table/partition_columns.py +472 -0
- vgi/_test_fixtures/table/partition_columns_broken.py +304 -0
- vgi/_test_fixtures/table/profiling_example.py +195 -0
- vgi/_test_fixtures/table/required_filters.py +234 -0
- vgi/_test_fixtures/table/sequence.py +710 -0
- vgi/_test_fixtures/table/settings.py +426 -0
- vgi/_test_fixtures/table/transaction_storage.py +162 -0
- vgi/_test_fixtures/table/tt_pushdown.py +191 -0
- vgi/_test_fixtures/table/versioned.py +230 -0
- vgi/_test_fixtures/table_in_out.py +1392 -0
- vgi/_test_fixtures/versioned.py +155 -0
- vgi/_test_fixtures/versioned_tables.py +595 -0
- vgi/_test_fixtures/worker.py +1631 -0
- vgi/_test_fixtures/writable/__init__.py +8 -0
- vgi/_test_fixtures/writable/generic.py +236 -0
- vgi/_test_fixtures/writable/table.py +149 -0
- vgi/_test_fixtures/writable/worker.py +1148 -0
- vgi/aggregate_function.py +607 -0
- vgi/argument_spec.py +472 -0
- vgi/arguments.py +1747 -0
- vgi/auth.py +55 -0
- vgi/catalog/__init__.py +88 -0
- vgi/catalog/attach_option.py +206 -0
- vgi/catalog/catalog_interface.py +2767 -0
- vgi/catalog/descriptors.py +870 -0
- vgi/catalog/duckdb_statistics.py +377 -0
- vgi/catalog/secret_type.py +96 -0
- vgi/catalog/setting.py +253 -0
- vgi/catalog/storage.py +372 -0
- vgi/client/__init__.py +67 -0
- vgi/client/catalog_mixin.py +1251 -0
- vgi/client/cli.py +582 -0
- vgi/client/cli_catalog.py +182 -0
- vgi/client/cli_schema.py +270 -0
- vgi/client/cli_table.py +907 -0
- vgi/client/cli_transaction.py +97 -0
- vgi/client/cli_utils.py +441 -0
- vgi/client/cli_view.py +303 -0
- vgi/client/client.py +2183 -0
- vgi/exceptions.py +205 -0
- vgi/function.py +245 -0
- vgi/function_storage.py +1636 -0
- vgi/function_storage_azure_sql.py +922 -0
- vgi/function_storage_cf_do.py +740 -0
- vgi/http/__init__.py +25 -0
- vgi/http/demo_storage.py +212 -0
- vgi/http/worker_page.py +1252 -0
- vgi/invocation.py +154 -0
- vgi/logging_config.py +93 -0
- vgi/meta_worker.py +661 -0
- vgi/metadata.py +1403 -0
- vgi/otel.py +406 -0
- vgi/protocol.py +2418 -0
- vgi/protocol_version.txt +1 -0
- vgi/py.typed +0 -0
- vgi/scalar_function.py +1211 -0
- vgi/schema_utils.py +234 -0
- vgi/secret_protocol.py +124 -0
- vgi/secret_service.py +238 -0
- vgi/serve.py +769 -0
- vgi/table_buffering_function.py +443 -0
- vgi/table_filter_pushdown.py +1528 -0
- vgi/table_function.py +1130 -0
- vgi/table_in_out_function.py +383 -0
- vgi/transactor/__init__.py +24 -0
- vgi/transactor/_duckdb_compat.py +27 -0
- vgi/transactor/client.py +137 -0
- vgi/transactor/protocol.py +149 -0
- vgi/transactor/server.py +740 -0
- vgi/worker.py +4761 -0
- vgi_python-0.8.0.dist-info/METADATA +735 -0
- vgi_python-0.8.0.dist-info/RECORD +124 -0
- vgi_python-0.8.0.dist-info/WHEEL +4 -0
- vgi_python-0.8.0.dist-info/entry_points.txt +5 -0
- vgi_python-0.8.0.dist-info/licenses/LICENSE +134 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Type-introspection scalar fixtures (type_info_*, any_mixed_*, pair_type_*)."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import pyarrow as pa
|
|
10
|
+
|
|
11
|
+
from vgi.arguments import Param, Returns
|
|
12
|
+
from vgi.scalar_function import ScalarFunction
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _type_info_result(label: str, v: pa.Array) -> pa.StringArray: # type: ignore[type-arg]
|
|
16
|
+
"""Shared compute logic for all type_info overloads."""
|
|
17
|
+
return pa.array([label if x is not None else None for x in v.to_pylist()], type=pa.string())
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TypeInfoInt32Function(ScalarFunction):
|
|
21
|
+
"""Return type name for int32 input."""
|
|
22
|
+
|
|
23
|
+
class Meta:
|
|
24
|
+
"""Function metadata."""
|
|
25
|
+
|
|
26
|
+
name = "type_info"
|
|
27
|
+
description = "Return type name for int32 input"
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def compute(
|
|
31
|
+
cls,
|
|
32
|
+
v: Annotated[pa.Int32Array, Param(doc="Input value")],
|
|
33
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
34
|
+
"""Return 'int32' for each row."""
|
|
35
|
+
return _type_info_result("int32", v)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TypeInfoInt64Function(ScalarFunction):
|
|
39
|
+
"""Return type name for int64 input."""
|
|
40
|
+
|
|
41
|
+
class Meta:
|
|
42
|
+
"""Function metadata."""
|
|
43
|
+
|
|
44
|
+
name = "type_info"
|
|
45
|
+
description = "Return type name for int64 input"
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def compute(
|
|
49
|
+
cls,
|
|
50
|
+
v: Annotated[pa.Int64Array, Param(doc="Input value")],
|
|
51
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
52
|
+
"""Return 'int64' for each row."""
|
|
53
|
+
return _type_info_result("int64", v)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class TypeInfoUInt32Function(ScalarFunction):
|
|
57
|
+
"""Return type name for uint32 input."""
|
|
58
|
+
|
|
59
|
+
class Meta:
|
|
60
|
+
"""Function metadata."""
|
|
61
|
+
|
|
62
|
+
name = "type_info"
|
|
63
|
+
description = "Return type name for uint32 input"
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def compute(
|
|
67
|
+
cls,
|
|
68
|
+
v: Annotated[pa.UInt32Array, Param(doc="Input value")],
|
|
69
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
70
|
+
"""Return 'uint32' for each row."""
|
|
71
|
+
return _type_info_result("uint32", v)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class TypeInfoUInt64Function(ScalarFunction):
|
|
75
|
+
"""Return type name for uint64 input."""
|
|
76
|
+
|
|
77
|
+
class Meta:
|
|
78
|
+
"""Function metadata."""
|
|
79
|
+
|
|
80
|
+
name = "type_info"
|
|
81
|
+
description = "Return type name for uint64 input"
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def compute(
|
|
85
|
+
cls,
|
|
86
|
+
v: Annotated[pa.UInt64Array, Param(doc="Input value")],
|
|
87
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
88
|
+
"""Return 'uint64' for each row."""
|
|
89
|
+
return _type_info_result("uint64", v)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class TypeInfoStringFunction(ScalarFunction):
|
|
93
|
+
"""Return type name for string input."""
|
|
94
|
+
|
|
95
|
+
class Meta:
|
|
96
|
+
"""Function metadata."""
|
|
97
|
+
|
|
98
|
+
name = "type_info"
|
|
99
|
+
description = "Return type name for string input"
|
|
100
|
+
|
|
101
|
+
@classmethod
|
|
102
|
+
def compute(
|
|
103
|
+
cls,
|
|
104
|
+
v: Annotated[pa.StringArray, Param(doc="Input value")],
|
|
105
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
106
|
+
"""Return 'varchar' for each row."""
|
|
107
|
+
return _type_info_result("varchar", v)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _pair_type_result(label: str, a: pa.Array, b: pa.Array) -> pa.StringArray: # type: ignore[type-arg]
|
|
111
|
+
"""Shared compute logic for all pair_type overloads."""
|
|
112
|
+
return pa.array(
|
|
113
|
+
[
|
|
114
|
+
label if (x is not None and y is not None) else None
|
|
115
|
+
for x, y in zip(a.to_pylist(), b.to_pylist(), strict=True)
|
|
116
|
+
],
|
|
117
|
+
type=pa.string(),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class PairTypeIntIntFunction(ScalarFunction):
|
|
122
|
+
"""Return 'int+int' for two int64 columns."""
|
|
123
|
+
|
|
124
|
+
class Meta:
|
|
125
|
+
"""Function metadata."""
|
|
126
|
+
|
|
127
|
+
name = "pair_type"
|
|
128
|
+
description = "Return type pair name for int+int"
|
|
129
|
+
|
|
130
|
+
@classmethod
|
|
131
|
+
def compute(
|
|
132
|
+
cls,
|
|
133
|
+
a: Annotated[pa.Int64Array, Param(doc="First value")],
|
|
134
|
+
b: Annotated[pa.Int64Array, Param(doc="Second value")],
|
|
135
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
136
|
+
"""Return 'int+int' for each row."""
|
|
137
|
+
return _pair_type_result("int+int", a, b)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class PairTypeStrStrFunction(ScalarFunction):
|
|
141
|
+
"""Return 'str+str' for two string columns."""
|
|
142
|
+
|
|
143
|
+
class Meta:
|
|
144
|
+
"""Function metadata."""
|
|
145
|
+
|
|
146
|
+
name = "pair_type"
|
|
147
|
+
description = "Return type pair name for str+str"
|
|
148
|
+
|
|
149
|
+
@classmethod
|
|
150
|
+
def compute(
|
|
151
|
+
cls,
|
|
152
|
+
a: Annotated[pa.StringArray, Param(doc="First value")],
|
|
153
|
+
b: Annotated[pa.StringArray, Param(doc="Second value")],
|
|
154
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
155
|
+
"""Return 'str+str' for each row."""
|
|
156
|
+
return _pair_type_result("str+str", a, b)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class PairTypeIntStrFunction(ScalarFunction):
|
|
160
|
+
"""Return 'int+str' for int64 + string columns."""
|
|
161
|
+
|
|
162
|
+
class Meta:
|
|
163
|
+
"""Function metadata."""
|
|
164
|
+
|
|
165
|
+
name = "pair_type"
|
|
166
|
+
description = "Return type pair name for int+str"
|
|
167
|
+
|
|
168
|
+
@classmethod
|
|
169
|
+
def compute(
|
|
170
|
+
cls,
|
|
171
|
+
a: Annotated[pa.Int64Array, Param(doc="First value")],
|
|
172
|
+
b: Annotated[pa.StringArray, Param(doc="Second value")],
|
|
173
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
174
|
+
"""Return 'int+str' for each row."""
|
|
175
|
+
return _pair_type_result("int+str", a, b)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class AnyMixedIntFunction(ScalarFunction):
|
|
179
|
+
"""AnyArrow first param, Int64 second param."""
|
|
180
|
+
|
|
181
|
+
class Meta:
|
|
182
|
+
"""Function metadata."""
|
|
183
|
+
|
|
184
|
+
name = "any_mixed"
|
|
185
|
+
description = "Any+int dispatch"
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def compute(
|
|
189
|
+
cls,
|
|
190
|
+
a: Annotated[pa.Array, Param(doc="Any type value")], # type: ignore[type-arg]
|
|
191
|
+
b: Annotated[pa.Int64Array, Param(doc="Int value")],
|
|
192
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
193
|
+
"""Return 'any+int: {b}' for each row."""
|
|
194
|
+
return pa.array(
|
|
195
|
+
[f"any+int: {y}" if y is not None else None for y in b.to_pylist()],
|
|
196
|
+
type=pa.string(),
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class AnyMixedStrFunction(ScalarFunction):
|
|
201
|
+
"""AnyArrow first param, String second param."""
|
|
202
|
+
|
|
203
|
+
class Meta:
|
|
204
|
+
"""Function metadata."""
|
|
205
|
+
|
|
206
|
+
name = "any_mixed"
|
|
207
|
+
description = "Any+str dispatch"
|
|
208
|
+
|
|
209
|
+
@classmethod
|
|
210
|
+
def compute(
|
|
211
|
+
cls,
|
|
212
|
+
a: Annotated[pa.Array, Param(doc="Any type value")], # type: ignore[type-arg]
|
|
213
|
+
b: Annotated[pa.StringArray, Param(doc="String value")],
|
|
214
|
+
) -> Annotated[pa.StringArray, Returns()]:
|
|
215
|
+
"""Return 'any+str: {b}' for each row."""
|
|
216
|
+
return pa.array(
|
|
217
|
+
[f"any+str: {y}" if y is not None else None for y in b.to_pylist()],
|
|
218
|
+
type=pa.string(),
|
|
219
|
+
)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Self-contained schema-reconciliation test fixture.
|
|
4
|
+
|
|
5
|
+
Exposes one writable virtual table whose declared Arrow schema is
|
|
6
|
+
deliberately quirky:
|
|
7
|
+
|
|
8
|
+
- ``id`` int64 NOT NULL
|
|
9
|
+
- ``ts`` timestamp[ms, tz=UTC] NOT NULL
|
|
10
|
+
- ``nested`` struct{a int32 NOT NULL, b string, ts2 timestamp[ms, tz=UTC]} NOT NULL
|
|
11
|
+
- ``tags`` list<item: struct<k string NOT NULL, v binary>> NOT NULL
|
|
12
|
+
- ``rowid`` int64 NOT NULL (DuckDB pseudocolumn)
|
|
13
|
+
|
|
14
|
+
Every facet of this schema (top-level NOT NULL primitives, TZ-aware
|
|
15
|
+
millisecond timestamps, NOT NULL leaves inside structs and lists) is
|
|
16
|
+
something DuckDB's ``ArrowConverter::ToArrowSchema`` cannot preserve on
|
|
17
|
+
the round trip — so the C++ ``ReconcileBatchToSchema`` helper inside the
|
|
18
|
+
vgi extension must reshape/cast every batch DuckDB hands the worker.
|
|
19
|
+
|
|
20
|
+
The INSERT, UPDATE, and DELETE handlers assert on the exact Arrow schema
|
|
21
|
+
of each batch they receive. If reconciliation drops a flag or fails to
|
|
22
|
+
cast a timestamp, the test fixture raises a loud ``ValueError`` rather
|
|
23
|
+
than silently storing wrong data — which is exactly what we want a
|
|
24
|
+
regression to look like.
|
|
25
|
+
|
|
26
|
+
The fixture is dependency-free: no transactor, no DuckDB, no SQLite.
|
|
27
|
+
Storage is a process-local dict keyed by rowid. Concurrency is not a
|
|
28
|
+
concern (one worker process per test).
|
|
29
|
+
"""
|