relationalai 0.13.5__py3-none-any.whl → 1.0.0a1__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.
- relationalai/__init__.py +1 -256
- relationalai/config/__init__.py +56 -0
- relationalai/config/config.py +289 -0
- relationalai/config/config_fields.py +86 -0
- relationalai/config/connections/__init__.py +46 -0
- relationalai/config/connections/base.py +23 -0
- relationalai/config/connections/duckdb.py +29 -0
- relationalai/config/connections/snowflake.py +243 -0
- relationalai/config/external/__init__.py +17 -0
- relationalai/config/external/dbt_converter.py +101 -0
- relationalai/config/external/dbt_models.py +93 -0
- relationalai/config/external/snowflake_converter.py +41 -0
- relationalai/config/external/snowflake_models.py +85 -0
- relationalai/config/external/utils.py +19 -0
- relationalai/config/shims.py +1 -0
- relationalai/semantics/__init__.py +146 -22
- relationalai/semantics/backends/lqp/annotations.py +11 -0
- relationalai/semantics/backends/sql/sql_compiler.py +327 -0
- relationalai/semantics/frontend/base.py +1716 -0
- relationalai/semantics/frontend/core.py +179 -0
- relationalai/semantics/frontend/front_compiler.py +1313 -0
- relationalai/semantics/frontend/pprint.py +408 -0
- relationalai/semantics/metamodel/__init__.py +6 -40
- relationalai/semantics/metamodel/builtins.py +205 -772
- relationalai/semantics/metamodel/metamodel.py +437 -0
- relationalai/semantics/metamodel/metamodel_analyzer.py +519 -0
- relationalai/semantics/metamodel/pprint.py +412 -0
- relationalai/semantics/metamodel/rewriter.py +266 -0
- relationalai/semantics/metamodel/typer.py +1186 -0
- relationalai/semantics/std/__init__.py +60 -40
- relationalai/semantics/std/aggregates.py +149 -0
- relationalai/semantics/std/common.py +44 -0
- relationalai/semantics/std/constraints.py +37 -43
- relationalai/semantics/std/datetime.py +246 -135
- relationalai/semantics/std/decimals.py +45 -52
- relationalai/semantics/std/floats.py +13 -5
- relationalai/semantics/std/integers.py +26 -11
- relationalai/semantics/std/math.py +183 -112
- relationalai/semantics/std/numbers.py +86 -0
- relationalai/semantics/std/re.py +80 -62
- relationalai/semantics/std/strings.py +101 -46
- relationalai/shims/executor.py +161 -0
- relationalai/shims/helpers.py +126 -0
- relationalai/shims/hoister.py +221 -0
- relationalai/shims/mm2v0.py +1324 -0
- relationalai/tools/cli/__init__.py +6 -0
- relationalai/tools/cli/cli.py +90 -0
- relationalai/tools/cli/components/__init__.py +5 -0
- relationalai/tools/cli/components/progress_reader.py +1524 -0
- relationalai/tools/cli/components/utils.py +58 -0
- relationalai/tools/cli/config_template.py +45 -0
- relationalai/tools/cli/dev.py +19 -0
- relationalai/tools/debugger.py +289 -183
- relationalai/tools/typer_debugger.py +93 -0
- relationalai/util/dataclasses.py +43 -0
- relationalai/util/docutils.py +40 -0
- relationalai/util/error.py +199 -0
- relationalai/util/format.py +48 -109
- relationalai/util/naming.py +145 -0
- relationalai/util/python.py +35 -0
- relationalai/util/runtime.py +156 -0
- relationalai/util/schema.py +197 -0
- relationalai/util/source.py +185 -0
- relationalai/util/structures.py +163 -0
- relationalai/util/tracing.py +261 -0
- relationalai-1.0.0a1.dist-info/METADATA +44 -0
- relationalai-1.0.0a1.dist-info/RECORD +489 -0
- relationalai-1.0.0a1.dist-info/WHEEL +5 -0
- relationalai-1.0.0a1.dist-info/entry_points.txt +3 -0
- relationalai-1.0.0a1.dist-info/top_level.txt +2 -0
- v0/relationalai/__init__.py +216 -0
- v0/relationalai/clients/__init__.py +5 -0
- v0/relationalai/clients/azure.py +477 -0
- v0/relationalai/clients/client.py +912 -0
- v0/relationalai/clients/config.py +673 -0
- v0/relationalai/clients/direct_access_client.py +118 -0
- v0/relationalai/clients/hash_util.py +31 -0
- v0/relationalai/clients/local.py +571 -0
- v0/relationalai/clients/profile_polling.py +73 -0
- v0/relationalai/clients/result_helpers.py +420 -0
- v0/relationalai/clients/snowflake.py +3869 -0
- v0/relationalai/clients/types.py +113 -0
- v0/relationalai/clients/use_index_poller.py +980 -0
- v0/relationalai/clients/util.py +356 -0
- v0/relationalai/debugging.py +389 -0
- v0/relationalai/dsl.py +1749 -0
- v0/relationalai/early_access/builder/__init__.py +30 -0
- v0/relationalai/early_access/builder/builder/__init__.py +35 -0
- v0/relationalai/early_access/builder/snowflake/__init__.py +12 -0
- v0/relationalai/early_access/builder/std/__init__.py +25 -0
- v0/relationalai/early_access/builder/std/decimals/__init__.py +12 -0
- v0/relationalai/early_access/builder/std/integers/__init__.py +12 -0
- v0/relationalai/early_access/builder/std/math/__init__.py +12 -0
- v0/relationalai/early_access/builder/std/strings/__init__.py +14 -0
- v0/relationalai/early_access/devtools/__init__.py +12 -0
- v0/relationalai/early_access/devtools/benchmark_lqp/__init__.py +12 -0
- v0/relationalai/early_access/devtools/extract_lqp/__init__.py +12 -0
- v0/relationalai/early_access/dsl/adapters/orm/adapter_qb.py +427 -0
- v0/relationalai/early_access/dsl/adapters/orm/parser.py +636 -0
- v0/relationalai/early_access/dsl/adapters/owl/adapter.py +176 -0
- v0/relationalai/early_access/dsl/adapters/owl/parser.py +160 -0
- v0/relationalai/early_access/dsl/bindings/common.py +402 -0
- v0/relationalai/early_access/dsl/bindings/csv.py +170 -0
- v0/relationalai/early_access/dsl/bindings/legacy/binding_models.py +143 -0
- v0/relationalai/early_access/dsl/bindings/snowflake.py +64 -0
- v0/relationalai/early_access/dsl/codegen/binder.py +411 -0
- v0/relationalai/early_access/dsl/codegen/common.py +79 -0
- v0/relationalai/early_access/dsl/codegen/helpers.py +23 -0
- v0/relationalai/early_access/dsl/codegen/relations.py +700 -0
- v0/relationalai/early_access/dsl/codegen/weaver.py +417 -0
- v0/relationalai/early_access/dsl/core/builders/__init__.py +47 -0
- v0/relationalai/early_access/dsl/core/builders/logic.py +19 -0
- v0/relationalai/early_access/dsl/core/builders/scalar_constraint.py +11 -0
- v0/relationalai/early_access/dsl/core/constraints/predicate/atomic.py +455 -0
- v0/relationalai/early_access/dsl/core/constraints/predicate/universal.py +73 -0
- v0/relationalai/early_access/dsl/core/constraints/scalar.py +310 -0
- v0/relationalai/early_access/dsl/core/context.py +13 -0
- v0/relationalai/early_access/dsl/core/cset.py +132 -0
- v0/relationalai/early_access/dsl/core/exprs/__init__.py +116 -0
- v0/relationalai/early_access/dsl/core/exprs/relational.py +18 -0
- v0/relationalai/early_access/dsl/core/exprs/scalar.py +412 -0
- v0/relationalai/early_access/dsl/core/instances.py +44 -0
- v0/relationalai/early_access/dsl/core/logic/__init__.py +193 -0
- v0/relationalai/early_access/dsl/core/logic/aggregation.py +98 -0
- v0/relationalai/early_access/dsl/core/logic/exists.py +223 -0
- v0/relationalai/early_access/dsl/core/logic/helper.py +163 -0
- v0/relationalai/early_access/dsl/core/namespaces.py +32 -0
- v0/relationalai/early_access/dsl/core/relations.py +276 -0
- v0/relationalai/early_access/dsl/core/rules.py +112 -0
- v0/relationalai/early_access/dsl/core/std/__init__.py +45 -0
- v0/relationalai/early_access/dsl/core/temporal/recall.py +6 -0
- v0/relationalai/early_access/dsl/core/types/__init__.py +270 -0
- v0/relationalai/early_access/dsl/core/types/concepts.py +128 -0
- v0/relationalai/early_access/dsl/core/types/constrained/__init__.py +267 -0
- v0/relationalai/early_access/dsl/core/types/constrained/nominal.py +143 -0
- v0/relationalai/early_access/dsl/core/types/constrained/subtype.py +124 -0
- v0/relationalai/early_access/dsl/core/types/standard.py +92 -0
- v0/relationalai/early_access/dsl/core/types/unconstrained.py +50 -0
- v0/relationalai/early_access/dsl/core/types/variables.py +203 -0
- v0/relationalai/early_access/dsl/ir/compiler.py +318 -0
- v0/relationalai/early_access/dsl/ir/executor.py +260 -0
- v0/relationalai/early_access/dsl/ontologies/constraints.py +88 -0
- v0/relationalai/early_access/dsl/ontologies/export.py +30 -0
- v0/relationalai/early_access/dsl/ontologies/models.py +453 -0
- v0/relationalai/early_access/dsl/ontologies/python_printer.py +303 -0
- v0/relationalai/early_access/dsl/ontologies/readings.py +60 -0
- v0/relationalai/early_access/dsl/ontologies/relationships.py +322 -0
- v0/relationalai/early_access/dsl/ontologies/roles.py +87 -0
- v0/relationalai/early_access/dsl/ontologies/subtyping.py +55 -0
- v0/relationalai/early_access/dsl/orm/constraints.py +438 -0
- v0/relationalai/early_access/dsl/orm/measures/dimensions.py +200 -0
- v0/relationalai/early_access/dsl/orm/measures/initializer.py +16 -0
- v0/relationalai/early_access/dsl/orm/measures/measure_rules.py +275 -0
- v0/relationalai/early_access/dsl/orm/measures/measures.py +299 -0
- v0/relationalai/early_access/dsl/orm/measures/role_exprs.py +268 -0
- v0/relationalai/early_access/dsl/orm/models.py +256 -0
- v0/relationalai/early_access/dsl/orm/object_oriented_printer.py +344 -0
- v0/relationalai/early_access/dsl/orm/printer.py +469 -0
- v0/relationalai/early_access/dsl/orm/reasoners.py +480 -0
- v0/relationalai/early_access/dsl/orm/relations.py +19 -0
- v0/relationalai/early_access/dsl/orm/relationships.py +251 -0
- v0/relationalai/early_access/dsl/orm/types.py +42 -0
- v0/relationalai/early_access/dsl/orm/utils.py +79 -0
- v0/relationalai/early_access/dsl/orm/verb.py +204 -0
- v0/relationalai/early_access/dsl/physical_metadata/tables.py +133 -0
- v0/relationalai/early_access/dsl/relations.py +170 -0
- v0/relationalai/early_access/dsl/rulesets.py +69 -0
- v0/relationalai/early_access/dsl/schemas/__init__.py +450 -0
- v0/relationalai/early_access/dsl/schemas/builder.py +48 -0
- v0/relationalai/early_access/dsl/schemas/comp_names.py +51 -0
- v0/relationalai/early_access/dsl/schemas/components.py +203 -0
- v0/relationalai/early_access/dsl/schemas/contexts.py +156 -0
- v0/relationalai/early_access/dsl/schemas/exprs.py +89 -0
- v0/relationalai/early_access/dsl/schemas/fragments.py +464 -0
- v0/relationalai/early_access/dsl/serialization.py +79 -0
- v0/relationalai/early_access/dsl/serialize/exporter.py +163 -0
- v0/relationalai/early_access/dsl/snow/api.py +104 -0
- v0/relationalai/early_access/dsl/snow/common.py +76 -0
- v0/relationalai/early_access/dsl/state_mgmt/__init__.py +129 -0
- v0/relationalai/early_access/dsl/state_mgmt/state_charts.py +125 -0
- v0/relationalai/early_access/dsl/state_mgmt/transitions.py +130 -0
- v0/relationalai/early_access/dsl/types/__init__.py +40 -0
- v0/relationalai/early_access/dsl/types/concepts.py +12 -0
- v0/relationalai/early_access/dsl/types/entities.py +135 -0
- v0/relationalai/early_access/dsl/types/values.py +17 -0
- v0/relationalai/early_access/dsl/utils.py +102 -0
- v0/relationalai/early_access/graphs/__init__.py +13 -0
- v0/relationalai/early_access/lqp/__init__.py +12 -0
- v0/relationalai/early_access/lqp/compiler/__init__.py +12 -0
- v0/relationalai/early_access/lqp/constructors/__init__.py +18 -0
- v0/relationalai/early_access/lqp/executor/__init__.py +12 -0
- v0/relationalai/early_access/lqp/ir/__init__.py +12 -0
- v0/relationalai/early_access/lqp/passes/__init__.py +12 -0
- v0/relationalai/early_access/lqp/pragmas/__init__.py +12 -0
- v0/relationalai/early_access/lqp/primitives/__init__.py +12 -0
- v0/relationalai/early_access/lqp/types/__init__.py +12 -0
- v0/relationalai/early_access/lqp/utils/__init__.py +12 -0
- v0/relationalai/early_access/lqp/validators/__init__.py +12 -0
- v0/relationalai/early_access/metamodel/__init__.py +58 -0
- v0/relationalai/early_access/metamodel/builtins/__init__.py +12 -0
- v0/relationalai/early_access/metamodel/compiler/__init__.py +12 -0
- v0/relationalai/early_access/metamodel/dependency/__init__.py +12 -0
- v0/relationalai/early_access/metamodel/factory/__init__.py +17 -0
- v0/relationalai/early_access/metamodel/helpers/__init__.py +12 -0
- v0/relationalai/early_access/metamodel/ir/__init__.py +14 -0
- v0/relationalai/early_access/metamodel/rewrite/__init__.py +7 -0
- v0/relationalai/early_access/metamodel/typer/__init__.py +3 -0
- v0/relationalai/early_access/metamodel/typer/typer/__init__.py +12 -0
- v0/relationalai/early_access/metamodel/types/__init__.py +15 -0
- v0/relationalai/early_access/metamodel/util/__init__.py +15 -0
- v0/relationalai/early_access/metamodel/visitor/__init__.py +12 -0
- v0/relationalai/early_access/rel/__init__.py +12 -0
- v0/relationalai/early_access/rel/executor/__init__.py +12 -0
- v0/relationalai/early_access/rel/rel_utils/__init__.py +12 -0
- v0/relationalai/early_access/rel/rewrite/__init__.py +7 -0
- v0/relationalai/early_access/solvers/__init__.py +19 -0
- v0/relationalai/early_access/sql/__init__.py +11 -0
- v0/relationalai/early_access/sql/executor/__init__.py +3 -0
- v0/relationalai/early_access/sql/rewrite/__init__.py +3 -0
- v0/relationalai/early_access/tests/logging/__init__.py +12 -0
- v0/relationalai/early_access/tests/test_snapshot_base/__init__.py +12 -0
- v0/relationalai/early_access/tests/utils/__init__.py +12 -0
- v0/relationalai/environments/__init__.py +35 -0
- v0/relationalai/environments/base.py +381 -0
- v0/relationalai/environments/colab.py +14 -0
- v0/relationalai/environments/generic.py +71 -0
- v0/relationalai/environments/ipython.py +68 -0
- v0/relationalai/environments/jupyter.py +9 -0
- v0/relationalai/environments/snowbook.py +169 -0
- v0/relationalai/errors.py +2455 -0
- v0/relationalai/experimental/SF.py +38 -0
- v0/relationalai/experimental/inspect.py +47 -0
- v0/relationalai/experimental/pathfinder/__init__.py +158 -0
- v0/relationalai/experimental/pathfinder/api.py +160 -0
- v0/relationalai/experimental/pathfinder/automaton.py +584 -0
- v0/relationalai/experimental/pathfinder/bridge.py +226 -0
- v0/relationalai/experimental/pathfinder/compiler.py +416 -0
- v0/relationalai/experimental/pathfinder/datalog.py +214 -0
- v0/relationalai/experimental/pathfinder/diagnostics.py +56 -0
- v0/relationalai/experimental/pathfinder/filter.py +236 -0
- v0/relationalai/experimental/pathfinder/glushkov.py +439 -0
- v0/relationalai/experimental/pathfinder/options.py +265 -0
- v0/relationalai/experimental/pathfinder/rpq.py +344 -0
- v0/relationalai/experimental/pathfinder/transition.py +200 -0
- v0/relationalai/experimental/pathfinder/utils.py +26 -0
- v0/relationalai/experimental/paths/api.py +143 -0
- v0/relationalai/experimental/paths/benchmarks/grid_graph.py +37 -0
- v0/relationalai/experimental/paths/examples/basic_example.py +40 -0
- v0/relationalai/experimental/paths/examples/minimal_engine_warmup.py +3 -0
- v0/relationalai/experimental/paths/examples/movie_example.py +77 -0
- v0/relationalai/experimental/paths/examples/paths_benchmark.py +115 -0
- v0/relationalai/experimental/paths/examples/paths_example.py +116 -0
- v0/relationalai/experimental/paths/examples/pattern_to_automaton.py +28 -0
- v0/relationalai/experimental/paths/find_paths_via_automaton.py +85 -0
- v0/relationalai/experimental/paths/graph.py +185 -0
- v0/relationalai/experimental/paths/path_algorithms/find_paths.py +280 -0
- v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +26 -0
- v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +111 -0
- v0/relationalai/experimental/paths/path_algorithms/single.py +59 -0
- v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +39 -0
- v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +103 -0
- v0/relationalai/experimental/paths/path_algorithms/usp-old.py +130 -0
- v0/relationalai/experimental/paths/path_algorithms/usp-tuple.py +183 -0
- v0/relationalai/experimental/paths/path_algorithms/usp.py +150 -0
- v0/relationalai/experimental/paths/product_graph.py +93 -0
- v0/relationalai/experimental/paths/rpq/automaton.py +584 -0
- v0/relationalai/experimental/paths/rpq/diagnostics.py +56 -0
- v0/relationalai/experimental/paths/rpq/rpq.py +378 -0
- v0/relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +90 -0
- v0/relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +119 -0
- v0/relationalai/experimental/paths/tests/tests_limit_sp_single.py +104 -0
- v0/relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +113 -0
- v0/relationalai/experimental/paths/tests/tests_limit_walks_single.py +149 -0
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +70 -0
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +64 -0
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +115 -0
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +75 -0
- v0/relationalai/experimental/paths/tests/tests_single_paths.py +152 -0
- v0/relationalai/experimental/paths/tests/tests_single_walks.py +208 -0
- v0/relationalai/experimental/paths/tests/tests_single_walks_undirected.py +297 -0
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +107 -0
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +76 -0
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +76 -0
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +110 -0
- v0/relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +229 -0
- v0/relationalai/experimental/paths/tests/tests_usp_nsp_single.py +108 -0
- v0/relationalai/experimental/paths/tree_agg.py +168 -0
- v0/relationalai/experimental/paths/utilities/iterators.py +27 -0
- v0/relationalai/experimental/paths/utilities/prefix_sum.py +91 -0
- v0/relationalai/experimental/solvers.py +1087 -0
- v0/relationalai/loaders/csv.py +195 -0
- v0/relationalai/loaders/loader.py +177 -0
- v0/relationalai/loaders/types.py +23 -0
- v0/relationalai/rel_emitter.py +373 -0
- v0/relationalai/rel_utils.py +185 -0
- v0/relationalai/semantics/__init__.py +29 -0
- v0/relationalai/semantics/devtools/benchmark_lqp.py +536 -0
- v0/relationalai/semantics/devtools/compilation_manager.py +294 -0
- v0/relationalai/semantics/devtools/extract_lqp.py +110 -0
- v0/relationalai/semantics/internal/internal.py +3785 -0
- v0/relationalai/semantics/internal/snowflake.py +324 -0
- v0/relationalai/semantics/lqp/builtins.py +16 -0
- v0/relationalai/semantics/lqp/compiler.py +22 -0
- v0/relationalai/semantics/lqp/constructors.py +68 -0
- v0/relationalai/semantics/lqp/executor.py +469 -0
- v0/relationalai/semantics/lqp/intrinsics.py +24 -0
- v0/relationalai/semantics/lqp/ir.py +124 -0
- v0/relationalai/semantics/lqp/model2lqp.py +839 -0
- v0/relationalai/semantics/lqp/passes.py +680 -0
- v0/relationalai/semantics/lqp/primitives.py +252 -0
- v0/relationalai/semantics/lqp/result_helpers.py +202 -0
- v0/relationalai/semantics/lqp/rewrite/__init__.py +18 -0
- v0/relationalai/semantics/lqp/rewrite/annotate_constraints.py +57 -0
- v0/relationalai/semantics/lqp/rewrite/cdc.py +216 -0
- v0/relationalai/semantics/lqp/rewrite/extract_common.py +338 -0
- v0/relationalai/semantics/lqp/rewrite/extract_keys.py +449 -0
- v0/relationalai/semantics/lqp/rewrite/function_annotations.py +114 -0
- v0/relationalai/semantics/lqp/rewrite/functional_dependencies.py +314 -0
- v0/relationalai/semantics/lqp/rewrite/quantify_vars.py +296 -0
- v0/relationalai/semantics/lqp/rewrite/splinter.py +76 -0
- v0/relationalai/semantics/lqp/types.py +101 -0
- v0/relationalai/semantics/lqp/utils.py +160 -0
- v0/relationalai/semantics/lqp/validators.py +57 -0
- v0/relationalai/semantics/metamodel/__init__.py +40 -0
- v0/relationalai/semantics/metamodel/builtins.py +774 -0
- v0/relationalai/semantics/metamodel/compiler.py +133 -0
- v0/relationalai/semantics/metamodel/dependency.py +862 -0
- v0/relationalai/semantics/metamodel/executor.py +61 -0
- v0/relationalai/semantics/metamodel/factory.py +287 -0
- v0/relationalai/semantics/metamodel/helpers.py +361 -0
- v0/relationalai/semantics/metamodel/ir.py +923 -0
- v0/relationalai/semantics/metamodel/rewrite/__init__.py +7 -0
- v0/relationalai/semantics/metamodel/rewrite/discharge_constraints.py +39 -0
- v0/relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +210 -0
- v0/relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +78 -0
- v0/relationalai/semantics/metamodel/rewrite/flatten.py +549 -0
- v0/relationalai/semantics/metamodel/rewrite/format_outputs.py +165 -0
- v0/relationalai/semantics/metamodel/typer/checker.py +353 -0
- v0/relationalai/semantics/metamodel/typer/typer.py +1395 -0
- v0/relationalai/semantics/metamodel/util.py +505 -0
- v0/relationalai/semantics/metamodel/visitor.py +944 -0
- v0/relationalai/semantics/reasoners/__init__.py +10 -0
- v0/relationalai/semantics/reasoners/graph/__init__.py +37 -0
- v0/relationalai/semantics/reasoners/graph/core.py +9020 -0
- v0/relationalai/semantics/reasoners/optimization/__init__.py +68 -0
- v0/relationalai/semantics/reasoners/optimization/common.py +88 -0
- v0/relationalai/semantics/reasoners/optimization/solvers_dev.py +568 -0
- v0/relationalai/semantics/reasoners/optimization/solvers_pb.py +1163 -0
- v0/relationalai/semantics/rel/builtins.py +40 -0
- v0/relationalai/semantics/rel/compiler.py +989 -0
- v0/relationalai/semantics/rel/executor.py +359 -0
- v0/relationalai/semantics/rel/rel.py +482 -0
- v0/relationalai/semantics/rel/rel_utils.py +276 -0
- v0/relationalai/semantics/snowflake/__init__.py +3 -0
- v0/relationalai/semantics/sql/compiler.py +2503 -0
- v0/relationalai/semantics/sql/executor/duck_db.py +52 -0
- v0/relationalai/semantics/sql/executor/result_helpers.py +64 -0
- v0/relationalai/semantics/sql/executor/snowflake.py +145 -0
- v0/relationalai/semantics/sql/rewrite/denormalize.py +222 -0
- v0/relationalai/semantics/sql/rewrite/double_negation.py +49 -0
- v0/relationalai/semantics/sql/rewrite/recursive_union.py +127 -0
- v0/relationalai/semantics/sql/rewrite/sort_output_query.py +246 -0
- v0/relationalai/semantics/sql/sql.py +504 -0
- v0/relationalai/semantics/std/__init__.py +54 -0
- v0/relationalai/semantics/std/constraints.py +43 -0
- v0/relationalai/semantics/std/datetime.py +363 -0
- v0/relationalai/semantics/std/decimals.py +62 -0
- v0/relationalai/semantics/std/floats.py +7 -0
- v0/relationalai/semantics/std/integers.py +22 -0
- v0/relationalai/semantics/std/math.py +141 -0
- v0/relationalai/semantics/std/pragmas.py +11 -0
- v0/relationalai/semantics/std/re.py +83 -0
- v0/relationalai/semantics/std/std.py +14 -0
- v0/relationalai/semantics/std/strings.py +63 -0
- v0/relationalai/semantics/tests/__init__.py +0 -0
- v0/relationalai/semantics/tests/test_snapshot_abstract.py +143 -0
- v0/relationalai/semantics/tests/test_snapshot_base.py +9 -0
- v0/relationalai/semantics/tests/utils.py +46 -0
- v0/relationalai/std/__init__.py +70 -0
- v0/relationalai/tools/__init__.py +0 -0
- v0/relationalai/tools/cli.py +1940 -0
- v0/relationalai/tools/cli_controls.py +1826 -0
- v0/relationalai/tools/cli_helpers.py +390 -0
- v0/relationalai/tools/debugger.py +183 -0
- v0/relationalai/tools/debugger_client.py +109 -0
- v0/relationalai/tools/debugger_server.py +302 -0
- v0/relationalai/tools/dev.py +685 -0
- v0/relationalai/tools/qb_debugger.py +425 -0
- v0/relationalai/util/clean_up_databases.py +95 -0
- v0/relationalai/util/format.py +123 -0
- v0/relationalai/util/list_databases.py +9 -0
- v0/relationalai/util/otel_configuration.py +25 -0
- v0/relationalai/util/otel_handler.py +484 -0
- v0/relationalai/util/snowflake_handler.py +88 -0
- v0/relationalai/util/span_format_test.py +43 -0
- v0/relationalai/util/span_tracker.py +207 -0
- v0/relationalai/util/spans_file_handler.py +72 -0
- v0/relationalai/util/tracing_handler.py +34 -0
- frontend/debugger/dist/.gitignore +0 -2
- frontend/debugger/dist/assets/favicon-Dy0ZgA6N.png +0 -0
- frontend/debugger/dist/assets/index-Cssla-O7.js +0 -208
- frontend/debugger/dist/assets/index-DlHsYx1V.css +0 -9
- frontend/debugger/dist/index.html +0 -17
- relationalai/clients/__init__.py +0 -18
- relationalai/clients/client.py +0 -946
- relationalai/clients/config.py +0 -673
- relationalai/clients/direct_access_client.py +0 -118
- relationalai/clients/exec_txn_poller.py +0 -153
- relationalai/clients/hash_util.py +0 -31
- relationalai/clients/local.py +0 -594
- relationalai/clients/profile_polling.py +0 -73
- relationalai/clients/resources/__init__.py +0 -8
- relationalai/clients/resources/azure/azure.py +0 -502
- relationalai/clients/resources/snowflake/__init__.py +0 -20
- relationalai/clients/resources/snowflake/cli_resources.py +0 -98
- relationalai/clients/resources/snowflake/direct_access_resources.py +0 -739
- relationalai/clients/resources/snowflake/engine_service.py +0 -381
- relationalai/clients/resources/snowflake/engine_state_handlers.py +0 -315
- relationalai/clients/resources/snowflake/error_handlers.py +0 -240
- relationalai/clients/resources/snowflake/export_procedure.py.jinja +0 -249
- relationalai/clients/resources/snowflake/resources_factory.py +0 -99
- relationalai/clients/resources/snowflake/snowflake.py +0 -3193
- relationalai/clients/resources/snowflake/use_index_poller.py +0 -1019
- relationalai/clients/resources/snowflake/use_index_resources.py +0 -188
- relationalai/clients/resources/snowflake/util.py +0 -387
- relationalai/clients/result_helpers.py +0 -420
- relationalai/clients/types.py +0 -118
- relationalai/clients/util.py +0 -356
- relationalai/debugging.py +0 -389
- relationalai/dsl.py +0 -1749
- relationalai/early_access/builder/__init__.py +0 -30
- relationalai/early_access/builder/builder/__init__.py +0 -35
- relationalai/early_access/builder/snowflake/__init__.py +0 -12
- relationalai/early_access/builder/std/__init__.py +0 -25
- relationalai/early_access/builder/std/decimals/__init__.py +0 -12
- relationalai/early_access/builder/std/integers/__init__.py +0 -12
- relationalai/early_access/builder/std/math/__init__.py +0 -12
- relationalai/early_access/builder/std/strings/__init__.py +0 -14
- relationalai/early_access/devtools/__init__.py +0 -12
- relationalai/early_access/devtools/benchmark_lqp/__init__.py +0 -12
- relationalai/early_access/devtools/extract_lqp/__init__.py +0 -12
- relationalai/early_access/dsl/adapters/orm/adapter_qb.py +0 -427
- relationalai/early_access/dsl/adapters/orm/parser.py +0 -636
- relationalai/early_access/dsl/adapters/owl/adapter.py +0 -176
- relationalai/early_access/dsl/adapters/owl/parser.py +0 -160
- relationalai/early_access/dsl/bindings/common.py +0 -402
- relationalai/early_access/dsl/bindings/csv.py +0 -170
- relationalai/early_access/dsl/bindings/legacy/binding_models.py +0 -143
- relationalai/early_access/dsl/bindings/snowflake.py +0 -64
- relationalai/early_access/dsl/codegen/binder.py +0 -411
- relationalai/early_access/dsl/codegen/common.py +0 -79
- relationalai/early_access/dsl/codegen/helpers.py +0 -23
- relationalai/early_access/dsl/codegen/relations.py +0 -700
- relationalai/early_access/dsl/codegen/weaver.py +0 -417
- relationalai/early_access/dsl/core/builders/__init__.py +0 -47
- relationalai/early_access/dsl/core/builders/logic.py +0 -19
- relationalai/early_access/dsl/core/builders/scalar_constraint.py +0 -11
- relationalai/early_access/dsl/core/constraints/predicate/atomic.py +0 -455
- relationalai/early_access/dsl/core/constraints/predicate/universal.py +0 -73
- relationalai/early_access/dsl/core/constraints/scalar.py +0 -310
- relationalai/early_access/dsl/core/context.py +0 -13
- relationalai/early_access/dsl/core/cset.py +0 -132
- relationalai/early_access/dsl/core/exprs/__init__.py +0 -116
- relationalai/early_access/dsl/core/exprs/relational.py +0 -18
- relationalai/early_access/dsl/core/exprs/scalar.py +0 -412
- relationalai/early_access/dsl/core/instances.py +0 -44
- relationalai/early_access/dsl/core/logic/__init__.py +0 -193
- relationalai/early_access/dsl/core/logic/aggregation.py +0 -98
- relationalai/early_access/dsl/core/logic/exists.py +0 -223
- relationalai/early_access/dsl/core/logic/helper.py +0 -163
- relationalai/early_access/dsl/core/namespaces.py +0 -32
- relationalai/early_access/dsl/core/relations.py +0 -276
- relationalai/early_access/dsl/core/rules.py +0 -112
- relationalai/early_access/dsl/core/std/__init__.py +0 -45
- relationalai/early_access/dsl/core/temporal/recall.py +0 -6
- relationalai/early_access/dsl/core/types/__init__.py +0 -270
- relationalai/early_access/dsl/core/types/concepts.py +0 -128
- relationalai/early_access/dsl/core/types/constrained/__init__.py +0 -267
- relationalai/early_access/dsl/core/types/constrained/nominal.py +0 -143
- relationalai/early_access/dsl/core/types/constrained/subtype.py +0 -124
- relationalai/early_access/dsl/core/types/standard.py +0 -92
- relationalai/early_access/dsl/core/types/unconstrained.py +0 -50
- relationalai/early_access/dsl/core/types/variables.py +0 -203
- relationalai/early_access/dsl/ir/compiler.py +0 -318
- relationalai/early_access/dsl/ir/executor.py +0 -260
- relationalai/early_access/dsl/ontologies/constraints.py +0 -88
- relationalai/early_access/dsl/ontologies/export.py +0 -30
- relationalai/early_access/dsl/ontologies/models.py +0 -453
- relationalai/early_access/dsl/ontologies/python_printer.py +0 -303
- relationalai/early_access/dsl/ontologies/readings.py +0 -60
- relationalai/early_access/dsl/ontologies/relationships.py +0 -322
- relationalai/early_access/dsl/ontologies/roles.py +0 -87
- relationalai/early_access/dsl/ontologies/subtyping.py +0 -55
- relationalai/early_access/dsl/orm/constraints.py +0 -438
- relationalai/early_access/dsl/orm/measures/dimensions.py +0 -200
- relationalai/early_access/dsl/orm/measures/initializer.py +0 -16
- relationalai/early_access/dsl/orm/measures/measure_rules.py +0 -275
- relationalai/early_access/dsl/orm/measures/measures.py +0 -299
- relationalai/early_access/dsl/orm/measures/role_exprs.py +0 -268
- relationalai/early_access/dsl/orm/models.py +0 -256
- relationalai/early_access/dsl/orm/object_oriented_printer.py +0 -344
- relationalai/early_access/dsl/orm/printer.py +0 -469
- relationalai/early_access/dsl/orm/reasoners.py +0 -480
- relationalai/early_access/dsl/orm/relations.py +0 -19
- relationalai/early_access/dsl/orm/relationships.py +0 -251
- relationalai/early_access/dsl/orm/types.py +0 -42
- relationalai/early_access/dsl/orm/utils.py +0 -79
- relationalai/early_access/dsl/orm/verb.py +0 -204
- relationalai/early_access/dsl/physical_metadata/tables.py +0 -133
- relationalai/early_access/dsl/relations.py +0 -170
- relationalai/early_access/dsl/rulesets.py +0 -69
- relationalai/early_access/dsl/schemas/__init__.py +0 -450
- relationalai/early_access/dsl/schemas/builder.py +0 -48
- relationalai/early_access/dsl/schemas/comp_names.py +0 -51
- relationalai/early_access/dsl/schemas/components.py +0 -203
- relationalai/early_access/dsl/schemas/contexts.py +0 -156
- relationalai/early_access/dsl/schemas/exprs.py +0 -89
- relationalai/early_access/dsl/schemas/fragments.py +0 -464
- relationalai/early_access/dsl/serialization.py +0 -79
- relationalai/early_access/dsl/serialize/exporter.py +0 -163
- relationalai/early_access/dsl/snow/api.py +0 -105
- relationalai/early_access/dsl/snow/common.py +0 -76
- relationalai/early_access/dsl/state_mgmt/__init__.py +0 -129
- relationalai/early_access/dsl/state_mgmt/state_charts.py +0 -125
- relationalai/early_access/dsl/state_mgmt/transitions.py +0 -130
- relationalai/early_access/dsl/types/__init__.py +0 -40
- relationalai/early_access/dsl/types/concepts.py +0 -12
- relationalai/early_access/dsl/types/entities.py +0 -135
- relationalai/early_access/dsl/types/values.py +0 -17
- relationalai/early_access/dsl/utils.py +0 -102
- relationalai/early_access/graphs/__init__.py +0 -13
- relationalai/early_access/lqp/__init__.py +0 -12
- relationalai/early_access/lqp/compiler/__init__.py +0 -12
- relationalai/early_access/lqp/constructors/__init__.py +0 -18
- relationalai/early_access/lqp/executor/__init__.py +0 -12
- relationalai/early_access/lqp/ir/__init__.py +0 -12
- relationalai/early_access/lqp/passes/__init__.py +0 -12
- relationalai/early_access/lqp/pragmas/__init__.py +0 -12
- relationalai/early_access/lqp/primitives/__init__.py +0 -12
- relationalai/early_access/lqp/types/__init__.py +0 -12
- relationalai/early_access/lqp/utils/__init__.py +0 -12
- relationalai/early_access/lqp/validators/__init__.py +0 -12
- relationalai/early_access/metamodel/__init__.py +0 -58
- relationalai/early_access/metamodel/builtins/__init__.py +0 -12
- relationalai/early_access/metamodel/compiler/__init__.py +0 -12
- relationalai/early_access/metamodel/dependency/__init__.py +0 -12
- relationalai/early_access/metamodel/factory/__init__.py +0 -17
- relationalai/early_access/metamodel/helpers/__init__.py +0 -12
- relationalai/early_access/metamodel/ir/__init__.py +0 -14
- relationalai/early_access/metamodel/rewrite/__init__.py +0 -7
- relationalai/early_access/metamodel/typer/__init__.py +0 -3
- relationalai/early_access/metamodel/typer/typer/__init__.py +0 -12
- relationalai/early_access/metamodel/types/__init__.py +0 -15
- relationalai/early_access/metamodel/util/__init__.py +0 -15
- relationalai/early_access/metamodel/visitor/__init__.py +0 -12
- relationalai/early_access/rel/__init__.py +0 -12
- relationalai/early_access/rel/executor/__init__.py +0 -12
- relationalai/early_access/rel/rel_utils/__init__.py +0 -12
- relationalai/early_access/rel/rewrite/__init__.py +0 -7
- relationalai/early_access/solvers/__init__.py +0 -19
- relationalai/early_access/sql/__init__.py +0 -11
- relationalai/early_access/sql/executor/__init__.py +0 -3
- relationalai/early_access/sql/rewrite/__init__.py +0 -3
- relationalai/early_access/tests/logging/__init__.py +0 -12
- relationalai/early_access/tests/test_snapshot_base/__init__.py +0 -12
- relationalai/early_access/tests/utils/__init__.py +0 -12
- relationalai/environments/__init__.py +0 -35
- relationalai/environments/base.py +0 -381
- relationalai/environments/colab.py +0 -14
- relationalai/environments/generic.py +0 -71
- relationalai/environments/ipython.py +0 -68
- relationalai/environments/jupyter.py +0 -9
- relationalai/environments/snowbook.py +0 -169
- relationalai/errors.py +0 -2496
- relationalai/experimental/SF.py +0 -38
- relationalai/experimental/inspect.py +0 -47
- relationalai/experimental/pathfinder/__init__.py +0 -158
- relationalai/experimental/pathfinder/api.py +0 -160
- relationalai/experimental/pathfinder/automaton.py +0 -584
- relationalai/experimental/pathfinder/bridge.py +0 -226
- relationalai/experimental/pathfinder/compiler.py +0 -416
- relationalai/experimental/pathfinder/datalog.py +0 -214
- relationalai/experimental/pathfinder/diagnostics.py +0 -56
- relationalai/experimental/pathfinder/filter.py +0 -236
- relationalai/experimental/pathfinder/glushkov.py +0 -439
- relationalai/experimental/pathfinder/options.py +0 -265
- relationalai/experimental/pathfinder/pathfinder-v0.7.0.rel +0 -1951
- relationalai/experimental/pathfinder/rpq.py +0 -344
- relationalai/experimental/pathfinder/transition.py +0 -200
- relationalai/experimental/pathfinder/utils.py +0 -26
- relationalai/experimental/paths/README.md +0 -107
- relationalai/experimental/paths/api.py +0 -143
- relationalai/experimental/paths/benchmarks/grid_graph.py +0 -37
- relationalai/experimental/paths/code_organization.md +0 -2
- relationalai/experimental/paths/examples/Movies.ipynb +0 -16328
- relationalai/experimental/paths/examples/basic_example.py +0 -40
- relationalai/experimental/paths/examples/minimal_engine_warmup.py +0 -3
- relationalai/experimental/paths/examples/movie_example.py +0 -77
- relationalai/experimental/paths/examples/movies_data/actedin.csv +0 -193
- relationalai/experimental/paths/examples/movies_data/directed.csv +0 -45
- relationalai/experimental/paths/examples/movies_data/follows.csv +0 -7
- relationalai/experimental/paths/examples/movies_data/movies.csv +0 -39
- relationalai/experimental/paths/examples/movies_data/person.csv +0 -134
- relationalai/experimental/paths/examples/movies_data/produced.csv +0 -16
- relationalai/experimental/paths/examples/movies_data/ratings.csv +0 -10
- relationalai/experimental/paths/examples/movies_data/wrote.csv +0 -11
- relationalai/experimental/paths/examples/paths_benchmark.py +0 -115
- relationalai/experimental/paths/examples/paths_example.py +0 -116
- relationalai/experimental/paths/examples/pattern_to_automaton.py +0 -28
- relationalai/experimental/paths/find_paths_via_automaton.py +0 -85
- relationalai/experimental/paths/graph.py +0 -185
- relationalai/experimental/paths/path_algorithms/find_paths.py +0 -280
- relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +0 -26
- relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +0 -111
- relationalai/experimental/paths/path_algorithms/single.py +0 -59
- relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +0 -39
- relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +0 -103
- relationalai/experimental/paths/path_algorithms/usp-old.py +0 -130
- relationalai/experimental/paths/path_algorithms/usp-tuple.py +0 -183
- relationalai/experimental/paths/path_algorithms/usp.py +0 -150
- relationalai/experimental/paths/product_graph.py +0 -93
- relationalai/experimental/paths/rpq/automaton.py +0 -584
- relationalai/experimental/paths/rpq/diagnostics.py +0 -56
- relationalai/experimental/paths/rpq/rpq.py +0 -378
- relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +0 -90
- relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +0 -119
- relationalai/experimental/paths/tests/tests_limit_sp_single.py +0 -104
- relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +0 -113
- relationalai/experimental/paths/tests/tests_limit_walks_single.py +0 -149
- relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +0 -70
- relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +0 -64
- relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +0 -115
- relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +0 -75
- relationalai/experimental/paths/tests/tests_single_paths.py +0 -152
- relationalai/experimental/paths/tests/tests_single_walks.py +0 -208
- relationalai/experimental/paths/tests/tests_single_walks_undirected.py +0 -297
- relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +0 -107
- relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +0 -76
- relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +0 -76
- relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +0 -110
- relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +0 -229
- relationalai/experimental/paths/tests/tests_usp_nsp_single.py +0 -108
- relationalai/experimental/paths/tree_agg.py +0 -168
- relationalai/experimental/paths/utilities/iterators.py +0 -27
- relationalai/experimental/paths/utilities/prefix_sum.py +0 -91
- relationalai/experimental/solvers.py +0 -1095
- relationalai/loaders/csv.py +0 -195
- relationalai/loaders/loader.py +0 -177
- relationalai/loaders/types.py +0 -23
- relationalai/rel_emitter.py +0 -373
- relationalai/rel_utils.py +0 -185
- relationalai/semantics/designs/query_builder/identify_by.md +0 -106
- relationalai/semantics/devtools/benchmark_lqp.py +0 -535
- relationalai/semantics/devtools/compilation_manager.py +0 -294
- relationalai/semantics/devtools/extract_lqp.py +0 -110
- relationalai/semantics/internal/internal.py +0 -3785
- relationalai/semantics/internal/snowflake.py +0 -329
- relationalai/semantics/lqp/README.md +0 -34
- relationalai/semantics/lqp/algorithms.py +0 -173
- relationalai/semantics/lqp/builtins.py +0 -213
- relationalai/semantics/lqp/compiler.py +0 -22
- relationalai/semantics/lqp/constructors.py +0 -68
- relationalai/semantics/lqp/executor.py +0 -518
- relationalai/semantics/lqp/export_rewriter.py +0 -40
- relationalai/semantics/lqp/intrinsics.py +0 -24
- relationalai/semantics/lqp/ir.py +0 -150
- relationalai/semantics/lqp/model2lqp.py +0 -1056
- relationalai/semantics/lqp/passes.py +0 -38
- relationalai/semantics/lqp/primitives.py +0 -252
- relationalai/semantics/lqp/result_helpers.py +0 -266
- relationalai/semantics/lqp/rewrite/__init__.py +0 -32
- relationalai/semantics/lqp/rewrite/algorithm.py +0 -385
- relationalai/semantics/lqp/rewrite/annotate_constraints.py +0 -69
- relationalai/semantics/lqp/rewrite/cdc.py +0 -216
- relationalai/semantics/lqp/rewrite/constants_to_vars.py +0 -70
- relationalai/semantics/lqp/rewrite/deduplicate_vars.py +0 -104
- relationalai/semantics/lqp/rewrite/eliminate_data.py +0 -108
- relationalai/semantics/lqp/rewrite/extract_common.py +0 -340
- relationalai/semantics/lqp/rewrite/extract_keys.py +0 -577
- relationalai/semantics/lqp/rewrite/flatten_script.py +0 -301
- relationalai/semantics/lqp/rewrite/function_annotations.py +0 -114
- relationalai/semantics/lqp/rewrite/functional_dependencies.py +0 -348
- relationalai/semantics/lqp/rewrite/period_math.py +0 -77
- relationalai/semantics/lqp/rewrite/quantify_vars.py +0 -339
- relationalai/semantics/lqp/rewrite/splinter.py +0 -76
- relationalai/semantics/lqp/rewrite/unify_definitions.py +0 -323
- relationalai/semantics/lqp/types.py +0 -101
- relationalai/semantics/lqp/utils.py +0 -170
- relationalai/semantics/lqp/validators.py +0 -70
- relationalai/semantics/metamodel/compiler.py +0 -134
- relationalai/semantics/metamodel/dependency.py +0 -880
- relationalai/semantics/metamodel/executor.py +0 -78
- relationalai/semantics/metamodel/factory.py +0 -287
- relationalai/semantics/metamodel/helpers.py +0 -368
- relationalai/semantics/metamodel/ir.py +0 -924
- relationalai/semantics/metamodel/rewrite/__init__.py +0 -8
- relationalai/semantics/metamodel/rewrite/discharge_constraints.py +0 -39
- relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +0 -220
- relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +0 -78
- relationalai/semantics/metamodel/rewrite/flatten.py +0 -590
- relationalai/semantics/metamodel/rewrite/format_outputs.py +0 -256
- relationalai/semantics/metamodel/rewrite/handle_aggregations_and_ranks.py +0 -237
- relationalai/semantics/metamodel/typer/checker.py +0 -355
- relationalai/semantics/metamodel/typer/typer.py +0 -1396
- relationalai/semantics/metamodel/util.py +0 -506
- relationalai/semantics/metamodel/visitor.py +0 -945
- relationalai/semantics/reasoners/__init__.py +0 -10
- relationalai/semantics/reasoners/graph/README.md +0 -620
- relationalai/semantics/reasoners/graph/__init__.py +0 -37
- relationalai/semantics/reasoners/graph/core.py +0 -9019
- relationalai/semantics/reasoners/graph/design/beyond_demand_transform.md +0 -797
- relationalai/semantics/reasoners/graph/tests/README.md +0 -21
- relationalai/semantics/reasoners/optimization/__init__.py +0 -68
- relationalai/semantics/reasoners/optimization/common.py +0 -88
- relationalai/semantics/reasoners/optimization/solvers_dev.py +0 -568
- relationalai/semantics/reasoners/optimization/solvers_pb.py +0 -1407
- relationalai/semantics/rel/builtins.py +0 -40
- relationalai/semantics/rel/compiler.py +0 -994
- relationalai/semantics/rel/executor.py +0 -363
- relationalai/semantics/rel/rel.py +0 -482
- relationalai/semantics/rel/rel_utils.py +0 -276
- relationalai/semantics/snowflake/__init__.py +0 -3
- relationalai/semantics/sql/compiler.py +0 -2503
- relationalai/semantics/sql/executor/duck_db.py +0 -52
- relationalai/semantics/sql/executor/result_helpers.py +0 -64
- relationalai/semantics/sql/executor/snowflake.py +0 -149
- relationalai/semantics/sql/rewrite/denormalize.py +0 -222
- relationalai/semantics/sql/rewrite/double_negation.py +0 -49
- relationalai/semantics/sql/rewrite/recursive_union.py +0 -127
- relationalai/semantics/sql/rewrite/sort_output_query.py +0 -246
- relationalai/semantics/sql/sql.py +0 -504
- relationalai/semantics/std/pragmas.py +0 -11
- relationalai/semantics/std/std.py +0 -14
- relationalai/semantics/tests/lqp/algorithms.py +0 -345
- relationalai/semantics/tests/test_snapshot_abstract.py +0 -144
- relationalai/semantics/tests/test_snapshot_base.py +0 -9
- relationalai/semantics/tests/utils.py +0 -46
- relationalai/std/__init__.py +0 -70
- relationalai/tools/cli.py +0 -2089
- relationalai/tools/cli_controls.py +0 -1975
- relationalai/tools/cli_helpers.py +0 -802
- relationalai/tools/debugger_client.py +0 -109
- relationalai/tools/debugger_server.py +0 -302
- relationalai/tools/dev.py +0 -685
- relationalai/tools/notes +0 -7
- relationalai/tools/qb_debugger.py +0 -425
- relationalai/tools/txn_progress.py +0 -188
- relationalai/util/clean_up_databases.py +0 -95
- relationalai/util/list_databases.py +0 -9
- relationalai/util/otel_configuration.py +0 -26
- relationalai/util/otel_handler.py +0 -484
- relationalai/util/snowflake_handler.py +0 -88
- relationalai/util/span_format_test.py +0 -43
- relationalai/util/span_tracker.py +0 -207
- relationalai/util/spans_file_handler.py +0 -72
- relationalai/util/tracing_handler.py +0 -34
- relationalai-0.13.5.dist-info/METADATA +0 -74
- relationalai-0.13.5.dist-info/RECORD +0 -473
- relationalai-0.13.5.dist-info/WHEEL +0 -4
- relationalai-0.13.5.dist-info/entry_points.txt +0 -3
- relationalai-0.13.5.dist-info/licenses/LICENSE +0 -202
- relationalai_test_util/__init__.py +0 -4
- relationalai_test_util/fixtures.py +0 -233
- relationalai_test_util/snapshot.py +0 -252
- relationalai_test_util/traceback.py +0 -118
- /relationalai/{analysis → semantics/frontend}/__init__.py +0 -0
- /relationalai/{auth/__init__.py → semantics/metamodel/metamodel_compiler.py} +0 -0
- /relationalai/{early_access → shims}/__init__.py +0 -0
- {relationalai/early_access/dsl/adapters → v0/relationalai/analysis}/__init__.py +0 -0
- {relationalai → v0/relationalai}/analysis/mechanistic.py +0 -0
- {relationalai → v0/relationalai}/analysis/whynot.py +0 -0
- {relationalai/early_access/dsl/adapters/orm → v0/relationalai/auth}/__init__.py +0 -0
- {relationalai → v0/relationalai}/auth/jwt_generator.py +0 -0
- {relationalai → v0/relationalai}/auth/oauth_callback_server.py +0 -0
- {relationalai → v0/relationalai}/auth/token_handler.py +0 -0
- {relationalai → v0/relationalai}/auth/util.py +0 -0
- {relationalai/clients/resources/snowflake → v0/relationalai/clients}/cache_store.py +0 -0
- {relationalai → v0/relationalai}/compiler.py +0 -0
- {relationalai → v0/relationalai}/dependencies.py +0 -0
- {relationalai → v0/relationalai}/docutils.py +0 -0
- {relationalai/early_access/dsl/adapters/owl → v0/relationalai/early_access}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/__init__.py +0 -0
- {relationalai/early_access/dsl/bindings → v0/relationalai/early_access/dsl/adapters}/__init__.py +0 -0
- {relationalai/early_access/dsl/bindings/legacy → v0/relationalai/early_access/dsl/adapters/orm}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/adapters/orm/model.py +0 -0
- {relationalai/early_access/dsl/codegen → v0/relationalai/early_access/dsl/adapters/owl}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/adapters/owl/model.py +0 -0
- {relationalai/early_access/dsl/core/temporal → v0/relationalai/early_access/dsl/bindings}/__init__.py +0 -0
- {relationalai/early_access/dsl/ir → v0/relationalai/early_access/dsl/bindings/legacy}/__init__.py +0 -0
- {relationalai/early_access/dsl/ontologies → v0/relationalai/early_access/dsl/codegen}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/constants.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/core/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/core/constraints/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/core/constraints/predicate/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/core/stack.py +0 -0
- {relationalai/early_access/dsl/orm → v0/relationalai/early_access/dsl/core/temporal}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/core/utils.py +0 -0
- {relationalai/early_access/dsl/orm/measures → v0/relationalai/early_access/dsl/ir}/__init__.py +0 -0
- {relationalai/early_access/dsl/physical_metadata → v0/relationalai/early_access/dsl/ontologies}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/ontologies/raw_source.py +0 -0
- {relationalai/early_access/dsl/serialize → v0/relationalai/early_access/dsl/orm}/__init__.py +0 -0
- {relationalai/early_access/dsl/snow → v0/relationalai/early_access/dsl/orm/measures}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/orm/reasoner_errors.py +0 -0
- {relationalai/loaders → v0/relationalai/early_access/dsl/physical_metadata}/__init__.py +0 -0
- {relationalai/semantics/tests → v0/relationalai/early_access/dsl/serialize}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/serialize/binding_model.py +0 -0
- {relationalai → v0/relationalai}/early_access/dsl/serialize/model.py +0 -0
- {relationalai/semantics/tests/lqp → v0/relationalai/early_access/dsl/snow}/__init__.py +0 -0
- {relationalai → v0/relationalai}/early_access/tests/__init__.py +0 -0
- {relationalai → v0/relationalai}/environments/ci.py +0 -0
- {relationalai → v0/relationalai}/environments/hex.py +0 -0
- {relationalai → v0/relationalai}/environments/terminal.py +0 -0
- {relationalai → v0/relationalai}/experimental/__init__.py +0 -0
- {relationalai → v0/relationalai}/experimental/graphs.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/__init__.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/benchmarks/__init__.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/path_algorithms/__init__.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/rpq/__init__.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/rpq/filter.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/rpq/glushkov.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/rpq/transition.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/utilities/__init__.py +0 -0
- {relationalai → v0/relationalai}/experimental/paths/utilities/utilities.py +0 -0
- {relationalai/tools → v0/relationalai/loaders}/__init__.py +0 -0
- {relationalai → v0/relationalai}/metagen.py +0 -0
- {relationalai → v0/relationalai}/metamodel.py +0 -0
- {relationalai → v0/relationalai}/rel.py +0 -0
- {relationalai → v0/relationalai}/semantics/devtools/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/internal/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/internal/annotations.py +0 -0
- {relationalai → v0/relationalai}/semantics/lqp/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/lqp/pragmas.py +0 -0
- {relationalai → v0/relationalai}/semantics/metamodel/dataflow.py +0 -0
- {relationalai → v0/relationalai}/semantics/metamodel/typer/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/metamodel/types.py +0 -0
- {relationalai → v0/relationalai}/semantics/reasoners/experimental/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/rel/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/sql/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/sql/executor/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/sql/rewrite/__init__.py +0 -0
- {relationalai → v0/relationalai}/semantics/tests/logging.py +0 -0
- {relationalai → v0/relationalai}/std/aggregates.py +0 -0
- {relationalai → v0/relationalai}/std/dates.py +0 -0
- {relationalai → v0/relationalai}/std/graphs.py +0 -0
- {relationalai → v0/relationalai}/std/inspect.py +0 -0
- {relationalai → v0/relationalai}/std/math.py +0 -0
- {relationalai → v0/relationalai}/std/re.py +0 -0
- {relationalai → v0/relationalai}/std/strings.py +0 -0
- {relationalai → v0/relationalai}/tools/cleanup_snapshots.py +0 -0
- {relationalai → v0/relationalai}/tools/constants.py +0 -0
- {relationalai → v0/relationalai}/tools/query_utils.py +0 -0
- {relationalai → v0/relationalai}/tools/snapshot_viewer.py +0 -0
- {relationalai → v0/relationalai}/util/__init__.py +0 -0
- {relationalai → v0/relationalai}/util/constants.py +0 -0
- {relationalai → v0/relationalai}/util/graph.py +0 -0
- {relationalai → v0/relationalai}/util/timeout.py +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import duckdb
|
|
4
|
+
import math
|
|
5
|
+
from pandas import DataFrame
|
|
6
|
+
from typing import Any, Union, Literal
|
|
7
|
+
from scipy.special import erfinv as special_erfinv
|
|
8
|
+
|
|
9
|
+
from v0.relationalai.semantics.sql import Compiler
|
|
10
|
+
from v0.relationalai.semantics.sql.executor.result_helpers import format_duckdb_columns
|
|
11
|
+
from v0.relationalai.semantics.metamodel import ir, executor as e, factory as f
|
|
12
|
+
|
|
13
|
+
class DuckDBExecutor(e.Executor):
|
|
14
|
+
|
|
15
|
+
def __init__(self, skip_denormalization: bool = False) -> None:
|
|
16
|
+
super().__init__()
|
|
17
|
+
self.compiler = Compiler(skip_denormalization)
|
|
18
|
+
|
|
19
|
+
def execute(self, model: ir.Model, task: ir.Task, format:Literal["pandas", "snowpark"]="pandas") -> Union[DataFrame, Any]:
|
|
20
|
+
""" Execute the SQL query directly. """
|
|
21
|
+
if format != "pandas":
|
|
22
|
+
raise ValueError(f"Unsupported format: {format}")
|
|
23
|
+
|
|
24
|
+
connection = duckdb.connect()
|
|
25
|
+
|
|
26
|
+
# Register scalar functions
|
|
27
|
+
connection.create_function("erf", self.erf)
|
|
28
|
+
connection.create_function("acot", self.acot)
|
|
29
|
+
connection.create_function("erfinv", self.erfinv)
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
model_sql, _ = self.compiler.compile(model, {"is_duck_db": True})
|
|
33
|
+
query_options = {"is_duck_db": True, "query_compilation": True}
|
|
34
|
+
query_sql, _ = self.compiler.compile(f.compute_model(f.logical([task])), query_options)
|
|
35
|
+
|
|
36
|
+
full_sql = model_sql + "\n" + query_sql
|
|
37
|
+
arrow_table = connection.query(full_sql).fetch_arrow_table()
|
|
38
|
+
return format_duckdb_columns(arrow_table.to_pandas(), arrow_table.schema)
|
|
39
|
+
finally:
|
|
40
|
+
connection.close()
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def erf(x: float) -> float:
|
|
44
|
+
return math.erf(x)
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def erfinv(x: float) -> float:
|
|
48
|
+
return special_erfinv(x)
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def acot(x: float) -> float:
|
|
52
|
+
return math.atan(1 / x) if x != 0 else math.copysign(math.pi / 2, x)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from typing import Sequence, Optional
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import numpy as np
|
|
5
|
+
import datetime
|
|
6
|
+
import pyarrow as pa
|
|
7
|
+
from snowflake.connector.cursor import ResultMetadata
|
|
8
|
+
from snowflake.connector.constants import FIELD_ID_TO_NAME
|
|
9
|
+
|
|
10
|
+
from v0.relationalai.semantics.metamodel import ir
|
|
11
|
+
from v0.relationalai.clients.result_helpers import Int128Dtype
|
|
12
|
+
from v0.relationalai.semantics.metamodel.types import Int64, Int128, DateTime
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def format_columns(result_frame:pd.DataFrame, result_metadata:Sequence[ResultMetadata],
|
|
16
|
+
original_columns_metadata: dict[str, Optional[ir.Type]]) -> pd.DataFrame:
|
|
17
|
+
for i, col in enumerate(result_frame.columns):
|
|
18
|
+
col_name = col.lower()
|
|
19
|
+
col_metadata = result_metadata[i]
|
|
20
|
+
col_type = original_columns_metadata[col_name] if col_name in original_columns_metadata else None
|
|
21
|
+
if col_type == DateTime:
|
|
22
|
+
result_frame[col] = result_frame[col].dt.floor("ms")
|
|
23
|
+
elif col_type and isinstance(col_type, ir.DecimalType):
|
|
24
|
+
pa_dtype = pa.decimal128(precision=col_type.precision, scale=col_type.scale)
|
|
25
|
+
result_frame[col] = result_frame[col].astype(pd.ArrowDtype(pa_dtype))
|
|
26
|
+
elif result_frame[col].apply(lambda x: isinstance(x, (datetime.date, datetime.datetime))).any():
|
|
27
|
+
result_frame[col] = pd.to_datetime(result_frame[col], errors='coerce')
|
|
28
|
+
elif FIELD_ID_TO_NAME[col_metadata.type_code] == "FIXED" and col_metadata.scale == 0:
|
|
29
|
+
series = result_frame[col]
|
|
30
|
+
|
|
31
|
+
# Prefer explicit type from original metadata if present
|
|
32
|
+
if col_type == Int64:
|
|
33
|
+
result_frame[col] = series.astype("Int64")
|
|
34
|
+
elif col_type == Int128:
|
|
35
|
+
result_frame[col] = series.astype(Int128Dtype())
|
|
36
|
+
elif col_metadata.precision:
|
|
37
|
+
result_frame[col] = _cast_integer_column(series, col_metadata.precision)
|
|
38
|
+
# Handle Snowflake VARIANT columns that are actually numeric
|
|
39
|
+
elif FIELD_ID_TO_NAME[col_metadata.type_code] == "VARIANT":
|
|
40
|
+
series = result_frame[col]
|
|
41
|
+
|
|
42
|
+
if col_type == Int64:
|
|
43
|
+
result_frame[col] = series.astype("Int64")
|
|
44
|
+
elif col_type == Int128:
|
|
45
|
+
result_frame[col] = series.astype(Int128Dtype())
|
|
46
|
+
|
|
47
|
+
# SQL may return None for nulls; replace with np.nan unless the column is FIXED, because
|
|
48
|
+
# both Int64 and Int128 already deal with nulls using pd.NA
|
|
49
|
+
if not FIELD_ID_TO_NAME[col_metadata.type_code] == "FIXED":
|
|
50
|
+
result_frame[col] = result_frame[col].replace({None: np.nan})
|
|
51
|
+
return result_frame
|
|
52
|
+
|
|
53
|
+
def format_duckdb_columns(result_frame: pd.DataFrame, arrow_schema: pa.Schema) -> pd.DataFrame:
|
|
54
|
+
for field in arrow_schema:
|
|
55
|
+
col = field.name
|
|
56
|
+
pa_type = field.type
|
|
57
|
+
if pa.types.is_decimal(pa_type):
|
|
58
|
+
if pa_type.scale == 0: # integer-like
|
|
59
|
+
result_frame[col] = _cast_integer_column(result_frame[col], pa_type.precision)
|
|
60
|
+
return result_frame
|
|
61
|
+
|
|
62
|
+
def _cast_integer_column(series: pd.Series, precision: int) -> pd.Series:
|
|
63
|
+
"""Cast a numeric pandas Series to Int64 or Int128 depending on precision."""
|
|
64
|
+
return series.astype("Int64") if precision <= 19 else series.astype(Int128Dtype())
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import uuid
|
|
5
|
+
|
|
6
|
+
import v0.relationalai as rai
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
from typing import Any, Union, Optional, Literal, TYPE_CHECKING
|
|
10
|
+
from snowflake.snowpark import Session
|
|
11
|
+
|
|
12
|
+
from .. import Compiler
|
|
13
|
+
from v0.relationalai import debugging
|
|
14
|
+
from v0.relationalai.semantics.metamodel import ir, executor as e, factory as f
|
|
15
|
+
from v0.relationalai.clients.result_helpers import sort_data_frame_result
|
|
16
|
+
from v0.relationalai.semantics.sql.executor.result_helpers import format_columns
|
|
17
|
+
from v0.relationalai.semantics.metamodel.visitor import collect_by_type
|
|
18
|
+
from v0.relationalai.semantics.metamodel.typer import typer
|
|
19
|
+
from v0.relationalai.tools.constants import USE_DIRECT_ACCESS
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from v0.relationalai.semantics.snowflake import Table
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SnowflakeExecutor(e.Executor):
|
|
26
|
+
"""Executes SQL using the RAI client."""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
database: str,
|
|
31
|
+
schema: str,
|
|
32
|
+
dry_run: bool = False,
|
|
33
|
+
skip_denormalization: bool = False,
|
|
34
|
+
connection: Session | None = None,
|
|
35
|
+
config: rai.Config | None = None,
|
|
36
|
+
) -> None:
|
|
37
|
+
super().__init__()
|
|
38
|
+
self.database = database
|
|
39
|
+
self.schema = schema
|
|
40
|
+
self.dry_run = dry_run
|
|
41
|
+
self._last_model = None
|
|
42
|
+
self._last_model_sql = None
|
|
43
|
+
self.config = config or rai.Config()
|
|
44
|
+
self.compiler = Compiler(skip_denormalization)
|
|
45
|
+
self.connection = connection
|
|
46
|
+
self._resources = None
|
|
47
|
+
self._provider = None
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def resources(self):
|
|
51
|
+
if not self._resources:
|
|
52
|
+
with debugging.span("create_session"):
|
|
53
|
+
self.dry_run |= bool(self.config.get("compiler.dry_run", False))
|
|
54
|
+
resource_class = rai.clients.snowflake.Resources
|
|
55
|
+
if self.config.get("use_direct_access", USE_DIRECT_ACCESS):
|
|
56
|
+
resource_class = rai.clients.snowflake.DirectAccessResources
|
|
57
|
+
self._resources = resource_class(dry_run=self.dry_run, config=self.config, generation=rai.Generation.QB,
|
|
58
|
+
connection=self.connection)
|
|
59
|
+
return self._resources
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def provider(self):
|
|
63
|
+
if not self._provider:
|
|
64
|
+
self._provider = rai.clients.snowflake.Provider(resources=self.resources)
|
|
65
|
+
return self._provider
|
|
66
|
+
|
|
67
|
+
def execute(self, model: ir.Model, task: ir.Task, format:Literal["pandas", "snowpark"]="pandas",
|
|
68
|
+
export_to: Optional[Table] = None,
|
|
69
|
+
update: bool = False, meta: dict[str, Any] | None = None) -> Union[pd.DataFrame, Any]:
|
|
70
|
+
""" Execute the SQL query directly. """
|
|
71
|
+
|
|
72
|
+
warehouse = self.resources.config.get("warehouse", None)
|
|
73
|
+
default_dynamic_table_target_lag = (
|
|
74
|
+
self.resources.config.get("reasoner.rule.sql.default_dynamic_table_target_lag", None))
|
|
75
|
+
|
|
76
|
+
options = {"warehouse": warehouse, "default_dynamic_table_target_lag": default_dynamic_table_target_lag}
|
|
77
|
+
|
|
78
|
+
if self._last_model != model:
|
|
79
|
+
with debugging.span("compile", metamodel=model) as model_span:
|
|
80
|
+
model_span["compile_type"] = "model"
|
|
81
|
+
model_sql, _ = self.compiler.compile(model, options)
|
|
82
|
+
model_span["sql"] = model_sql
|
|
83
|
+
self._last_model = model
|
|
84
|
+
self._last_model_sql = model_sql
|
|
85
|
+
|
|
86
|
+
with debugging.span("compile", metamodel=task) as compile_span:
|
|
87
|
+
compile_span["compile_type"] = "query"
|
|
88
|
+
# compile into sql and keep the new_task, which is the task model after rewrites,
|
|
89
|
+
# as it may contain results of type inference, which is useful for determining
|
|
90
|
+
# how to format the outputs
|
|
91
|
+
query_options = {**options, "query_compilation": True}
|
|
92
|
+
query_sql, new_task = self.compiler.compile(f.compute_model(f.logical([task])), query_options)
|
|
93
|
+
compile_span["sql"] = query_sql
|
|
94
|
+
|
|
95
|
+
if self.dry_run:
|
|
96
|
+
return pd.DataFrame()
|
|
97
|
+
|
|
98
|
+
if format != "pandas":
|
|
99
|
+
raise ValueError(f"Unsupported format: {format}")
|
|
100
|
+
|
|
101
|
+
_replace_pattern = re.compile(r"[ /:-]")
|
|
102
|
+
|
|
103
|
+
def sanitize_name(value: str) -> str:
|
|
104
|
+
return _replace_pattern.sub("_", value)
|
|
105
|
+
|
|
106
|
+
database = sanitize_name(self.database)
|
|
107
|
+
schema = sanitize_name(self.schema)
|
|
108
|
+
unique_id = sanitize_name(str(uuid.uuid4()).lower())
|
|
109
|
+
db_name = f"{database}_{unique_id}"
|
|
110
|
+
db_query = f"CREATE OR REPLACE DATABASE {db_name};"
|
|
111
|
+
schema_query = f"CREATE OR REPLACE SCHEMA {db_name}.{schema};"
|
|
112
|
+
use_schema_query = f"USE SCHEMA {db_name}.{schema};"
|
|
113
|
+
|
|
114
|
+
full_model_sql = f"{db_query}\n{schema_query}\n{use_schema_query}\n{self._last_model_sql}\n{query_sql}"
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
result = self.provider.resources._session.connection.execute_string(full_model_sql) # type: ignore
|
|
118
|
+
|
|
119
|
+
# Assuming that `task` is a single SQL query per model, and we have it always at the end of the generated SQL.
|
|
120
|
+
rows = result[-1].fetchall()
|
|
121
|
+
result_metadata = result[-1].description
|
|
122
|
+
|
|
123
|
+
df = pd.DataFrame(rows, columns=[col.name for col in result_metadata])
|
|
124
|
+
if df.empty:
|
|
125
|
+
# return empty df without column names if it's empty
|
|
126
|
+
return df.iloc[:, 0:0]
|
|
127
|
+
|
|
128
|
+
df = format_columns(df, result_metadata, self._collect_columns_metadata(new_task))
|
|
129
|
+
return sort_data_frame_result(df)
|
|
130
|
+
|
|
131
|
+
finally:
|
|
132
|
+
self.provider.sql(f"DROP DATABASE IF EXISTS {db_name};")
|
|
133
|
+
|
|
134
|
+
def _collect_columns_metadata(self, task: ir.Task) -> dict[str, Optional[ir.Type]]:
|
|
135
|
+
if not task:
|
|
136
|
+
return {}
|
|
137
|
+
|
|
138
|
+
outputs = collect_by_type(ir.Output, task)
|
|
139
|
+
|
|
140
|
+
assert len(outputs) == 1
|
|
141
|
+
return {
|
|
142
|
+
alias.lower(): typer.to_base_primitive(var.type)
|
|
143
|
+
for alias, var in outputs[0].aliases
|
|
144
|
+
if alias and isinstance(var, ir.Var)
|
|
145
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Tuple, Union
|
|
4
|
+
from typing import cast
|
|
5
|
+
|
|
6
|
+
from v0.relationalai.semantics.metamodel import ir, compiler as c, factory as f, types, visitor
|
|
7
|
+
from v0.relationalai.semantics.metamodel.util import FrozenOrderedSet, OrderedSet, ordered_set, group_by, split_by
|
|
8
|
+
|
|
9
|
+
class Denormalize(c.Pass):
|
|
10
|
+
"""
|
|
11
|
+
Pass to denormalize relations, grouping relations that have the same entity as key.
|
|
12
|
+
|
|
13
|
+
General algorithm:
|
|
14
|
+
|
|
15
|
+
1. when handling the Model, go to its relations and find the ones that have common
|
|
16
|
+
entity keys. They will be denormalized (joined together as a single "table").
|
|
17
|
+
2. when handling lookups and updates that refer to one of these relations that were
|
|
18
|
+
denormalized, change the reference to be to the new relation and fill the blanks with
|
|
19
|
+
Nones, which represent NULLs.
|
|
20
|
+
3. finally, when handling Logical nodes, try to group together lookups and updates that
|
|
21
|
+
are refering to the same denormalized relation. This may remove some of the NULLs.
|
|
22
|
+
"""
|
|
23
|
+
def rewrite(self, model: ir.Model, options:dict={}) -> ir.Model:
|
|
24
|
+
return OldDenormalize().walk(model)
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class OldDenormalize(visitor.Rewriter):
|
|
28
|
+
|
|
29
|
+
denormalized: dict[ir.Relation, ir.Relation] = field(default_factory=dict, init=False, hash=False, compare=False)
|
|
30
|
+
|
|
31
|
+
def reset(self):
|
|
32
|
+
self.context = dict()
|
|
33
|
+
self.denormalized = dict()
|
|
34
|
+
|
|
35
|
+
def handle_model(self, model: ir.Model, parent: None):
|
|
36
|
+
# denormalize some relations in the model, set it in the context, and then push
|
|
37
|
+
# that context to the root traversal so that references to the denormalized
|
|
38
|
+
# relations are adjusted.
|
|
39
|
+
|
|
40
|
+
# denormalize the relations
|
|
41
|
+
relations, self.denormalized = self._denormalize_relations(model.relations)
|
|
42
|
+
|
|
43
|
+
# rewrite tasks to refer to denormalized relations
|
|
44
|
+
return ir.Model(
|
|
45
|
+
self.walk_set(model.engines, model),
|
|
46
|
+
relations,
|
|
47
|
+
self.walk_set(model.types, model),
|
|
48
|
+
self.walk(model.root, model),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def handle_update(self, node: ir.Update, parent: ir.Node):
|
|
52
|
+
# if the relation to be updated was denormalized, denormalize the reference
|
|
53
|
+
|
|
54
|
+
if node.relation not in self.denormalized:
|
|
55
|
+
return super().handle_update(node, parent)
|
|
56
|
+
|
|
57
|
+
denormalized_relation = self.denormalized[node.relation]
|
|
58
|
+
args = self._denormalize_reference(
|
|
59
|
+
denormalized_relation, node.relation, node.args
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
return ir.Update(
|
|
63
|
+
node.engine,
|
|
64
|
+
denormalized_relation,
|
|
65
|
+
args,
|
|
66
|
+
node.effect,
|
|
67
|
+
node.annotations
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
def handle_lookup(self, node: ir.Lookup, parent: ir.Node):
|
|
71
|
+
# if the relation to be looked up was denormalized, denormalize the reference
|
|
72
|
+
|
|
73
|
+
if node.relation not in self.denormalized:
|
|
74
|
+
return super().handle_lookup(node, parent)
|
|
75
|
+
|
|
76
|
+
denormalized_relation = self.denormalized[node.relation]
|
|
77
|
+
args = self._denormalize_reference(
|
|
78
|
+
denormalized_relation, node.relation, node.args
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return ir.Lookup(
|
|
82
|
+
node.engine,
|
|
83
|
+
denormalized_relation,
|
|
84
|
+
args
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def handle_logical(self, node: ir.Logical, parent: ir.Node):
|
|
88
|
+
# denormalize the body first
|
|
89
|
+
body = self.walk_list(node.body, node)
|
|
90
|
+
|
|
91
|
+
# Unwrap single lookups from the logical
|
|
92
|
+
# for example we may have this IR to say that `adult` may not have a `name`
|
|
93
|
+
# Logical ⇑[name=None]
|
|
94
|
+
# name(adult, name)
|
|
95
|
+
updated_body = [
|
|
96
|
+
t.body[0] if isinstance(t, ir.Logical) and len(t.body) == 1 else t
|
|
97
|
+
for t in body
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
# function to compute a key to group Lookups or Updates that can be merged
|
|
101
|
+
def task_key(t: ir.Task):
|
|
102
|
+
assert isinstance(t, (ir.Lookup, ir.Update))
|
|
103
|
+
return (t.kind, t.relation, t.args[0])
|
|
104
|
+
|
|
105
|
+
# now group references
|
|
106
|
+
tasks, new_body = split_by(updated_body, lambda t: isinstance(t, (ir.Lookup, ir.Update)))
|
|
107
|
+
for _, grouped_tasks in group_by(tasks, task_key).items():
|
|
108
|
+
grouped_tasks = cast(OrderedSet[Union[ir.Lookup, ir.Update]], grouped_tasks)
|
|
109
|
+
|
|
110
|
+
# get some of the tasks as a representative
|
|
111
|
+
some = grouped_tasks.some()
|
|
112
|
+
|
|
113
|
+
if len(grouped_tasks) == 1:
|
|
114
|
+
new_body.append(some)
|
|
115
|
+
continue
|
|
116
|
+
|
|
117
|
+
# now join the arguments of the multiple references
|
|
118
|
+
# TODO: this will fail if we have multiple tasks on the same arg
|
|
119
|
+
new_args = []
|
|
120
|
+
i = 0
|
|
121
|
+
for _ in some.relation.fields:
|
|
122
|
+
# note that we are still using None to indicate we don't care about the column
|
|
123
|
+
v = None
|
|
124
|
+
for t in grouped_tasks:
|
|
125
|
+
if t.args[i] is not None:
|
|
126
|
+
v = t.args[i]
|
|
127
|
+
break
|
|
128
|
+
new_args.append(v)
|
|
129
|
+
i += 1
|
|
130
|
+
|
|
131
|
+
# finally, create a rewritten task for the whole group
|
|
132
|
+
if isinstance(some, ir.Lookup):
|
|
133
|
+
new_body.append(ir.Lookup(some.engine, some.relation, tuple(new_args)))
|
|
134
|
+
else:
|
|
135
|
+
new_body.append(ir.Update(some.engine, some.relation, tuple(new_args), some.effect, some.annotations)) # TODO maybe merge annos?
|
|
136
|
+
return ir.Logical(
|
|
137
|
+
node.engine,
|
|
138
|
+
node.hoisted,
|
|
139
|
+
tuple(new_body)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _denormalize_reference(self, denormalized_relation, relation, args) -> Tuple[ir.Value, ...]:
|
|
144
|
+
""" Adjust arguments to a denormalized reference.
|
|
145
|
+
|
|
146
|
+
A reference to `relation` was used with `args`. But `relation` was denormalized
|
|
147
|
+
into `denormalized_relation`. This method returns a new tuple of adjusted args
|
|
148
|
+
to account for the denormalization, filling Nones as appropriate.
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
# the first arg is always the entity
|
|
152
|
+
new_args = [args[0]]
|
|
153
|
+
# for the rest of the denormalized relation columns, lookup only if the field came
|
|
154
|
+
# from this relation, otherwise use None
|
|
155
|
+
i = 1
|
|
156
|
+
for fld in denormalized_relation.fields[1:]:
|
|
157
|
+
if fld in relation.fields:
|
|
158
|
+
new_args.append(args[i])
|
|
159
|
+
i += 1
|
|
160
|
+
else:
|
|
161
|
+
new_args.append(None)
|
|
162
|
+
return tuple(new_args)
|
|
163
|
+
|
|
164
|
+
def _denormalize_relations(self, relations: FrozenOrderedSet[ir.Relation]) -> \
|
|
165
|
+
Tuple[FrozenOrderedSet[ir.Relation], dict[ir.Relation, ir.Relation]]:
|
|
166
|
+
|
|
167
|
+
""" Denormalize the relations that can be denormalized.
|
|
168
|
+
|
|
169
|
+
Group together relations that are keyed by the same "entity". This method defines
|
|
170
|
+
entities as being types that have a unary relation containing only that type. All
|
|
171
|
+
relations whose first argument is this type are grouped together.
|
|
172
|
+
|
|
173
|
+
Returns a tuple with 2 elements:
|
|
174
|
+
1. The new set of relations after denormalization
|
|
175
|
+
2. A dict from relations that were denormalized away to the new relation that took its place.
|
|
176
|
+
"""
|
|
177
|
+
new_relations = ordered_set()
|
|
178
|
+
denormalized: dict[ir.Relation, ir.Relation] = dict()
|
|
179
|
+
|
|
180
|
+
# entities are non-builtin types that have a unary relation
|
|
181
|
+
entity_types: OrderedSet[ir.Type] = ordered_set()
|
|
182
|
+
entity_relations: dict[ir.Type, ir.Relation] = dict()
|
|
183
|
+
|
|
184
|
+
for r in relations:
|
|
185
|
+
if len(r.fields) == 1 and not types.is_builtin(r.fields[0].type) and not r.name == 'Error':
|
|
186
|
+
e = r.fields[0].type
|
|
187
|
+
entity_types.add(e)
|
|
188
|
+
entity_relations[e] = r
|
|
189
|
+
|
|
190
|
+
# filter out relations that don't have an entity as a key
|
|
191
|
+
with_entity, unaffected = split_by(
|
|
192
|
+
relations,
|
|
193
|
+
lambda r:
|
|
194
|
+
r.fields[0].type in entity_types # the first element is an entity
|
|
195
|
+
# TODO - we need to account for wide relations that have multis
|
|
196
|
+
)
|
|
197
|
+
new_relations.update(unaffected)
|
|
198
|
+
|
|
199
|
+
# group relations by entity, they will be denormalized
|
|
200
|
+
by_entity = group_by(with_entity, lambda r: cast(ir.ScalarType, r.fields[0].type))
|
|
201
|
+
for e_type, group in by_entity.items():
|
|
202
|
+
r = entity_relations[e_type]
|
|
203
|
+
fields = []
|
|
204
|
+
# the first column of the denormalized relation is the "id"
|
|
205
|
+
fields.append(r.fields[0])
|
|
206
|
+
for relation in group:
|
|
207
|
+
# add all fields except the first entity field
|
|
208
|
+
# TODO - we may have multiple relations with the same name
|
|
209
|
+
fields.extend(relation.fields[1:])
|
|
210
|
+
|
|
211
|
+
# create the new denormalized relation, add it to the new_relations set
|
|
212
|
+
denormalized_relation = f.relation(
|
|
213
|
+
e_type.name,
|
|
214
|
+
fields
|
|
215
|
+
)
|
|
216
|
+
new_relations.add(denormalized_relation)
|
|
217
|
+
|
|
218
|
+
# make sure the original relations point to the new relation
|
|
219
|
+
for g in group:
|
|
220
|
+
denormalized[g] = denormalized_relation
|
|
221
|
+
|
|
222
|
+
return new_relations.frozen(), denormalized
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from v0.relationalai.semantics.metamodel import ir, compiler as c, factory as f, visitor
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class DoubleNegation(c.Pass):
|
|
8
|
+
"""
|
|
9
|
+
Pass to drop double negations.
|
|
10
|
+
|
|
11
|
+
Examples:
|
|
12
|
+
not_(not_(Person.age > 18, Person.id == 2)) -> (Person.age > 18, Person.id == 2)
|
|
13
|
+
not_(not_(not_(Person.age > 18, Person.id == 2))) -> not_(Person.age > 18, Person.id == 2)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def rewrite(self, model: ir.Model, options: dict = {}) -> ir.Model:
|
|
17
|
+
return DropDoubleNegationsVisitor().walk(model)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class DropDoubleNegationsVisitor(visitor.Rewriter):
|
|
22
|
+
"""
|
|
23
|
+
Visitor drops double negations when they are followed one by one in IR Model.
|
|
24
|
+
The rewrite occurs only when `ir.Not`'s task is an `ir.Logical` with single `ir.Not` in the body.
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
Not
|
|
28
|
+
Logical
|
|
29
|
+
Not
|
|
30
|
+
Logical
|
|
31
|
+
age(person, age)
|
|
32
|
+
age > 18
|
|
33
|
+
|
|
34
|
+
Logical
|
|
35
|
+
age(person, age)
|
|
36
|
+
age > 18
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def handle_not(self, node: ir.Not, parent: ir.Node):
|
|
40
|
+
if isinstance(node.task, ir.Logical) and len(node.task.body) == 1 and isinstance(node.task.body[0], ir.Not):
|
|
41
|
+
new_task = self.walk(node.task.body[0].task, node.task.body[0])
|
|
42
|
+
# dropping redundant Logical if it has only 1 element in his body
|
|
43
|
+
if isinstance(new_task, ir.Logical) and len(new_task.body) == 1:
|
|
44
|
+
return new_task.body[0]
|
|
45
|
+
else:
|
|
46
|
+
return new_task
|
|
47
|
+
else:
|
|
48
|
+
new_task = self.walk(node.task, node)
|
|
49
|
+
return node if node.task is new_task else f.not_(new_task)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import cast, Optional
|
|
6
|
+
|
|
7
|
+
from v0.relationalai.semantics.metamodel import ir, compiler as c, factory as f
|
|
8
|
+
from v0.relationalai.semantics.metamodel.util import OrderedSet, ordered_set
|
|
9
|
+
from v0.relationalai.semantics.metamodel.visitor import Visitor
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RecursiveUnion(c.Pass):
|
|
13
|
+
"""
|
|
14
|
+
Pass to rewrite recursive relations as unions of `ir.Logical` nodes.
|
|
15
|
+
|
|
16
|
+
This pass identifies recursive relations by detecting `ir.Logical` nodes that both read from and write to the same `ir.Relation`.
|
|
17
|
+
Once a recursive relation is found, all logicals that write to that relation are grouped together.
|
|
18
|
+
These groups are then wrapped in an `ir.Union`, and the model's root task is reconstructed accordingly.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def rewrite(self, model: ir.Model, options:dict={}) -> ir.Model:
|
|
22
|
+
rpv = TopLogicalReadWriteVisitor()
|
|
23
|
+
model.accept(rpv)
|
|
24
|
+
|
|
25
|
+
reads: dict[ir.Logical, OrderedSet[int]] = rpv.reads()
|
|
26
|
+
writes: dict[ir.Logical, OrderedSet[int]] = rpv.writes()
|
|
27
|
+
|
|
28
|
+
# Step 1: Identify recursive relation IDs (read & write in same logical)
|
|
29
|
+
recursive_rel_ids = {
|
|
30
|
+
rel_id
|
|
31
|
+
for logical, write_ids in writes.items()
|
|
32
|
+
for rel_id in write_ids & reads.get(logical, OrderedSet())
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Step 2: Group ir.Logical nodes that write to any recursive relation
|
|
36
|
+
recursive_groups: dict[int, OrderedSet[ir.Logical]] = defaultdict(OrderedSet)
|
|
37
|
+
recursive_logicals: OrderedSet[ir.Logical] = OrderedSet()
|
|
38
|
+
|
|
39
|
+
for logical, write_ids in writes.items():
|
|
40
|
+
for rel_id in write_ids:
|
|
41
|
+
if rel_id in recursive_rel_ids:
|
|
42
|
+
recursive_groups[rel_id].add(logical)
|
|
43
|
+
recursive_logicals.add(logical)
|
|
44
|
+
|
|
45
|
+
if recursive_logicals:
|
|
46
|
+
|
|
47
|
+
# Step 3: Construct the new logical body
|
|
48
|
+
root_logical = cast(ir.Logical, model.root)
|
|
49
|
+
new_body = [logical for logical in root_logical.body if logical not in recursive_logicals]
|
|
50
|
+
|
|
51
|
+
# Step 4: Add unions for each recursive group
|
|
52
|
+
for rel_id, logical_group in recursive_groups.items():
|
|
53
|
+
split_group = ordered_set()
|
|
54
|
+
|
|
55
|
+
for logical in logical_group:
|
|
56
|
+
# Count total ir.Update tasks in this logical
|
|
57
|
+
update_count = sum(isinstance(t, ir.Update) for t in logical.body)
|
|
58
|
+
|
|
59
|
+
# If there's only one, keep the original logical as-is
|
|
60
|
+
if update_count == 1:
|
|
61
|
+
split_group.add(logical)
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
# Otherwise, keep only updates relevant to this relation (and non-update tasks)
|
|
65
|
+
filtered_body = [
|
|
66
|
+
t for t in logical.body
|
|
67
|
+
if not isinstance(t, ir.Update) or t.relation.id == rel_id
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
if filtered_body:
|
|
71
|
+
split_group.add(f.logical(filtered_body))
|
|
72
|
+
|
|
73
|
+
if split_group:
|
|
74
|
+
new_body.append(f.union(list(split_group)))
|
|
75
|
+
|
|
76
|
+
return model.reconstruct(model.engines, model.relations, model.types, f.logical(new_body), model.annotations)
|
|
77
|
+
|
|
78
|
+
return model
|
|
79
|
+
|
|
80
|
+
@dataclass
|
|
81
|
+
class TopLogicalReadWriteVisitor(Visitor):
|
|
82
|
+
"""
|
|
83
|
+
Compute the set of reads and writes relation ids for top level Logical nodes.
|
|
84
|
+
Skip unions, because we are using this pass to find recursive rule and union them.
|
|
85
|
+
|
|
86
|
+
Note that reads are Lookups and writes are Updates. We don't consider Output a write
|
|
87
|
+
because it is not targeting a relation.
|
|
88
|
+
|
|
89
|
+
This visitor can be called from ir.Model.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
_reads: dict[ir.Logical, OrderedSet[int]] = field(default_factory=dict)
|
|
93
|
+
_writes: dict[ir.Logical, OrderedSet[int]] = field(default_factory=dict)
|
|
94
|
+
|
|
95
|
+
def reads(self):
|
|
96
|
+
return self._reads
|
|
97
|
+
|
|
98
|
+
def writes(self):
|
|
99
|
+
return self._writes
|
|
100
|
+
|
|
101
|
+
_stack: list[ir.Logical] = field(default_factory=list)
|
|
102
|
+
|
|
103
|
+
def visit_logical(self, node: ir.Logical, parent: Optional[ir.Node]):
|
|
104
|
+
# We only track reads/writes for top-level Logical nodes and also skip top level program Logical node.
|
|
105
|
+
if not isinstance(parent, ir.Model):
|
|
106
|
+
self._stack.append(node)
|
|
107
|
+
super().visit_logical(node, parent)
|
|
108
|
+
if self._stack:
|
|
109
|
+
self._stack.pop()
|
|
110
|
+
|
|
111
|
+
def visit_lookup(self, node: ir.Lookup, parent: Optional[ir.Node]):
|
|
112
|
+
for logical in self._stack:
|
|
113
|
+
if logical not in self._reads:
|
|
114
|
+
self._reads[logical] = ordered_set()
|
|
115
|
+
self._reads[logical].add(node.relation.id)
|
|
116
|
+
return super().visit_lookup(node, parent)
|
|
117
|
+
|
|
118
|
+
def visit_update(self, node: ir.Update, parent: Optional[ir.Node]):
|
|
119
|
+
for logical in self._stack:
|
|
120
|
+
if logical not in self.writes():
|
|
121
|
+
self._writes[logical] = ordered_set()
|
|
122
|
+
self._writes[logical].add(node.relation.id)
|
|
123
|
+
return super().visit_update(node, parent)
|
|
124
|
+
|
|
125
|
+
def visit_union(self, node: ir.Union, parent: Optional[ir.Node]):
|
|
126
|
+
# Skip unions, because we are using this pass to find recursive rule and union them.
|
|
127
|
+
pass
|