diff --git a/pyproject.toml b/pyproject.toml index bba7c97..b412a0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,8 @@ write_to = "src/substrait/_version.py" [project.optional-dependencies] extensions = ["antlr4-python3-runtime", "pyyaml"] gen_proto = ["protobuf == 3.20.1", "protoletariat >= 2.0.0"] -test = ["pytest >= 7.0.0", "antlr4-python3-runtime", "pyyaml"] +sql = ["sqloxide", "deepdiff"] +test = ["pytest >= 7.0.0", "antlr4-python3-runtime", "pyyaml", "sqloxide", "deepdiff", "duckdb<=1.2.2", "datafusion"] [tool.pytest.ini_options] pythonpath = "src" diff --git a/src/substrait/builders/plan.py b/src/substrait/builders/plan.py index 51cc64a..eca32da 100644 --- a/src/substrait/builders/plan.py +++ b/src/substrait/builders/plan.py @@ -26,8 +26,8 @@ def _merge_extensions(*objs): return { - "extension_uris": merge_extension_uris(*[b.extension_uris for b in objs]), - "extensions": merge_extension_declarations(*[b.extensions for b in objs]), + "extension_uris": merge_extension_uris(*[b.extension_uris for b in objs if b]), + "extensions": merge_extension_declarations(*[b.extensions for b in objs if b]), } @@ -193,13 +193,15 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: bound_plan = plan if isinstance(plan, stp.Plan) else plan(registry) ns = infer_plan_schema(bound_plan) - bound_offset = resolve_expression(offset, ns, registry) + bound_offset = resolve_expression(offset, ns, registry) if offset else None bound_count = resolve_expression(count, ns, registry) rel = stalg.Rel( fetch=stalg.FetchRel( input=bound_plan.relations[-1].root.input, - offset_expr=bound_offset.referred_expr[0].expression, + offset_expr=bound_offset.referred_expr[0].expression + if bound_offset + else None, count_expr=bound_count.referred_expr[0].expression, ) ) diff --git a/src/substrait/sql/sql_to_substrait.py b/src/substrait/sql/sql_to_substrait.py new file mode 100644 index 0000000..b11e385 --- /dev/null +++ b/src/substrait/sql/sql_to_substrait.py @@ -0,0 +1,339 @@ +import random +import string +from sqloxide import parse_sql +from substrait.builders.extended_expression import ( + UnboundExtendedExpression, + column, + scalar_function, + literal, + aggregate_function, + window_function, +) +from substrait.builders.plan import ( + read_named_table, + project, + filter, + sort, + fetch, + set, + join, + aggregate, +) +from substrait.gen.proto import type_pb2 as stt +from substrait.gen.proto import algebra_pb2 as stalg +from substrait.extension_registry import ExtensionRegistry +from typing import Callable +from deepdiff import DeepDiff + +SchemaResolver = Callable[[str], stt.NamedStruct] + +function_mapping = { + "Plus": ("functions_arithmetic.yaml", "add"), + "Minus": ("functions_arithmetic.yaml", "subtract"), + "Gt": ("functions_comparison.yaml", "gt"), + "GtEq": ("functions_comparison.yaml", "gte"), + "Lt": ("functions_comparison.yaml", "lt"), + "Eq": ("functions_comparison.yaml", "equal"), +} + +aggregate_function_mapping = {"SUM": ("functions_arithmetic.yaml", "sum")} + +window_function_mapping = { + "row_number": ("functions_arithmetic.yaml", "row_number"), +} + + +def compare_dicts(dict1, dict2): + diff = DeepDiff(dict1, dict2, exclude_regex_paths=["span"]) + return len(diff) == 0 + + +def translate_expression( + ast: dict, + schema_resolver: SchemaResolver, + registry: ExtensionRegistry, + measures: list[UnboundExtendedExpression], + groupings: list[dict], + alias: str = None, +) -> UnboundExtendedExpression: + assert len(ast) == 1 + op = list(ast.keys())[0] + + if groupings: + # This means we are parsing a projection after a grouping + # Loop through used groupings for an identical ast and return it rather than recalculate + for i, f in enumerate(groupings): + if compare_dicts(ast, f): + return column(i, alias=alias) + + ast = ast[op] + + if op == "Identifier": + return column(ast["value"], alias=alias) + elif op == "UnnamedExpr" or op == "expr" or op == "Unnamed" or op == "Expr": + return translate_expression( + ast, + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=groupings, + ) + elif op == "ExprWithAlias": + return translate_expression( + ast["expr"], + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=groupings, + alias=ast["alias"]["value"], + ) + elif op == "BinaryOp": + expressions = [ + translate_expression( + ast["left"], + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=groupings, + ), + translate_expression( + ast["right"], + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=groupings, + ), + ] + func = function_mapping[ast["op"]] + return scalar_function(func[0], func[1], expressions=expressions, alias=alias) + elif op == "Value": + return literal( + int(ast["value"]["Number"][0]), stt.Type(i64=stt.Type.I64()), alias=alias + ) # TODO infer type + elif op == "Function": + expressions = [ + translate_expression( + e, + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=groupings, + ) + for e in ast["args"]["List"]["args"] + ] + name = ast["name"][0]["Identifier"]["value"] + + if name in function_mapping: + func = function_mapping[name] + return scalar_function(func[0], func[1], *expressions, alias=alias) + elif name in aggregate_function_mapping: + # All measures need to be extracted out because substrait calculates measures in a separate rel + # We generate a random name for the measure and return a column with that name for the projection to work + # Start by checking if multiple measures are identical and reuse previously generated name + for m in measures: + if compare_dicts(ast, m[1]): + return column(m[2], alias=alias) + + func = aggregate_function_mapping[name] + random_name = "".join( + random.choices(string.ascii_uppercase + string.digits, k=5) + ) # TODO make this deterministic + aggr = aggregate_function(func[0], func[1], expressions, alias=random_name) + measures.append((aggr, ast, random_name)) + return column(random_name, alias=alias) + elif name in window_function_mapping: + func = window_function_mapping[name] + + partitions = [ + translate_expression( + e, + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=groupings, + ) + for e in ast["over"]["WindowSpec"]["partition_by"] + ] + + return window_function( + func[0], func[1], expressions, partitions=partitions, alias=alias + ) + + else: + raise Exception(f"Unknown function {name}") + # elif op == "Wildcard": + # return wildcard() + else: + raise Exception(f"Unknown op {op}") + + +def translate(ast: dict, schema_resolver: SchemaResolver, registry: ExtensionRegistry): + assert len(ast) == 1 + op = list(ast.keys())[0] + ast = ast[op] + + if op == "Query": + relation = translate( + ast["body"], schema_resolver=schema_resolver, registry=registry + ) + + if ast["order_by"]: + expressions = [ + translate_expression( + e["expr"], + schema_resolver=schema_resolver, + registry=registry, + measures=None, + groupings=None, + ) + for e in ast["order_by"]["kind"]["Expressions"] + ] + relation = sort(relation, expressions)(registry) + + if ast["limit_clause"]: + limit_expression = translate_expression( + ast["limit_clause"]["LimitOffset"]["limit"], + schema_resolver=schema_resolver, + registry=registry, + measures=None, + groupings=None, + ) + + if ast["limit_clause"]["LimitOffset"]["offset"]: + offset_expression = translate_expression( + ast["limit_clause"]["LimitOffset"]["offset"]["value"], + schema_resolver=schema_resolver, + registry=registry, + measures=None, + groupings=None, + ) + else: + offset_expression = None + + relation = fetch(relation, offset_expression, limit_expression)(registry) + + return relation + elif op == "Select": + relation = translate( + ast["from"][0]["relation"], + schema_resolver=schema_resolver, + registry=registry, + ) + + if ast["from"][0]["joins"]: + for _join in ast["from"][0]["joins"]: + join_type_mapping = { + "Inner": stalg.JoinRel.JOIN_TYPE_INNER, + "Left": stalg.JoinRel.JOIN_TYPE_LEFT, + "LeftOuter": stalg.JoinRel.JOIN_TYPE_LEFT, + "RightOuter": stalg.JoinRel.JOIN_TYPE_RIGHT, + "Right": stalg.JoinRel.JOIN_TYPE_RIGHT, + } + right = translate( + _join["relation"], + schema_resolver=schema_resolver, + registry=registry, + ) + + join_type = list(_join["join_operator"].keys())[0] + + expression = translate_expression( + _join["join_operator"][join_type]["On"], + schema_resolver=schema_resolver, + registry=registry, + measures=None, + groupings=None, + ) + + relation = join( + relation, right, expression, join_type_mapping[join_type] + )(registry) + + if "selection" in ast and ast["selection"]: + where_expression = translate_expression( + ast["selection"], + schema_resolver=schema_resolver, + registry=registry, + measures=None, + groupings=None, + ) + relation = filter(relation, where_expression)(registry) + + if ast["group_by"] and ast["group_by"]["Expressions"][0]: + groupings = ast["group_by"]["Expressions"][0] + grouping_expressions = [ + translate_expression( + e, + schema_resolver=schema_resolver, + registry=registry, + measures=None, + groupings=None, + ) + for e in groupings + ] + else: + groupings = [] + grouping_expressions = [] + + measures = [] + + projection = [ + translate_expression( + p, + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=groupings, + ) + for p in ast["projection"] + ] + + if ast["having"]: + having_predicate = translate_expression( + ast["having"], + schema_resolver=schema_resolver, + registry=registry, + measures=measures, + groupings=[], + ) + else: + having_predicate = None + + if measures or groupings: + relation = aggregate( + relation, grouping_expressions, [e[0] for e in measures] + )(registry) + + if having_predicate: + relation = filter(relation, having_predicate)(registry) + + return project(relation, expressions=projection)(registry) + elif op == "Table": + name = ast["name"][0]["Identifier"]["value"] + return read_named_table(name, schema_resolver(name)) + elif op == "SetOperation": + # TODO more than 2 inputs to a set operation + left = translate( + ast["left"], schema_resolver=schema_resolver, registry=registry + ) + right = translate( + ast["right"], schema_resolver=schema_resolver, registry=registry + ) + if ast["op"] == "Union": + set_op = ( + stalg.SetRel.SET_OP_UNION_ALL + if ast["set_quantifier"] == "All" + else stalg.SetRel.SET_OP_UNION_DISTINCT + ) + else: + raise Exception("") + + return set([left, right], set_op)(registry) + else: + raise Exception(f"Unknown op {op}") + + +def convert(query: str, dialect: str, schema_resolver: SchemaResolver): + ast = parse_sql(sql=query, dialect=dialect)[0] + registry = ExtensionRegistry(load_default_extensions=True) + return translate(ast, schema_resolver=schema_resolver, registry=registry) diff --git a/tests/sql/test_sql_to_substrait.py b/tests/sql/test_sql_to_substrait.py new file mode 100644 index 0000000..ec33ee8 --- /dev/null +++ b/tests/sql/test_sql_to_substrait.py @@ -0,0 +1,317 @@ +from substrait.sql.sql_to_substrait import convert +import pyarrow +import substrait.json +import tempfile +import pyarrow.substrait as pa_substrait +import pytest +import sys + + +data: pyarrow.Table = pyarrow.Table.from_batches( + [ + pyarrow.record_batch( + [[2, 1, 3, 4], ["a", "b", "c", "d"]], + names=["store_id", "name"], + ) + ] +) + + +sales_data = pyarrow.Table.from_batches( + [ + pyarrow.record_batch( + [ + [1, 2, 3], + [1, 1, 4], + [10, 20, 50], + ], + names=["sale_id", "fk_store_id", "amount"], + ) + ] +) + + +def sort_arrow(table: pyarrow.Table): + import pyarrow.compute as pc + + sort_keys = [(name, "ascending") for name in table.column_names] + sort_indices = pc.sort_indices(table, sort_keys) + sorted_table = pc.take(table, sort_indices) + return sorted_table + + +def assert_query_datafusion(query: str, ignore_order=True): + from datafusion import SessionContext + from datafusion import substrait as ss + + ctx = SessionContext() + ctx.register_record_batches("stores", [data.to_batches()]) + ctx.register_record_batches("sales", [sales_data.to_batches()]) + + def df_schema_resolver(name: str): + pa_schema = ctx.sql(f"SELECT * FROM {name} LIMIT 0").schema() + return pa_substrait.serialize_schema(pa_schema).to_pysubstrait().base_schema + + plan = convert(query, "generic", df_schema_resolver) + + sql_arrow = ctx.sql(query).to_arrow_table() + + substrait_plan = ss.Serde.deserialize_bytes(plan.SerializeToString()) + df_logical_plan = ss.Consumer.from_substrait_plan(ctx, substrait_plan) + df = ctx.create_dataframe_from_logical_plan(df_logical_plan) + substrait_arrow = df.to_arrow_table() + + if ignore_order: + substrait_arrow = sort_arrow(substrait_arrow) + sql_arrow = sort_arrow(sql_arrow) + + assert substrait_arrow.equals(sql_arrow, check_metadata=True) + + +def assert_query_duckdb(query: str, ignore_order=True): + import duckdb + + duckdb.install_extension("substrait", repository="community") + duckdb.load_extension("substrait") + + with tempfile.TemporaryDirectory() as temp_dir: + db = f"{temp_dir}/test.db" + + conn = duckdb.connect(db) + + def duckdb_schema_resolver(name: str): + pa_schema = conn.sql(f"SELECT * FROM {name} LIMIT 0").arrow().schema + return pa_substrait.serialize_schema(pa_schema).to_pysubstrait().base_schema + + conn.register("stores", data) + conn.register("sales", sales_data) + + plan = convert(query, "duckdb", duckdb_schema_resolver) + + conn.install_extension("substrait", repository="community") + conn.load_extension("substrait") + + plan_json = substrait.json.dump_json(plan) + sql = f"CALL from_substrait_json('{plan_json}')" + + substrait_out = conn.sql(sql) + sql_out = conn.sql(query) + + substrait_arrow = substrait_out.arrow() + sql_arrow = sql_out.arrow() + + if ignore_order: + substrait_arrow = sort_arrow(substrait_arrow) + sql_arrow = sort_arrow(sql_arrow) + + assert substrait_arrow.equals(sql_arrow, check_metadata=True) + + +def assert_query(query: str, engine: str, ignore_order=True): + if engine == "duckdb": + assert_query_duckdb(query, ignore_order) + elif engine == "datafusion": + assert_query_datafusion(query, ignore_order) + + +engines = [ + pytest.param( + "duckdb", + marks=pytest.mark.skipif( + sys.platform.startswith("win"), + reason="duckdb substrait extension not found on windows", + ), + ), + "datafusion", +] + + +@pytest.mark.parametrize("engine", engines) +def test_select_field(engine: str): + assert_query("""SELECT store_id FROM stores""", engine) + + +@pytest.mark.parametrize("engine", engines) +def test_inner_join_filtered(engine: str): + assert_query( + """SELECT sale_id + 1 as sale_id, name + FROM sales + INNER JOIN stores ON store_id = fk_store_id + WHERE sale_id < 3 + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_left_join(engine: str): + assert_query( + """SELECT sale_id + 1 as sale_id, name + FROM sales + LEFT JOIN stores ON store_id = fk_store_id + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_right_join(engine: str): + assert_query( + """SELECT sale_id + 1 as sale_id, name + FROM sales + RIGHT JOIN stores ON store_id = fk_store_id + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_group_by_empty_measures(engine: str): + assert_query( + """SELECT fk_store_id, sale_id + FROM sales + GROUP BY fk_store_id, sale_id + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_group_by_count(engine: str): + assert_query( + """SELECT fk_store_id, SUM(amount) as income + FROM sales + GROUP BY fk_store_id + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_group_by_unnamed_expr(engine: str): + assert_query( + """SELECT fk_store_id + 2 AS plustwo, SUM(amount) as income + FROM sales + GROUP BY fk_store_id + 2 + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_sum(engine: str): + assert_query( + """SELECT SUM(amount) + SUM(fk_store_id) as income + FROM sales + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_group_by_hidden_dimension(engine: str): + assert_query( + """SELECT fk_store_id + FROM sales + GROUP BY fk_store_id, sale_id + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_group_by_having_no_duplicate(engine: str): + assert_query( + """SELECT fk_store_id, SUM(amount + 1) as income + FROM sales + GROUP BY fk_store_id + HAVING SUM(amount) < 40 + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_group_by_having_duplicate(engine: str): + assert_query( + """SELECT fk_store_id, SUM(amount) as income + FROM sales + GROUP BY fk_store_id + HAVING SUM(amount) < 40 + """, + engine, + ) + + +@pytest.mark.parametrize("engine", engines) +def test_order_by(engine: str): + assert_query( + """SELECT store_id FROM stores ORDER BY store_id""", engine, ignore_order=False + ) + + +@pytest.mark.parametrize( + "engine", + [ + pytest.param( + "duckdb", + marks=[ + pytest.mark.skipif( + sys.platform.startswith("win"), + reason="duckdb substrait extension not found on windows", + ), + pytest.mark.xfail, + ], + ), + "datafusion", + ], +) +def test_select_limit(engine: str): + assert_query("""SELECT store_id FROM stores ORDER BY store_id LIMIT 2""", engine) + + +@pytest.mark.parametrize( + "engine", + [ + pytest.param( + "duckdb", + marks=[ + pytest.mark.skipif( + sys.platform.startswith("win"), + reason="duckdb substrait extension not found on windows", + ), + pytest.mark.xfail, + ], + ), + "datafusion", + ], +) +def test_select_limit_offset(engine: str): + assert_query( + """SELECT store_id FROM stores ORDER BY store_id LIMIT 2 OFFSET 2""", engine + ) + + +@pytest.mark.parametrize( + "engine", + [ + pytest.param( + "duckdb", + marks=[ + pytest.mark.skipif( + sys.platform.startswith("win"), + reason="duckdb substrait extension not found on windows", + ), + pytest.mark.xfail, + ], + ), + "datafusion", + ], +) +def test_row_number(engine: str): + assert_query( + """SELECT sale_id, fk_store_id, row_number() over (partition by fk_store_id order by sale_id) as rn + FROM sales + """, + engine, + ) diff --git a/uv.lock b/uv.lock index f3543bc..d89c6a6 100644 --- a/uv.lock +++ b/uv.lock @@ -54,6 +54,83 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "datafusion" +version = "47.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyarrow" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/50/4bddadafa559d58146a7686f28beeae65c58c8d019ba63ca14a56c0eef45/datafusion-47.0.0.tar.gz", hash = "sha256:19a6976731aa96a6f6e264c390c64b9e32051e866366bd69450bc77e67bc91b1", size = 172795, upload-time = "2025-05-28T18:23:52.504Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/47/4a4e223a98db03b4447b6d24f52986321d0fe02f60d8ed56430ffdb4b51a/datafusion-47.0.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:ccd83a8e49fb39be06ddfa87023200a9ddc93d181247654ac951fa5720219d08", size = 25162494, upload-time = "2025-05-28T18:23:17.155Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/f65413e64742e170b99e4404a1090b6f722fc2b939c402e0793eeb2ba78a/datafusion-47.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:43677e6284b165727031aec14d4beaa97296e991960293c61dcb66a3a9ce59b8", size = 23143314, upload-time = "2025-05-28T18:23:24.734Z" }, + { url = "https://files.pythonhosted.org/packages/5f/63/796be8eeed404fdf7487d0911e7e5cec0f5647cb17423210997c293eacb3/datafusion-47.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d244ed32a2fae7c4dd292a6bfe092cc94b3b86c600eddb7d633609043d406bae", size = 27767937, upload-time = "2025-05-28T18:23:33.257Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ed/f16ef2fb05df78e1b88b67f2881815f745716bc635f717dfd64794225534/datafusion-47.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:b3304ec63fb89f27e4280226807fd033ed7f0ea36d2d69fecf68f257d975c24d", size = 26674823, upload-time = "2025-05-28T18:23:41.166Z" }, + { url = "https://files.pythonhosted.org/packages/da/30/08a6620a05e81cbbbadf02e755c6c456c7e324f9e038674928495c5c6298/datafusion-47.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:73c5d056908185c77eedcaea43a5a8ab5e1c2e747a3e34d36d3625e09a3dc2af", size = 27229351, upload-time = "2025-05-28T18:23:50.408Z" }, +] + +[[package]] +name = "deepdiff" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "orderly-set" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/0f/9cd2624f7dcd755cbf1fa21fb7234541f19a1be96a56f387ec9053ebe220/deepdiff-8.5.0.tar.gz", hash = "sha256:a4dd3529fa8d4cd5b9cbb6e3ea9c95997eaa919ba37dac3966c1b8f872dc1cd1", size = 538517, upload-time = "2025-05-09T18:44:10.035Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/3b/2e0797200c51531a6d8c97a8e4c9fa6fb56de7e6e2a15c1c067b6b10a0b0/deepdiff-8.5.0-py3-none-any.whl", hash = "sha256:d4599db637f36a1c285f5fdfc2cd8d38bde8d8be8636b65ab5e425b67c54df26", size = 85112, upload-time = "2025-05-09T18:44:07.784Z" }, +] + +[[package]] +name = "duckdb" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/28/b8/0f86278684fb7a1fac7c0c869fc6d68ed005cdc91c963eb4373e0551bc0a/duckdb-1.2.2.tar.gz", hash = "sha256:1e53555dece49201df08645dbfa4510c86440339889667702f936b7d28d39e43", size = 11595514, upload-time = "2025-04-08T08:47:20.234Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/47/d17eecc8bf23519f4385a7ad361482e5791f6b94995a50839f130c469626/duckdb-1.2.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:6e5e6c333b550903ff11919ed1154c60c9b9d935db51afdb263babe523a8a69e", size = 15255351, upload-time = "2025-04-08T08:45:14.845Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d1/317397198e0481339c469441762ce4e563f612479c2be70ddba3c1493bf2/duckdb-1.2.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:c1fcbc579de8e4fa7e34242fd6f419c1a39520073b1fe0c29ed6e60ed5553f38", size = 31925074, upload-time = "2025-04-08T08:45:17.649Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e2/9f8cfa9d8a8d1370ae2b5cf0c6a34e6adc51be533771fd75b5ff84fb2441/duckdb-1.2.2-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:690885060c4140922ffa2f6935291c6e74ddad0ca2cf33bff66474ce89312ab3", size = 16779904, upload-time = "2025-04-08T08:45:21.97Z" }, + { url = "https://files.pythonhosted.org/packages/e6/47/3651b1ab62b6e8ce15a1ead5d81d4bc76b09912c2ae0b11aa0bbcbd0209d/duckdb-1.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a382782980643f5ee827990b76f079b22f47786509061c0afac28afaa5b8bf5", size = 18726556, upload-time = "2025-04-08T08:45:24.353Z" }, + { url = "https://files.pythonhosted.org/packages/6d/66/6b2a433d042a3a5109c1a62a4daaea40b908e7876756aed2837adaf0ca26/duckdb-1.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7c33345570ed8c50c9fe340c2767470115cc02d330f25384104cfad1f6e54f5", size = 20195269, upload-time = "2025-04-08T08:45:26.969Z" }, + { url = "https://files.pythonhosted.org/packages/a3/38/1737151fba968c0e7221b68d11c80ed9ff63edf380d91058426b51f1b233/duckdb-1.2.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b744f8293ce649d802a9eabbf88e4930d672cf9de7d4fc9af5d14ceaeeec5805", size = 18737528, upload-time = "2025-04-08T08:45:29.097Z" }, + { url = "https://files.pythonhosted.org/packages/b3/37/bfde2ea14353a297e7effe9e4688b4e60a3ec08a9bd67c404c64046e5d9e/duckdb-1.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c8680e81b0c77be9fc968c1dd4cd38395c34b18bb693cbfc7b7742c18221cc9b", size = 22254571, upload-time = "2025-04-08T08:45:32.369Z" }, + { url = "https://files.pythonhosted.org/packages/f0/42/392736bfd62b5b5f0d9ea15b010c90a8c92c21fdfc4372e46160f3d8f680/duckdb-1.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:fb41f2035a70378b3021f724bb08b047ca4aa475850a3744c442570054af3c52", size = 11366201, upload-time = "2025-04-08T08:45:34.817Z" }, + { url = "https://files.pythonhosted.org/packages/c1/41/78c63937a4f7a5de7d128203c567303d4813c1109b7d17e6b3959f0882e1/duckdb-1.2.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:081110ffbc9d53c9740ef55482c93b97db2f8030d681d1658827d2e94f77da03", size = 15258298, upload-time = "2025-04-08T08:45:36.648Z" }, + { url = "https://files.pythonhosted.org/packages/94/b2/91d983ecd67a1b87343e98395ffe7d77c996e1798c1bab339beed4680693/duckdb-1.2.2-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:53a154dbc074604036a537784ce5d1468edf263745a4363ca06fdb922f0d0a99", size = 31933969, upload-time = "2025-04-08T08:45:39.356Z" }, + { url = "https://files.pythonhosted.org/packages/ad/12/4737b682cbc1b4778ffb37e4f4cdb603676c50aec89d6c9781ec29d3e904/duckdb-1.2.2-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:0353f80882c066f7b14451852395b7a360f3d4846a10555c4268eb49144ea11c", size = 16784775, upload-time = "2025-04-08T08:45:42.246Z" }, + { url = "https://files.pythonhosted.org/packages/71/be/dfb52b579a0b82aa92993aecc100bd951d0bd1850c6a8d47c68953a9de62/duckdb-1.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b134a5002757af1ae44a9ae26c2fe963ffa09eb47a62779ce0c5eeb44bfc2f28", size = 18731124, upload-time = "2025-04-08T08:45:44.573Z" }, + { url = "https://files.pythonhosted.org/packages/ca/49/153dd6289a3d06e87c3199a5547ccc04c574d167d7f85c1a8196218bf040/duckdb-1.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd9c434127fd1575694e1cf19a393bed301f5d6e80b4bcdae80caa368a61a678", size = 20199712, upload-time = "2025-04-08T08:45:47.031Z" }, + { url = "https://files.pythonhosted.org/packages/97/ce/f27a7b735a8abb04e2c1efcc05178e25e455539c74d70f76c2845bae8473/duckdb-1.2.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:890f58855d127c25bc3a53f4c24b27e79391c4468c4fcc99bc10d87b5d4bd1c4", size = 18739966, upload-time = "2025-04-08T08:45:49.779Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f2/a8066267eb5fcd1f535776efde29b6d0fa678d978a7de73f47bc59cc940d/duckdb-1.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a5002305cdd4e76c94b61b50abc5e3f4e32c9cb81116960bb4b74acbbc9c6c8", size = 22255946, upload-time = "2025-04-08T08:45:52.274Z" }, + { url = "https://files.pythonhosted.org/packages/df/74/8a05ef00c554882d8300c2c261e8f7e7ead74e2b3ff66059599ff2646cf4/duckdb-1.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:cdb9999c6a109aa31196cdd22fc58a810a3d35d08181a25d1bf963988e89f0a5", size = 11368173, upload-time = "2025-04-08T08:45:54.846Z" }, + { url = "https://files.pythonhosted.org/packages/77/25/549f68e55e1b455bd2daf2e5fc912000a3139fe0395111b3d49b23a2cec1/duckdb-1.2.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:f745379f44ad302560688855baaed9739c03b37a331338eda6a4ac655e4eb42f", size = 15271882, upload-time = "2025-04-08T08:45:57.156Z" }, + { url = "https://files.pythonhosted.org/packages/f6/84/13de7bf9056dcc7a346125d9a9f0f26f76c633db6b54052738f78f828538/duckdb-1.2.2-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:087713fc5958cae5eb59097856b3deaae0def021660c8f2052ec83fa8345174a", size = 31964873, upload-time = "2025-04-08T08:45:59.701Z" }, + { url = "https://files.pythonhosted.org/packages/0f/53/c8d2d56a801b7843ea87f8533a3634e6b38f06910098a266f8a096bd4c61/duckdb-1.2.2-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:a1f96395319c447a31b9477881bd84b4cb8323d6f86f21ceaef355d22dd90623", size = 16800653, upload-time = "2025-04-08T08:46:02.527Z" }, + { url = "https://files.pythonhosted.org/packages/bb/36/e25791d879fb93b92a56bf481ce11949ab19109103ae2ba12d64e49355d9/duckdb-1.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6aba3bc0acf4f8d52b94f7746c3b0007b78b517676d482dc516d63f48f967baf", size = 18735524, upload-time = "2025-04-08T08:46:04.842Z" }, + { url = "https://files.pythonhosted.org/packages/d7/46/4745aa10a1e460f4c8b473eddaffe2c783ac5280e1e5929dd84bd1a1acde/duckdb-1.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5c1556775a9ebaa49b5c8d64718f155ac3e05b34a49e9c99443cf105e8b0371", size = 20210314, upload-time = "2025-04-08T08:46:07.052Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0d/8563fc5ece36252e3d07dd3d29c7a0a034dcf62f14bed7cdc016d95adcbe/duckdb-1.2.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d625cc7d2faacfb2fc83ebbe001ae75dda175b3d8dce6a51a71c199ffac3627a", size = 18755134, upload-time = "2025-04-08T08:46:09.274Z" }, + { url = "https://files.pythonhosted.org/packages/11/f1/b7ade7d980eee4fb3ad7469ccf23adb3668a9a28cf3989b24418392d3786/duckdb-1.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:73263f81545c5cb4360fbaf7b22a493e55ddf88fadbe639c43efb7bc8d7554c4", size = 22294397, upload-time = "2025-04-08T08:46:11.476Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c9/896e8ced7b408df81e015fe0c6497cda46c92d9dfc8bf84b6d13f5dad473/duckdb-1.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:b1c0c4d737fd2ab9681e4e78b9f361e0a827916a730e84fa91e76dca451b14d5", size = 11370381, upload-time = "2025-04-08T08:46:13.549Z" }, + { url = "https://files.pythonhosted.org/packages/41/31/5e2f68cbd000137f6ed52092ad83a8e9c09eca70c59e0b4c5eb679709997/duckdb-1.2.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:fb9a2c77236fae079185a990434cb9d8432902488ba990235c702fc2692d2dcd", size = 15272507, upload-time = "2025-04-08T08:46:15.605Z" }, + { url = "https://files.pythonhosted.org/packages/d2/15/aa9078fc897e744e077c0c1510e34db4c809de1d51ddb5cb62e1f9c61312/duckdb-1.2.2-cp313-cp313-macosx_12_0_universal2.whl", hash = "sha256:d8bb89e580cb9a3aaf42e4555bf265d3db9446abfb118e32150e1a5dfa4b5b15", size = 31965548, upload-time = "2025-04-08T08:46:18.593Z" }, + { url = "https://files.pythonhosted.org/packages/9f/28/943773d44fd97055c59b58dde9182733661c2b6e3b3549f15dc26b2e139e/duckdb-1.2.2-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:88916d7f0532dc926bed84b50408c00dcbe6d2097d0de93c3ff647d8d57b4f83", size = 16800600, upload-time = "2025-04-08T08:46:21.51Z" }, + { url = "https://files.pythonhosted.org/packages/39/51/2caf01e7791e490290798c8c155d4d702ed61d69e815915b42e72b3e7473/duckdb-1.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30bece4f58a6c7bb0944a02dd1dc6de435a9daf8668fa31a9fe3a9923b20bd65", size = 18735886, upload-time = "2025-04-08T08:46:24.26Z" }, + { url = "https://files.pythonhosted.org/packages/87/0c/48ae1d485725af3a452303af409a9022d751ecab260cb9ca2f8c9fb670bc/duckdb-1.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bd2c6373b8b54474724c2119f6939c4568c428e1d0be5bcb1f4e3d7f1b7c8bb", size = 20210481, upload-time = "2025-04-08T08:46:26.717Z" }, + { url = "https://files.pythonhosted.org/packages/69/c7/95fcd7bde0f754ea6700208d36b845379cbd2b28779c0eff4dd4a7396369/duckdb-1.2.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72f688a8b0df7030c5a28ca6072817c1f090979e08d28ee5912dee37c26a7d0c", size = 18756619, upload-time = "2025-04-08T08:46:29.035Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1b/c9eab9e84d4a70dd5f7e2a93dd6e9d7b4d868d3df755cd58b572d82d6c5d/duckdb-1.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26e9c349f56f7c99341b5c79bbaff5ba12a5414af0261e79bf1a6a2693f152f6", size = 22294667, upload-time = "2025-04-08T08:46:31.295Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3d/ce68db53084746a4a62695a4cb064e44ce04123f8582bb3afbf6ee944e16/duckdb-1.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1aec7102670e59d83512cf47d32a6c77a79df9df0294c5e4d16b6259851e2e9", size = 11370206, upload-time = "2025-04-08T08:46:33.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/a8/9d75eeab4ff76a4e9dae52298cd0c582f513300f3fc34db9520a6db6c4b1/duckdb-1.2.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:25ac669180f88fecca20f300b898e191f81aa674d51dde8a328bdeb28a572ab0", size = 15255341, upload-time = "2025-04-08T08:46:59.758Z" }, + { url = "https://files.pythonhosted.org/packages/67/52/745839eb1299be96379b52b6cc3783ee330e91ec8d325b157611b9a2d49c/duckdb-1.2.2-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:d42e7e545d1059e6b73d0f0baa9ae34c90684bfd8c862e70b0d8ab92e01e0e3f", size = 31923916, upload-time = "2025-04-08T08:47:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/0c/6b/0e1da90808ec4f60215c2a2873c5ae5a248337ccccc77c2b5fb71918f7eb/duckdb-1.2.2-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:f3ce127bcecc723f1c7bddbc57f0526d11128cb05bfd81ffcd5e69e2dd5a1624", size = 16778052, upload-time = "2025-04-08T08:47:06.091Z" }, + { url = "https://files.pythonhosted.org/packages/60/13/04974fdd6106492d6ebbd411c51fca949f73d1a08b5281f9b41c622b0386/duckdb-1.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2418937adb9d6d0ca823bd385b914495294db27bc2963749d54af6708757f679", size = 18727076, upload-time = "2025-04-08T08:47:08.456Z" }, + { url = "https://files.pythonhosted.org/packages/be/cf/f875823e9eae416928b7e583b2174e826e67c120297880f1dde3a726accc/duckdb-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d41f899ce7979e7b3f9097ebce70da5c659db2d81d08c07a72b2b50f869859", size = 20196346, upload-time = "2025-04-08T08:47:10.868Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3e/b483c5ad2223392474f4d74d42e522b7545a95154c673f81eea4252d7192/duckdb-1.2.2-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:85e90a9c5307cf4d9151844e60c80f492618ea6e9b71081020e7d462e071ac8f", size = 18724393, upload-time = "2025-04-08T08:47:13.235Z" }, + { url = "https://files.pythonhosted.org/packages/a6/99/349475c08be5abe686d647ca4585287bd01c01b16121f329e05e664630f4/duckdb-1.2.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:df8c8a4ec998139b8507213c44c50e24f62a36af1cfded87e8972173dc9f8baf", size = 22237700, upload-time = "2025-04-08T08:47:15.63Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1a/1a9da0336c146750ba1dc9a5ad1ab8c228da4512991e1d5b8f0e07076bd5/duckdb-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6507ad2445cd3479853fb6473164b5eb5b22446d283c9892cfbbd0a85c5f361d", size = 11400288, upload-time = "2025-04-08T08:47:17.999Z" }, +] + [[package]] name = "exceptiongroup" version = "1.3.0" @@ -75,6 +152,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] +[[package]] +name = "orderly-set" +version = "5.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/03/4a/38030da31c13dcd5a531490006e63a0954083fb115113be9393179738e25/orderly_set-5.4.1.tar.gz", hash = "sha256:a1fb5a4fdc5e234e9e8d8e5c1bbdbc4540f4dfe50d12bf17c8bc5dbf1c9c878d", size = 20943, upload-time = "2025-05-06T22:34:13.512Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/bc/e0dfb4db9210d92b44e49d6e61ba5caefbd411958357fa9d7ff489eeb835/orderly_set-5.4.1-py3-none-any.whl", hash = "sha256:b5e21d21680bd9ef456885db800c5cb4f76a03879880c0175e1b077fb166fd83", size = 12339, upload-time = "2025-05-06T22:34:12.564Z" }, +] + [[package]] name = "packaging" version = "25.0" @@ -126,6 +212,68 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/30/6b/d8b8fb09a31f85685d41f63d0d4a807c14aca175c71e17bebcfbf5dc768a/protoletariat-3.3.10-py3-none-any.whl", hash = "sha256:4b0ab790a1791613d9ef1c4159e03424a7f056592ca66578ba585ae96686ee2d", size = 20736, upload-time = "2025-03-19T22:39:13.679Z" }, ] +[[package]] +name = "pyarrow" +version = "20.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/ee/a7810cb9f3d6e9238e61d312076a9859bf3668fd21c69744de9532383912/pyarrow-20.0.0.tar.gz", hash = "sha256:febc4a913592573c8d5805091a6c2b5064c8bd6e002131f01061797d91c783c1", size = 1125187, upload-time = "2025-04-27T12:34:23.264Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/23/77094eb8ee0dbe88441689cb6afc40ac312a1e15d3a7acc0586999518222/pyarrow-20.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c7dd06fd7d7b410ca5dc839cc9d485d2bc4ae5240851bcd45d85105cc90a47d7", size = 30832591, upload-time = "2025-04-27T12:27:27.89Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d5/48cc573aff00d62913701d9fac478518f693b30c25f2c157550b0b2565cb/pyarrow-20.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:d5382de8dc34c943249b01c19110783d0d64b207167c728461add1ecc2db88e4", size = 32273686, upload-time = "2025-04-27T12:27:36.816Z" }, + { url = "https://files.pythonhosted.org/packages/37/df/4099b69a432b5cb412dd18adc2629975544d656df3d7fda6d73c5dba935d/pyarrow-20.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6415a0d0174487456ddc9beaead703d0ded5966129fa4fd3114d76b5d1c5ceae", size = 41337051, upload-time = "2025-04-27T12:27:44.4Z" }, + { url = "https://files.pythonhosted.org/packages/4c/27/99922a9ac1c9226f346e3a1e15e63dee6f623ed757ff2893f9d6994a69d3/pyarrow-20.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15aa1b3b2587e74328a730457068dc6c89e6dcbf438d4369f572af9d320a25ee", size = 42404659, upload-time = "2025-04-27T12:27:51.715Z" }, + { url = "https://files.pythonhosted.org/packages/21/d1/71d91b2791b829c9e98f1e0d85be66ed93aff399f80abb99678511847eaa/pyarrow-20.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:5605919fbe67a7948c1f03b9f3727d82846c053cd2ce9303ace791855923fd20", size = 40695446, upload-time = "2025-04-27T12:27:59.643Z" }, + { url = "https://files.pythonhosted.org/packages/f1/ca/ae10fba419a6e94329707487835ec721f5a95f3ac9168500bcf7aa3813c7/pyarrow-20.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a5704f29a74b81673d266e5ec1fe376f060627c2e42c5c7651288ed4b0db29e9", size = 42278528, upload-time = "2025-04-27T12:28:07.297Z" }, + { url = "https://files.pythonhosted.org/packages/7a/a6/aba40a2bf01b5d00cf9cd16d427a5da1fad0fb69b514ce8c8292ab80e968/pyarrow-20.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:00138f79ee1b5aca81e2bdedb91e3739b987245e11fa3c826f9e57c5d102fb75", size = 42918162, upload-time = "2025-04-27T12:28:15.716Z" }, + { url = "https://files.pythonhosted.org/packages/93/6b/98b39650cd64f32bf2ec6d627a9bd24fcb3e4e6ea1873c5e1ea8a83b1a18/pyarrow-20.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f2d67ac28f57a362f1a2c1e6fa98bfe2f03230f7e15927aecd067433b1e70ce8", size = 44550319, upload-time = "2025-04-27T12:28:27.026Z" }, + { url = "https://files.pythonhosted.org/packages/ab/32/340238be1eb5037e7b5de7e640ee22334417239bc347eadefaf8c373936d/pyarrow-20.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:4a8b029a07956b8d7bd742ffca25374dd3f634b35e46cc7a7c3fa4c75b297191", size = 25770759, upload-time = "2025-04-27T12:28:33.702Z" }, + { url = "https://files.pythonhosted.org/packages/47/a2/b7930824181ceadd0c63c1042d01fa4ef63eee233934826a7a2a9af6e463/pyarrow-20.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:24ca380585444cb2a31324c546a9a56abbe87e26069189e14bdba19c86c049f0", size = 30856035, upload-time = "2025-04-27T12:28:40.78Z" }, + { url = "https://files.pythonhosted.org/packages/9b/18/c765770227d7f5bdfa8a69f64b49194352325c66a5c3bb5e332dfd5867d9/pyarrow-20.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:95b330059ddfdc591a3225f2d272123be26c8fa76e8c9ee1a77aad507361cfdb", size = 32309552, upload-time = "2025-04-27T12:28:47.051Z" }, + { url = "https://files.pythonhosted.org/packages/44/fb/dfb2dfdd3e488bb14f822d7335653092dde150cffc2da97de6e7500681f9/pyarrow-20.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f0fb1041267e9968c6d0d2ce3ff92e3928b243e2b6d11eeb84d9ac547308232", size = 41334704, upload-time = "2025-04-27T12:28:55.064Z" }, + { url = "https://files.pythonhosted.org/packages/58/0d/08a95878d38808051a953e887332d4a76bc06c6ee04351918ee1155407eb/pyarrow-20.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8ff87cc837601532cc8242d2f7e09b4e02404de1b797aee747dd4ba4bd6313f", size = 42399836, upload-time = "2025-04-27T12:29:02.13Z" }, + { url = "https://files.pythonhosted.org/packages/f3/cd/efa271234dfe38f0271561086eedcad7bc0f2ddd1efba423916ff0883684/pyarrow-20.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:7a3a5dcf54286e6141d5114522cf31dd67a9e7c9133d150799f30ee302a7a1ab", size = 40711789, upload-time = "2025-04-27T12:29:09.951Z" }, + { url = "https://files.pythonhosted.org/packages/46/1f/7f02009bc7fc8955c391defee5348f510e589a020e4b40ca05edcb847854/pyarrow-20.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a6ad3e7758ecf559900261a4df985662df54fb7fdb55e8e3b3aa99b23d526b62", size = 42301124, upload-time = "2025-04-27T12:29:17.187Z" }, + { url = "https://files.pythonhosted.org/packages/4f/92/692c562be4504c262089e86757a9048739fe1acb4024f92d39615e7bab3f/pyarrow-20.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6bb830757103a6cb300a04610e08d9636f0cd223d32f388418ea893a3e655f1c", size = 42916060, upload-time = "2025-04-27T12:29:24.253Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ec/9f5c7e7c828d8e0a3c7ef50ee62eca38a7de2fa6eb1b8fa43685c9414fef/pyarrow-20.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:96e37f0766ecb4514a899d9a3554fadda770fb57ddf42b63d80f14bc20aa7db3", size = 44547640, upload-time = "2025-04-27T12:29:32.782Z" }, + { url = "https://files.pythonhosted.org/packages/54/96/46613131b4727f10fd2ffa6d0d6f02efcc09a0e7374eff3b5771548aa95b/pyarrow-20.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3346babb516f4b6fd790da99b98bed9708e3f02e734c84971faccb20736848dc", size = 25781491, upload-time = "2025-04-27T12:29:38.464Z" }, + { url = "https://files.pythonhosted.org/packages/a1/d6/0c10e0d54f6c13eb464ee9b67a68b8c71bcf2f67760ef5b6fbcddd2ab05f/pyarrow-20.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:75a51a5b0eef32727a247707d4755322cb970be7e935172b6a3a9f9ae98404ba", size = 30815067, upload-time = "2025-04-27T12:29:44.384Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e2/04e9874abe4094a06fd8b0cbb0f1312d8dd7d707f144c2ec1e5e8f452ffa/pyarrow-20.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:211d5e84cecc640c7a3ab900f930aaff5cd2702177e0d562d426fb7c4f737781", size = 32297128, upload-time = "2025-04-27T12:29:52.038Z" }, + { url = "https://files.pythonhosted.org/packages/31/fd/c565e5dcc906a3b471a83273039cb75cb79aad4a2d4a12f76cc5ae90a4b8/pyarrow-20.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ba3cf4182828be7a896cbd232aa8dd6a31bd1f9e32776cc3796c012855e1199", size = 41334890, upload-time = "2025-04-27T12:29:59.452Z" }, + { url = "https://files.pythonhosted.org/packages/af/a9/3bdd799e2c9b20c1ea6dc6fa8e83f29480a97711cf806e823f808c2316ac/pyarrow-20.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c3a01f313ffe27ac4126f4c2e5ea0f36a5fc6ab51f8726cf41fee4b256680bd", size = 42421775, upload-time = "2025-04-27T12:30:06.875Z" }, + { url = "https://files.pythonhosted.org/packages/10/f7/da98ccd86354c332f593218101ae56568d5dcedb460e342000bd89c49cc1/pyarrow-20.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:a2791f69ad72addd33510fec7bb14ee06c2a448e06b649e264c094c5b5f7ce28", size = 40687231, upload-time = "2025-04-27T12:30:13.954Z" }, + { url = "https://files.pythonhosted.org/packages/bb/1b/2168d6050e52ff1e6cefc61d600723870bf569cbf41d13db939c8cf97a16/pyarrow-20.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4250e28a22302ce8692d3a0e8ec9d9dde54ec00d237cff4dfa9c1fbf79e472a8", size = 42295639, upload-time = "2025-04-27T12:30:21.949Z" }, + { url = "https://files.pythonhosted.org/packages/b2/66/2d976c0c7158fd25591c8ca55aee026e6d5745a021915a1835578707feb3/pyarrow-20.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:89e030dc58fc760e4010148e6ff164d2f44441490280ef1e97a542375e41058e", size = 42908549, upload-time = "2025-04-27T12:30:29.551Z" }, + { url = "https://files.pythonhosted.org/packages/31/a9/dfb999c2fc6911201dcbf348247f9cc382a8990f9ab45c12eabfd7243a38/pyarrow-20.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6102b4864d77102dbbb72965618e204e550135a940c2534711d5ffa787df2a5a", size = 44557216, upload-time = "2025-04-27T12:30:36.977Z" }, + { url = "https://files.pythonhosted.org/packages/a0/8e/9adee63dfa3911be2382fb4d92e4b2e7d82610f9d9f668493bebaa2af50f/pyarrow-20.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:96d6a0a37d9c98be08f5ed6a10831d88d52cac7b13f5287f1e0f625a0de8062b", size = 25660496, upload-time = "2025-04-27T12:30:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/9b/aa/daa413b81446d20d4dad2944110dcf4cf4f4179ef7f685dd5a6d7570dc8e/pyarrow-20.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a15532e77b94c61efadde86d10957950392999503b3616b2ffcef7621a002893", size = 30798501, upload-time = "2025-04-27T12:30:48.351Z" }, + { url = "https://files.pythonhosted.org/packages/ff/75/2303d1caa410925de902d32ac215dc80a7ce7dd8dfe95358c165f2adf107/pyarrow-20.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:dd43f58037443af715f34f1322c782ec463a3c8a94a85fdb2d987ceb5658e061", size = 32277895, upload-time = "2025-04-27T12:30:55.238Z" }, + { url = "https://files.pythonhosted.org/packages/92/41/fe18c7c0b38b20811b73d1bdd54b1fccba0dab0e51d2048878042d84afa8/pyarrow-20.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa0d288143a8585806e3cc7c39566407aab646fb9ece164609dac1cfff45f6ae", size = 41327322, upload-time = "2025-04-27T12:31:05.587Z" }, + { url = "https://files.pythonhosted.org/packages/da/ab/7dbf3d11db67c72dbf36ae63dcbc9f30b866c153b3a22ef728523943eee6/pyarrow-20.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6953f0114f8d6f3d905d98e987d0924dabce59c3cda380bdfaa25a6201563b4", size = 42411441, upload-time = "2025-04-27T12:31:15.675Z" }, + { url = "https://files.pythonhosted.org/packages/90/c3/0c7da7b6dac863af75b64e2f827e4742161128c350bfe7955b426484e226/pyarrow-20.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:991f85b48a8a5e839b2128590ce07611fae48a904cae6cab1f089c5955b57eb5", size = 40677027, upload-time = "2025-04-27T12:31:24.631Z" }, + { url = "https://files.pythonhosted.org/packages/be/27/43a47fa0ff9053ab5203bb3faeec435d43c0d8bfa40179bfd076cdbd4e1c/pyarrow-20.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:97c8dc984ed09cb07d618d57d8d4b67a5100a30c3818c2fb0b04599f0da2de7b", size = 42281473, upload-time = "2025-04-27T12:31:31.311Z" }, + { url = "https://files.pythonhosted.org/packages/bc/0b/d56c63b078876da81bbb9ba695a596eabee9b085555ed12bf6eb3b7cab0e/pyarrow-20.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9b71daf534f4745818f96c214dbc1e6124d7daf059167330b610fc69b6f3d3e3", size = 42893897, upload-time = "2025-04-27T12:31:39.406Z" }, + { url = "https://files.pythonhosted.org/packages/92/ac/7d4bd020ba9145f354012838692d48300c1b8fe5634bfda886abcada67ed/pyarrow-20.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e8b88758f9303fa5a83d6c90e176714b2fd3852e776fc2d7e42a22dd6c2fb368", size = 44543847, upload-time = "2025-04-27T12:31:45.997Z" }, + { url = "https://files.pythonhosted.org/packages/9d/07/290f4abf9ca702c5df7b47739c1b2c83588641ddfa2cc75e34a301d42e55/pyarrow-20.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:30b3051b7975801c1e1d387e17c588d8ab05ced9b1e14eec57915f79869b5031", size = 25653219, upload-time = "2025-04-27T12:31:54.11Z" }, + { url = "https://files.pythonhosted.org/packages/95/df/720bb17704b10bd69dde086e1400b8eefb8f58df3f8ac9cff6c425bf57f1/pyarrow-20.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:ca151afa4f9b7bc45bcc791eb9a89e90a9eb2772767d0b1e5389609c7d03db63", size = 30853957, upload-time = "2025-04-27T12:31:59.215Z" }, + { url = "https://files.pythonhosted.org/packages/d9/72/0d5f875efc31baef742ba55a00a25213a19ea64d7176e0fe001c5d8b6e9a/pyarrow-20.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:4680f01ecd86e0dd63e39eb5cd59ef9ff24a9d166db328679e36c108dc993d4c", size = 32247972, upload-time = "2025-04-27T12:32:05.369Z" }, + { url = "https://files.pythonhosted.org/packages/d5/bc/e48b4fa544d2eea72f7844180eb77f83f2030b84c8dad860f199f94307ed/pyarrow-20.0.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f4c8534e2ff059765647aa69b75d6543f9fef59e2cd4c6d18015192565d2b70", size = 41256434, upload-time = "2025-04-27T12:32:11.814Z" }, + { url = "https://files.pythonhosted.org/packages/c3/01/974043a29874aa2cf4f87fb07fd108828fc7362300265a2a64a94965e35b/pyarrow-20.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e1f8a47f4b4ae4c69c4d702cfbdfe4d41e18e5c7ef6f1bb1c50918c1e81c57b", size = 42353648, upload-time = "2025-04-27T12:32:20.766Z" }, + { url = "https://files.pythonhosted.org/packages/68/95/cc0d3634cde9ca69b0e51cbe830d8915ea32dda2157560dda27ff3b3337b/pyarrow-20.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:a1f60dc14658efaa927f8214734f6a01a806d7690be4b3232ba526836d216122", size = 40619853, upload-time = "2025-04-27T12:32:28.1Z" }, + { url = "https://files.pythonhosted.org/packages/29/c2/3ad40e07e96a3e74e7ed7cc8285aadfa84eb848a798c98ec0ad009eb6bcc/pyarrow-20.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:204a846dca751428991346976b914d6d2a82ae5b8316a6ed99789ebf976551e6", size = 42241743, upload-time = "2025-04-27T12:32:35.792Z" }, + { url = "https://files.pythonhosted.org/packages/eb/cb/65fa110b483339add6a9bc7b6373614166b14e20375d4daa73483755f830/pyarrow-20.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f3b117b922af5e4c6b9a9115825726cac7d8b1421c37c2b5e24fbacc8930612c", size = 42839441, upload-time = "2025-04-27T12:32:46.64Z" }, + { url = "https://files.pythonhosted.org/packages/98/7b/f30b1954589243207d7a0fbc9997401044bf9a033eec78f6cb50da3f304a/pyarrow-20.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e724a3fd23ae5b9c010e7be857f4405ed5e679db5c93e66204db1a69f733936a", size = 44503279, upload-time = "2025-04-27T12:32:56.503Z" }, + { url = "https://files.pythonhosted.org/packages/37/40/ad395740cd641869a13bcf60851296c89624662575621968dcfafabaa7f6/pyarrow-20.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:82f1ee5133bd8f49d31be1299dc07f585136679666b502540db854968576faf9", size = 25944982, upload-time = "2025-04-27T12:33:04.72Z" }, + { url = "https://files.pythonhosted.org/packages/10/53/421820fa125138c868729b930d4bc487af2c4b01b1c6104818aab7e98f13/pyarrow-20.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:1bcbe471ef3349be7714261dea28fe280db574f9d0f77eeccc195a2d161fd861", size = 30844702, upload-time = "2025-04-27T12:33:12.122Z" }, + { url = "https://files.pythonhosted.org/packages/2e/70/fd75e03312b715e90d928fb91ed8d45c9b0520346e5231b1c69293afd4c7/pyarrow-20.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:a18a14baef7d7ae49247e75641fd8bcbb39f44ed49a9fc4ec2f65d5031aa3b96", size = 32287180, upload-time = "2025-04-27T12:33:20.597Z" }, + { url = "https://files.pythonhosted.org/packages/c4/e3/21e5758e46219fdedf5e6c800574dd9d17e962e80014cfe08d6d475be863/pyarrow-20.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb497649e505dc36542d0e68eca1a3c94ecbe9799cb67b578b55f2441a247fbc", size = 41351968, upload-time = "2025-04-27T12:33:28.215Z" }, + { url = "https://files.pythonhosted.org/packages/ac/f5/ed6a4c4b11f9215092a35097a985485bb7d879cb79d93d203494e8604f4e/pyarrow-20.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11529a2283cb1f6271d7c23e4a8f9f8b7fd173f7360776b668e509d712a02eec", size = 42415208, upload-time = "2025-04-27T12:33:37.04Z" }, + { url = "https://files.pythonhosted.org/packages/44/e5/466a63668ba25788ee8d38d55f853a60469ae7ad1cda343db9f3f45e0b0a/pyarrow-20.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fc1499ed3b4b57ee4e090e1cea6eb3584793fe3d1b4297bbf53f09b434991a5", size = 40708556, upload-time = "2025-04-27T12:33:46.483Z" }, + { url = "https://files.pythonhosted.org/packages/e8/d7/4c4d4e4cf6e53e16a519366dfe9223ee4a7a38e6e28c1c0d372b38ba3fe7/pyarrow-20.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:db53390eaf8a4dab4dbd6d93c85c5cf002db24902dbff0ca7d988beb5c9dd15b", size = 42291754, upload-time = "2025-04-27T12:33:55.4Z" }, + { url = "https://files.pythonhosted.org/packages/07/d5/79effb32585b7c18897d3047a2163034f3f9c944d12f7b2fd8df6a2edc70/pyarrow-20.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:851c6a8260ad387caf82d2bbf54759130534723e37083111d4ed481cb253cc0d", size = 42936483, upload-time = "2025-04-27T12:34:03.694Z" }, + { url = "https://files.pythonhosted.org/packages/09/5c/f707603552c058b2e9129732de99a67befb1f13f008cc58856304a62c38b/pyarrow-20.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e22f80b97a271f0a7d9cd07394a7d348f80d3ac63ed7cc38b6d1b696ab3b2619", size = 44558895, upload-time = "2025-04-27T12:34:13.26Z" }, + { url = "https://files.pythonhosted.org/packages/26/cc/1eb6a01c1bbc787f596c270c46bcd2273e35154a84afcb1d0cb4cc72457e/pyarrow-20.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:9965a050048ab02409fb7cbbefeedba04d3d67f2cc899eff505cc084345959ca", size = 25785667, upload-time = "2025-04-27T12:34:19.739Z" }, +] + [[package]] name = "pygments" version = "2.19.1" @@ -206,6 +354,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312, upload-time = "2024-08-06T20:33:49.073Z" }, ] +[[package]] +name = "sqloxide" +version = "0.1.56" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/10/c7/79f57728f300079148ac4e4b988000dcbd1f58960040db89594424a58336/sqloxide-0.1.56.tar.gz", hash = "sha256:2379917f04c85c618abea77af0d48af9bc87b7d527c37170bfe390eac26ad397", size = 15976, upload-time = "2025-05-17T18:09:16.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/a2/6c7e25b9d6d9ef22eb7d40a923b00eb23f88408bcc762ee5cbe53bee9802/sqloxide-0.1.56-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cfb01bd42e12ada0d647873967dbc572029fb9aca207cf5ab963960f2f1b9f03", size = 3002177, upload-time = "2025-05-17T18:08:23.765Z" }, + { url = "https://files.pythonhosted.org/packages/4f/e1/483be52307cec72e3a6cd70e0d45bdcec829edefa693bbb7c9ff72aade29/sqloxide-0.1.56-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89fba7ec9d27b03af6f276043a3ab1706ae77d879bbcfdfca9079482a4e93873", size = 3240565, upload-time = "2025-05-17T18:08:25.756Z" }, + { url = "https://files.pythonhosted.org/packages/59/ce/6d31d249ef723ab069f25d9a6c9f403dfaeec3140e23002e825f3e01fd53/sqloxide-0.1.56-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:655ce500b7c7fd560108139af83c65d8d5ea19fde342bb915ba58ec110612474", size = 3423436, upload-time = "2025-05-17T18:08:26.966Z" }, + { url = "https://files.pythonhosted.org/packages/72/19/86a62bf065bb1a4399e92f8a6a78414aea1edf886f311bfa85fbd974f25e/sqloxide-0.1.56-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:923ceb0dfe0bfb3c155890028100ada14f1d462c7c6b5da8e32b8d016533711b", size = 3734785, upload-time = "2025-05-17T18:08:28.6Z" }, + { url = "https://files.pythonhosted.org/packages/8b/fc/63d80b88e55c3efa040b9d89f749c7798f4be42a705e22556049fdacba86/sqloxide-0.1.56-cp310-cp310-win_amd64.whl", hash = "sha256:a6f032b2a8c0778f3397186de239c633e8cdedbbb808053bf4a06ca7469a0998", size = 3016568, upload-time = "2025-05-17T18:08:29.803Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b8/6cfe46500743d49ab5862ff22ffe3249379d635d9440f0df63d882b20997/sqloxide-0.1.56-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ec7ea3c69d8977bfc104579d17cef1448912f9b7728eb78aaae8f6f2d6412cb6", size = 3002130, upload-time = "2025-05-17T18:08:31.009Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e3/62d93b538906ddc11529e71b2396589816aaf5c55256ecf4b9fcbf5f7f23/sqloxide-0.1.56-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25536ab40fe02cd882a61bf98c52d5fd0126dcdfa1c8a12dfeba1df3b4d7c3c5", size = 3240150, upload-time = "2025-05-17T18:08:32.721Z" }, + { url = "https://files.pythonhosted.org/packages/00/a2/35ee7ce0ace4291029ca4388cfd528933982a46bea1ea95fd3ef04fc2e0a/sqloxide-0.1.56-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11574d3b317d0d1ddd5a4aefe36bdbed7e02a5fdf179e6a34fd047eff80745ce", size = 3423377, upload-time = "2025-05-17T18:08:34.816Z" }, + { url = "https://files.pythonhosted.org/packages/6d/18/d36cf7f10996230e095e98d2dcdc4fb4782bfbb4f5bca42861d8448fb84a/sqloxide-0.1.56-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1be67ed903c875b4a42852cadc5f8ef14e8c2fc09c518cfef86a5f74d43e88ca", size = 3734643, upload-time = "2025-05-17T18:08:36.525Z" }, + { url = "https://files.pythonhosted.org/packages/71/96/b121727508e7a020715ba3ff57e1ce8b7eb9255ed6314e4d4cb0a73811bd/sqloxide-0.1.56-cp311-cp311-win_amd64.whl", hash = "sha256:a7f38559b3f10755d43ed3700680061ddcf706a58d957eb16ec400f7113b02b4", size = 3016657, upload-time = "2025-05-17T18:08:39.115Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5d/ecd7c89a48cfaa43a920cd1475380e331a95364ad5e914ea60daf2038430/sqloxide-0.1.56-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ec5efc92634cc400d64eb84c6c492eefab9d2e8fe4973bbb758d79da23299c36", size = 2992231, upload-time = "2025-05-17T18:08:40.786Z" }, + { url = "https://files.pythonhosted.org/packages/c0/09/3819ba9b9bc33a758b90f7b883e69d5b69141423892fe3c96e9f150fd2ea/sqloxide-0.1.56-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35bd4a5ca3c1e6886ade4962735d2581206144d9d21bdec43bc2897d31f1418f", size = 3229769, upload-time = "2025-05-17T18:08:42.462Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b9/fc4c3f7122fbb9017967839ec013f93be9bc0790d5d103b031892d1a1250/sqloxide-0.1.56-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:305301d43494b7689c271269d9a45dd99b8c006cf769711d46ee1a0851ae9688", size = 3420784, upload-time = "2025-05-17T18:08:44.049Z" }, + { url = "https://files.pythonhosted.org/packages/fb/cf/05ae5906a7fb3f5165a8f2a00ad5974f36d77a33ae34f485d671cd38c010/sqloxide-0.1.56-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f171890e5e067d16619de2ae08f1062ea698d8c4c2a3a5df094ce8881ad3b7a6", size = 3730822, upload-time = "2025-05-17T18:08:45.515Z" }, + { url = "https://files.pythonhosted.org/packages/77/02/1e83b8d224b7c9b6e590609725651953fac64742312c70da909542c2427f/sqloxide-0.1.56-cp312-cp312-win_amd64.whl", hash = "sha256:63c8b66a8bc89bbbba8586a0c9b7969d210224cbb508a3f2531bab6dd0620a9b", size = 3018266, upload-time = "2025-05-17T18:08:46.777Z" }, + { url = "https://files.pythonhosted.org/packages/94/fd/268d58f8feb4d206d2896dae5e8a4a17c671c9cbb6b15c6e6300d2e168a2/sqloxide-0.1.56-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42d51efeb52e72f1d8242e61461733359eaf330dabc7ce533e970972ade1f9ab", size = 2992256, upload-time = "2025-05-17T18:08:48.126Z" }, + { url = "https://files.pythonhosted.org/packages/de/77/dd27f6e325537126ba0b142fdce63bde4305681662ac58e8e779e3c87635/sqloxide-0.1.56-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7730693f46ed313ff6531de8ba0874158d154875d3c6721825aa3122be600d4", size = 3230573, upload-time = "2025-05-17T18:08:49.444Z" }, + { url = "https://files.pythonhosted.org/packages/f9/04/98c216967275cd9a3e517dfeeb513ebff3183f1f22da29180c479c749ac8/sqloxide-0.1.56-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e94f9037d7336bef4e3090b15299c2a405c55aba4ae87ef6d963df2f0b48016", size = 3421350, upload-time = "2025-05-17T18:08:50.758Z" }, + { url = "https://files.pythonhosted.org/packages/c2/2a/402274bf73fedfb986fab94239d8b34f9bfdb1a0a24adec3c43bd28e4387/sqloxide-0.1.56-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33006d8414d8c65b8e7e8313c61dd5c3f5dc1a4f88c7d1b7ae25bc8fa9f26fdc", size = 3730165, upload-time = "2025-05-17T18:08:51.995Z" }, + { url = "https://files.pythonhosted.org/packages/c8/5c/487e081a5ac1a8538f7eb3a3e3ea04c39da13acde1f17916ca1767d40c4e/sqloxide-0.1.56-cp313-cp313-win_amd64.whl", hash = "sha256:08a119f20334285663989fd39f78eaa448ebf023ca451a25adba78321e3a17ae", size = 3018363, upload-time = "2025-05-17T18:08:53.208Z" }, + { url = "https://files.pythonhosted.org/packages/1d/6b/3c72d38aa754028b573ed5267ebb980f63f9be48c116cabb7553a678f8ee/sqloxide-0.1.56-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95264629cc13ec4ed9b155a88fc78fc9002f0ade1030d74dad5c211931fe679c", size = 3002496, upload-time = "2025-05-17T18:09:09.11Z" }, + { url = "https://files.pythonhosted.org/packages/89/45/e79b9140776d5a025aa885889d233d0543719ad8506c0d9aec0b3e04f663/sqloxide-0.1.56-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ef6b83e670c82a2053870624146c9f95b7a448c7e27d57bf7d562f6a80e0277", size = 3240645, upload-time = "2025-05-17T18:09:10.786Z" }, + { url = "https://files.pythonhosted.org/packages/14/78/684e9423a56073a90a1febf6ec77584e0ac50798cbbee4aca738ded0a740/sqloxide-0.1.56-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8b42d65e52814415ab8a70384405af0dded4762c746787ccd039add83023f99", size = 3423725, upload-time = "2025-05-17T18:09:12.019Z" }, + { url = "https://files.pythonhosted.org/packages/40/0c/b6e4141feafcd654c402a8893c38ee7c2efef9604179ed5727b6fd3198d2/sqloxide-0.1.56-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:176f9fbe86326cf9c3510255aa5cffd2a3b3566f282d7a32be543ff832a726bd", size = 3735201, upload-time = "2025-05-17T18:09:13.312Z" }, + { url = "https://files.pythonhosted.org/packages/c5/0e/77951d60ec8cec3cac652564223fdf7623d3e72906d0356035326a2e80cb/sqloxide-0.1.56-cp39-cp39-win_amd64.whl", hash = "sha256:effeae7e15a173790859a8e32314c50f070751125d5f583fb6b474a525839ecd", size = 3016855, upload-time = "2025-05-17T18:09:15.233Z" }, +] + [[package]] name = "substrait" source = { editable = "." } @@ -222,24 +403,38 @@ gen-proto = [ { name = "protobuf" }, { name = "protoletariat" }, ] +sql = [ + { name = "deepdiff" }, + { name = "sqloxide" }, +] test = [ { name = "antlr4-python3-runtime" }, + { name = "datafusion" }, + { name = "deepdiff" }, + { name = "duckdb" }, { name = "pytest" }, { name = "pyyaml" }, + { name = "sqloxide" }, ] [package.metadata] requires-dist = [ { name = "antlr4-python3-runtime", marker = "extra == 'extensions'" }, { name = "antlr4-python3-runtime", marker = "extra == 'test'" }, + { name = "datafusion", marker = "extra == 'test'" }, + { name = "deepdiff", marker = "extra == 'sql'" }, + { name = "deepdiff", marker = "extra == 'test'" }, + { name = "duckdb", marker = "extra == 'test'", specifier = "<=1.2.2" }, { name = "protobuf", specifier = ">=3.20" }, { name = "protobuf", marker = "extra == 'gen-proto'", specifier = "==3.20.1" }, { name = "protoletariat", marker = "extra == 'gen-proto'", specifier = ">=2.0.0" }, { name = "pytest", marker = "extra == 'test'", specifier = ">=7.0.0" }, { name = "pyyaml", marker = "extra == 'extensions'" }, { name = "pyyaml", marker = "extra == 'test'" }, + { name = "sqloxide", marker = "extra == 'sql'" }, + { name = "sqloxide", marker = "extra == 'test'" }, ] -provides-extras = ["extensions", "gen-proto", "test"] +provides-extras = ["extensions", "gen-proto", "sql", "test"] [[package]] name = "tomli"