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,680 @@
|
|
|
1
|
+
from v0.relationalai.semantics.metamodel.compiler import Pass
|
|
2
|
+
from v0.relationalai.semantics.metamodel import ir, builtins as rel_builtins, factory as f, visitor
|
|
3
|
+
from v0.relationalai.semantics.metamodel.typer import Checker, InferTypes, typer
|
|
4
|
+
from v0.relationalai.semantics.metamodel import helpers, types
|
|
5
|
+
from v0.relationalai.semantics.metamodel.util import FrozenOrderedSet
|
|
6
|
+
|
|
7
|
+
from v0.relationalai.semantics.metamodel.rewrite import Flatten
|
|
8
|
+
|
|
9
|
+
from ..metamodel.rewrite import DNFUnionSplitter, ExtractNestedLogicals, FormatOutputs
|
|
10
|
+
from .rewrite import (
|
|
11
|
+
AnnotateConstraints, CDC, ExtractCommon, ExtractKeys, FunctionAnnotations, QuantifyVars,
|
|
12
|
+
Splinter, SplitMultiCheckRequires
|
|
13
|
+
)
|
|
14
|
+
from v0.relationalai.semantics.lqp.utils import output_names
|
|
15
|
+
|
|
16
|
+
from typing import cast, List, Sequence, Tuple, Union, Optional, Iterable
|
|
17
|
+
from collections import defaultdict
|
|
18
|
+
import pandas as pd
|
|
19
|
+
import hashlib
|
|
20
|
+
|
|
21
|
+
def lqp_passes() -> list[Pass]:
|
|
22
|
+
return [
|
|
23
|
+
SplitMultiCheckRequires(),
|
|
24
|
+
FunctionAnnotations(),
|
|
25
|
+
AnnotateConstraints(),
|
|
26
|
+
Checker(),
|
|
27
|
+
CDC(), # specialize to physical relations before extracting nested and typing
|
|
28
|
+
ExtractNestedLogicals(), # before InferTypes to avoid extracting casts
|
|
29
|
+
InferTypes(),
|
|
30
|
+
DNFUnionSplitter(),
|
|
31
|
+
ExtractKeys(),
|
|
32
|
+
FormatOutputs(),
|
|
33
|
+
ExtractCommon(), # Extracts tasks that will become common after Flatten into their own definition
|
|
34
|
+
Flatten(),
|
|
35
|
+
Splinter(), # Splits multi-headed rules into multiple rules
|
|
36
|
+
QuantifyVars(), # Adds missing existentials
|
|
37
|
+
EliminateData(), # Turns Data nodes into ordinary relations.
|
|
38
|
+
DeduplicateVars(), # Deduplicates vars in Updates and Outputs.
|
|
39
|
+
PeriodMath(), # Rewrite date period uses.
|
|
40
|
+
ConstantsToVars(), # Turns constants in Updates and Outputs into vars.
|
|
41
|
+
UnifyDefinitions(),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
# LQP does not support multiple definitions for the same relation. This pass unifies all
|
|
45
|
+
# definitions for each relation into a single definition using a union.
|
|
46
|
+
class UnifyDefinitions(Pass):
|
|
47
|
+
def __init__(self):
|
|
48
|
+
super().__init__()
|
|
49
|
+
|
|
50
|
+
def rewrite(self, model: ir.Model, options:dict={}) -> ir.Model:
|
|
51
|
+
# Maintain a cache of renamings for each relation. These need to be consistent
|
|
52
|
+
# across all definitions of the same relation.
|
|
53
|
+
self.renamed_relation_args: dict[Union[ir.Value, ir.Relation], list[ir.Var]] = {}
|
|
54
|
+
|
|
55
|
+
root = cast(ir.Logical, model.root)
|
|
56
|
+
new_tasks = self.get_combined_multidefs(root)
|
|
57
|
+
return ir.Model(
|
|
58
|
+
model.engines,
|
|
59
|
+
model.relations,
|
|
60
|
+
model.types,
|
|
61
|
+
f.logical(
|
|
62
|
+
tuple(new_tasks),
|
|
63
|
+
root.hoisted,
|
|
64
|
+
root.engine,
|
|
65
|
+
),
|
|
66
|
+
model.annotations,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def _get_heads(self, logical: ir.Logical) -> list[Union[ir.Update, ir.Output]]:
|
|
70
|
+
derives = []
|
|
71
|
+
for task in logical.body:
|
|
72
|
+
if isinstance(task, ir.Update) and task.effect == ir.Effect.derive:
|
|
73
|
+
derives.append(task)
|
|
74
|
+
elif isinstance(task, ir.Output):
|
|
75
|
+
derives.append(task)
|
|
76
|
+
return derives
|
|
77
|
+
|
|
78
|
+
def _get_non_heads(self, logical: ir.Logical) -> list[ir.Task]:
|
|
79
|
+
non_derives = []
|
|
80
|
+
for task in logical.body:
|
|
81
|
+
if not(isinstance(task, ir.Update) and task.effect == ir.Effect.derive) and not isinstance(task, ir.Output):
|
|
82
|
+
non_derives.append(task)
|
|
83
|
+
return non_derives
|
|
84
|
+
|
|
85
|
+
def _get_head_identifier(self, head: Union[ir.Update, ir.Output]) -> Optional[ir.Value]:
|
|
86
|
+
if isinstance(head, ir.Update):
|
|
87
|
+
return head.relation
|
|
88
|
+
else:
|
|
89
|
+
assert isinstance(head, ir.Output)
|
|
90
|
+
if len(head.aliases) <= 2:
|
|
91
|
+
# For processing here, we need output to have at least the column markers
|
|
92
|
+
# `cols` and `col`, and also a key
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
output_alias_names = helpers.output_alias_names(head.aliases)
|
|
96
|
+
output_vals = helpers.output_values(head.aliases)
|
|
97
|
+
|
|
98
|
+
# For normal outputs, the pattern is output[keys](cols, "col000" as 'col', ...)
|
|
99
|
+
if output_alias_names[0] == "cols" and output_alias_names[1] == "col":
|
|
100
|
+
return output_vals[1]
|
|
101
|
+
|
|
102
|
+
# For exports, the pattern is output[keys]("col000" as 'col', ...)
|
|
103
|
+
if rel_builtins.export_annotation in head.annotations:
|
|
104
|
+
if output_alias_names[0] == "col":
|
|
105
|
+
return output_vals[0]
|
|
106
|
+
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
def get_combined_multidefs(self, root: ir.Logical) -> list[ir.Logical]:
|
|
110
|
+
# Step 1: Group tasks by the relation they define.
|
|
111
|
+
relation_to_tasks: dict[Union[None, ir.Value, ir.Relation], list[ir.Logical]] = defaultdict(list)
|
|
112
|
+
|
|
113
|
+
for task in root.body:
|
|
114
|
+
task = cast(ir.Logical, task)
|
|
115
|
+
task_heads = self._get_heads(task)
|
|
116
|
+
|
|
117
|
+
# Some relations do not need to be grouped, e.g., if they don't contain a
|
|
118
|
+
# derive. Use `None` as a placeholder key for these cases.
|
|
119
|
+
if len(task_heads) != 1:
|
|
120
|
+
relation_to_tasks[None].append(task)
|
|
121
|
+
continue
|
|
122
|
+
|
|
123
|
+
head_id = self._get_head_identifier(task_heads[0])
|
|
124
|
+
relation_to_tasks[head_id].append(task)
|
|
125
|
+
|
|
126
|
+
# Step 2: For each relation, combine all of the body definitions into a union.
|
|
127
|
+
result_tasks = []
|
|
128
|
+
for relation, tasks in relation_to_tasks.items():
|
|
129
|
+
# If there's only one task for the relation, or if grouping is not needed, then
|
|
130
|
+
# just keep the original tasks.
|
|
131
|
+
if len(tasks) == 1 or relation is None:
|
|
132
|
+
result_tasks.extend(tasks)
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
result_tasks.append(self._combine_tasks_into_union(tasks))
|
|
136
|
+
return result_tasks
|
|
137
|
+
|
|
138
|
+
def _get_variable_mapping(self, logical: ir.Logical) -> dict[ir.Value, ir.Var]:
|
|
139
|
+
heads = self._get_heads(logical)
|
|
140
|
+
assert len(heads) == 1, "should only have one head in a logical at this stage"
|
|
141
|
+
head = heads[0]
|
|
142
|
+
|
|
143
|
+
var_mapping = {}
|
|
144
|
+
head_id = self._get_head_identifier(head)
|
|
145
|
+
|
|
146
|
+
if isinstance(head, ir.Update):
|
|
147
|
+
args_for_renaming = head.args
|
|
148
|
+
else:
|
|
149
|
+
assert isinstance(head, ir.Output)
|
|
150
|
+
output_alias_names = helpers.output_alias_names(head.aliases)
|
|
151
|
+
if output_alias_names[0] == "cols" and output_alias_names[1] == "col":
|
|
152
|
+
assert len(head.aliases) > 2
|
|
153
|
+
|
|
154
|
+
# For outputs, we do not need to rename the `cols` and `col` markers or the
|
|
155
|
+
# keys.
|
|
156
|
+
output_values = helpers.output_values(head.aliases)[2:]
|
|
157
|
+
|
|
158
|
+
else:
|
|
159
|
+
assert rel_builtins.export_annotation in head.annotations and output_alias_names[0] == "col"
|
|
160
|
+
assert len(head.aliases) > 1
|
|
161
|
+
|
|
162
|
+
# For exports, we do not need to rename the `col` marker or the keys.
|
|
163
|
+
output_values = helpers.output_values(head.aliases)[1:]
|
|
164
|
+
|
|
165
|
+
args_for_renaming = []
|
|
166
|
+
for v in output_values:
|
|
167
|
+
if head.keys and isinstance(v, ir.Var) and v in head.keys:
|
|
168
|
+
continue
|
|
169
|
+
args_for_renaming.append(v)
|
|
170
|
+
|
|
171
|
+
if head_id not in self.renamed_relation_args:
|
|
172
|
+
renamed_vars = []
|
|
173
|
+
for (i, arg) in enumerate(args_for_renaming):
|
|
174
|
+
typ = typer.to_type(arg)
|
|
175
|
+
assert arg not in var_mapping, "args of update should be unique"
|
|
176
|
+
if isinstance(arg, ir.Var):
|
|
177
|
+
var_mapping[arg] = ir.Var(typ, arg.name)
|
|
178
|
+
else:
|
|
179
|
+
var_mapping[arg] = ir.Var(typ, f"arg_{i}")
|
|
180
|
+
|
|
181
|
+
renamed_vars.append(var_mapping[arg])
|
|
182
|
+
self.renamed_relation_args[head_id] = renamed_vars
|
|
183
|
+
else:
|
|
184
|
+
for (arg, var) in zip(args_for_renaming, self.renamed_relation_args[head_id]):
|
|
185
|
+
var_mapping[arg] = var
|
|
186
|
+
|
|
187
|
+
return var_mapping
|
|
188
|
+
|
|
189
|
+
def _rename_variables(self, logical: ir.Logical) -> ir.Logical:
|
|
190
|
+
class RenameVisitor(visitor.Rewriter):
|
|
191
|
+
def __init__(self, var_mapping: dict[ir.Value, ir.Var]):
|
|
192
|
+
super().__init__()
|
|
193
|
+
self.var_mapping = var_mapping
|
|
194
|
+
|
|
195
|
+
def _get_mapped_value(self, val: ir.Value) -> ir.Value:
|
|
196
|
+
if isinstance(val, tuple):
|
|
197
|
+
return tuple(self._get_mapped_value(t) for t in val)
|
|
198
|
+
return self.var_mapping.get(val, val)
|
|
199
|
+
|
|
200
|
+
def _get_mapped_values(self, vals: Iterable[ir.Value]) -> list[ir.Value]:
|
|
201
|
+
return [self._get_mapped_value(v) for v in vals]
|
|
202
|
+
|
|
203
|
+
def handle_var(self, node: ir.Var, parent: ir.Node) -> ir.Var:
|
|
204
|
+
return self.var_mapping.get(node, node)
|
|
205
|
+
|
|
206
|
+
# TODO: ideally, extend the rewriter class to allow rewriting PyValue to Var so
|
|
207
|
+
# we don't need to separately handle all cases containing them.
|
|
208
|
+
def handle_update(self, node: ir.Update, parent: ir.Node) -> ir.Update:
|
|
209
|
+
return ir.Update(
|
|
210
|
+
node.engine,
|
|
211
|
+
node.relation,
|
|
212
|
+
tuple(self._get_mapped_values(node.args)),
|
|
213
|
+
node.effect,
|
|
214
|
+
node.annotations,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
def handle_lookup(self, node: ir.Lookup, parent: ir.Node) -> ir.Lookup:
|
|
218
|
+
return ir.Lookup(
|
|
219
|
+
node.engine,
|
|
220
|
+
node.relation,
|
|
221
|
+
tuple(self._get_mapped_values(node.args)),
|
|
222
|
+
node.annotations,
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
def handle_output(self, node: ir.Output, parent: ir.Node) -> ir.Output:
|
|
226
|
+
new_aliases = FrozenOrderedSet(
|
|
227
|
+
[(name, self._get_mapped_value(value)) for name, value in node.aliases]
|
|
228
|
+
)
|
|
229
|
+
if node.keys:
|
|
230
|
+
new_keys = FrozenOrderedSet(
|
|
231
|
+
[self.var_mapping.get(key, key) for key in node.keys]
|
|
232
|
+
)
|
|
233
|
+
else:
|
|
234
|
+
new_keys = node.keys
|
|
235
|
+
|
|
236
|
+
return ir.Output(
|
|
237
|
+
node.engine,
|
|
238
|
+
new_aliases,
|
|
239
|
+
new_keys,
|
|
240
|
+
node.annotations,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
def handle_construct(self, node: ir.Construct, parent: ir.Node) -> ir.Construct:
|
|
244
|
+
new_values = tuple(self._get_mapped_values(node.values))
|
|
245
|
+
new_id_var = self.var_mapping.get(node.id_var, node.id_var)
|
|
246
|
+
return ir.Construct(
|
|
247
|
+
node.engine,
|
|
248
|
+
new_values,
|
|
249
|
+
new_id_var,
|
|
250
|
+
node.annotations,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
def handle_aggregate(self, node: ir.Aggregate, parent: ir.Node) -> ir.Aggregate:
|
|
254
|
+
new_projection = tuple(self.var_mapping.get(arg, arg) for arg in node.projection)
|
|
255
|
+
new_group = tuple(self.var_mapping.get(arg, arg) for arg in node.group)
|
|
256
|
+
new_args = tuple(self._get_mapped_values(node.args))
|
|
257
|
+
return ir.Aggregate(
|
|
258
|
+
node.engine,
|
|
259
|
+
node.aggregation,
|
|
260
|
+
new_projection,
|
|
261
|
+
new_group,
|
|
262
|
+
new_args,
|
|
263
|
+
node.annotations,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
def handle_rank(self, node: ir.Rank, parent: ir.Node) -> ir.Rank:
|
|
267
|
+
new_projection = tuple(self.var_mapping.get(arg, arg) for arg in node.projection)
|
|
268
|
+
new_group = tuple(self.var_mapping.get(arg, arg) for arg in node.group)
|
|
269
|
+
new_args = tuple(self.var_mapping.get(arg, arg) for arg in node.args)
|
|
270
|
+
new_result = self.var_mapping.get(node.result, node.result)
|
|
271
|
+
|
|
272
|
+
return ir.Rank(
|
|
273
|
+
node.engine,
|
|
274
|
+
new_projection,
|
|
275
|
+
new_group,
|
|
276
|
+
new_args,
|
|
277
|
+
node.arg_is_ascending,
|
|
278
|
+
new_result,
|
|
279
|
+
node.limit,
|
|
280
|
+
node.annotations,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
var_mapping = self._get_variable_mapping(logical)
|
|
284
|
+
|
|
285
|
+
renamer = RenameVisitor(var_mapping)
|
|
286
|
+
result = renamer.walk(logical)
|
|
287
|
+
|
|
288
|
+
# Also need to append the equality for each renamed constant. E.g., if the mapping
|
|
289
|
+
# contains (50.0::FLOAT -> arg_2::FLOAT), we need to add
|
|
290
|
+
# `eq(arg_2::FLOAT, 50.0::FLOAT)` to the result.
|
|
291
|
+
value_eqs = []
|
|
292
|
+
for (old_var, new_var) in var_mapping.items():
|
|
293
|
+
if not isinstance(old_var, ir.Var):
|
|
294
|
+
value_eqs.append(f.lookup(rel_builtins.eq, [new_var, old_var]))
|
|
295
|
+
|
|
296
|
+
return ir.Logical(
|
|
297
|
+
result.engine,
|
|
298
|
+
result.hoisted,
|
|
299
|
+
tuple(value_eqs) + tuple(result.body),
|
|
300
|
+
result.annotations,
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
# This function is the main workhorse for this rewrite pass. It takes a list of tasks
|
|
304
|
+
# that define the same relation, and combines them into a single task that defines
|
|
305
|
+
# the relation using a union of all of the bodies.
|
|
306
|
+
def _combine_tasks_into_union(self, tasks: list[ir.Logical]) -> ir.Logical:
|
|
307
|
+
# Step 1: Rename the variables in all tasks so that they will match the final derive
|
|
308
|
+
# after reconstructing into a union
|
|
309
|
+
renamed_tasks = [self._rename_variables(task) for task in tasks]
|
|
310
|
+
|
|
311
|
+
# Step 2: Get the final derive
|
|
312
|
+
derives = self._get_heads(renamed_tasks[0])
|
|
313
|
+
assert len(derives) == 1, "should only have one derive in a logical at this stage"
|
|
314
|
+
# Also make sure that all the derives are the same. This should be the case because
|
|
315
|
+
# we renamed all the variables to be the same in step 1.
|
|
316
|
+
for task in renamed_tasks[1:]:
|
|
317
|
+
assert self._get_heads(task) == derives, "all derives should be the same"
|
|
318
|
+
|
|
319
|
+
derive = derives[0]
|
|
320
|
+
|
|
321
|
+
# Step 3: Remove the final `derive` from each task
|
|
322
|
+
renamed_task_bodies = [
|
|
323
|
+
f.logical(
|
|
324
|
+
tuple(self._get_non_heads(t)), # Only keep non-head tasks
|
|
325
|
+
t.hoisted,
|
|
326
|
+
t.engine,
|
|
327
|
+
)
|
|
328
|
+
for t in renamed_tasks
|
|
329
|
+
]
|
|
330
|
+
|
|
331
|
+
# Step 4: Construct a union of all the task bodies
|
|
332
|
+
union = f.union(
|
|
333
|
+
tuple(renamed_task_bodies),
|
|
334
|
+
[],
|
|
335
|
+
renamed_tasks[0].engine,
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
# Step 5: Add the final derive back
|
|
339
|
+
return f.logical(
|
|
340
|
+
(union, derive),
|
|
341
|
+
[],
|
|
342
|
+
renamed_tasks[0].engine,
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
# Creates intermediary relations for all Data nodes and replaces said Data nodes
|
|
346
|
+
# with a Lookup into these created relations. Reuse duplicate created relations.
|
|
347
|
+
class EliminateData(Pass):
|
|
348
|
+
def rewrite(self, model: ir.Model, options:dict={}) -> ir.Model:
|
|
349
|
+
r = self.DataRewriter()
|
|
350
|
+
return r.walk(model)
|
|
351
|
+
|
|
352
|
+
# Does the actual work.
|
|
353
|
+
class DataRewriter(visitor.Rewriter):
|
|
354
|
+
new_relations: list[ir.Relation]
|
|
355
|
+
new_updates: list[ir.Logical]
|
|
356
|
+
# Counter for naming new relations.
|
|
357
|
+
# It must be that new_count == len new_updates == len new_relations.
|
|
358
|
+
new_count: int
|
|
359
|
+
# Cache for Data nodes to avoid creating duplicate intermediary relations
|
|
360
|
+
data_cache: dict[str, ir.Relation]
|
|
361
|
+
|
|
362
|
+
def __init__(self):
|
|
363
|
+
self.new_relations = []
|
|
364
|
+
self.new_updates = []
|
|
365
|
+
self.new_count = 0
|
|
366
|
+
self.data_cache = {}
|
|
367
|
+
super().__init__()
|
|
368
|
+
|
|
369
|
+
# Create a cache key for a Data node based on its structure and content
|
|
370
|
+
def _data_cache_key(self, node: ir.Data) -> str:
|
|
371
|
+
values = pd.util.hash_pandas_object(node.data).values
|
|
372
|
+
return hashlib.sha256(bytes(values)).hexdigest()
|
|
373
|
+
|
|
374
|
+
def _intermediary_relation(self, node: ir.Data) -> ir.Relation:
|
|
375
|
+
cache_key = self._data_cache_key(node)
|
|
376
|
+
if cache_key in self.data_cache:
|
|
377
|
+
return self.data_cache[cache_key]
|
|
378
|
+
self.new_count += 1
|
|
379
|
+
intermediary_name = f"formerly_Data_{self.new_count}"
|
|
380
|
+
|
|
381
|
+
intermediary_relation = f.relation(
|
|
382
|
+
intermediary_name,
|
|
383
|
+
[f.field(v.name, v.type) for v in node.vars]
|
|
384
|
+
)
|
|
385
|
+
self.new_relations.append(intermediary_relation)
|
|
386
|
+
|
|
387
|
+
intermediary_update = f.logical([
|
|
388
|
+
# For each row (union), equate values and their variable (logical).
|
|
389
|
+
f.union(
|
|
390
|
+
[
|
|
391
|
+
f.logical(
|
|
392
|
+
[
|
|
393
|
+
f.lookup(rel_builtins.eq, [f.literal(val), var])
|
|
394
|
+
for (val, var) in zip(row, node.vars)
|
|
395
|
+
],
|
|
396
|
+
)
|
|
397
|
+
for row in node
|
|
398
|
+
],
|
|
399
|
+
hoisted = node.vars,
|
|
400
|
+
),
|
|
401
|
+
# And pop it back into the relation.
|
|
402
|
+
f.update(intermediary_relation, node.vars, ir.Effect.derive),
|
|
403
|
+
])
|
|
404
|
+
self.new_updates.append(intermediary_update)
|
|
405
|
+
|
|
406
|
+
# Cache the result for reuse
|
|
407
|
+
self.data_cache[cache_key] = intermediary_relation
|
|
408
|
+
|
|
409
|
+
return intermediary_relation
|
|
410
|
+
|
|
411
|
+
# Create a new intermediary relation representing the Data (and pop it in
|
|
412
|
+
# new_updates/new_relations) and replace this Data with a Lookup of said
|
|
413
|
+
# intermediary.
|
|
414
|
+
def handle_data(self, node: ir.Data, parent: ir.Node) -> ir.Lookup:
|
|
415
|
+
intermediary_relation = self._intermediary_relation(node)
|
|
416
|
+
replacement_lookup = f.lookup(intermediary_relation, node.vars)
|
|
417
|
+
|
|
418
|
+
return replacement_lookup
|
|
419
|
+
|
|
420
|
+
# Walks the model for the handle_data work then updates the model with
|
|
421
|
+
# the new state.
|
|
422
|
+
def handle_model(self, model: ir.Model, parent: None):
|
|
423
|
+
walked_model = super().handle_model(model, parent)
|
|
424
|
+
assert len(self.new_relations) == len(self.new_updates) and self.new_count == len(self.new_relations)
|
|
425
|
+
|
|
426
|
+
# This is okay because its LQP.
|
|
427
|
+
assert isinstance(walked_model.root, ir.Logical)
|
|
428
|
+
root_logical = cast(ir.Logical, walked_model.root)
|
|
429
|
+
|
|
430
|
+
# We may need to add the new intermediaries from handle_data to the model.
|
|
431
|
+
if self.new_count == 0:
|
|
432
|
+
return model
|
|
433
|
+
else:
|
|
434
|
+
return ir.Model(
|
|
435
|
+
walked_model.engines,
|
|
436
|
+
walked_model.relations | self.new_relations,
|
|
437
|
+
walked_model.types,
|
|
438
|
+
ir.Logical(
|
|
439
|
+
root_logical.engine,
|
|
440
|
+
root_logical.hoisted,
|
|
441
|
+
root_logical.body + tuple(self.new_updates),
|
|
442
|
+
root_logical.annotations,
|
|
443
|
+
),
|
|
444
|
+
walked_model.annotations,
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
# Deduplicate Vars in Updates and Outputs.
|
|
448
|
+
class DeduplicateVars(Pass):
|
|
449
|
+
def rewrite(self, model: ir.Model, options:dict={}) -> ir.Model:
|
|
450
|
+
r = self.VarDeduplicator()
|
|
451
|
+
return r.walk(model)
|
|
452
|
+
|
|
453
|
+
# Return 1) a new list of Values with no duplicates (at the object level) and
|
|
454
|
+
# 2) equalities between any original Value and a deduplicated Value.
|
|
455
|
+
@staticmethod
|
|
456
|
+
def dedup_values(vals: Sequence[ir.Value]) -> Tuple[List[ir.Value], List[ir.Lookup]]:
|
|
457
|
+
# If a var is seen more than once, it is a duplicate and we will create
|
|
458
|
+
# a new Var and equate it with the seen one.
|
|
459
|
+
seen_vars = set()
|
|
460
|
+
|
|
461
|
+
new_vals = []
|
|
462
|
+
eqs = []
|
|
463
|
+
|
|
464
|
+
for i, val in enumerate(vals):
|
|
465
|
+
# Duplicates can only occur within Vars.
|
|
466
|
+
# TODO: we don't know for sure if these are the only relevant cases.
|
|
467
|
+
if isinstance(val, ir.Default) or isinstance(val, ir.Var):
|
|
468
|
+
var = val if isinstance(val, ir.Var) else val.var
|
|
469
|
+
if var in seen_vars:
|
|
470
|
+
new_var = ir.Var(var.type, var.name + "_dup_" + str(i))
|
|
471
|
+
new_val = new_var if isinstance(val, ir.Var) else ir.Default(new_var, val.value)
|
|
472
|
+
new_vals.append(new_val)
|
|
473
|
+
eqs.append(f.lookup(rel_builtins.eq, [new_var, var]))
|
|
474
|
+
else:
|
|
475
|
+
seen_vars.add(var)
|
|
476
|
+
new_vals.append(val)
|
|
477
|
+
else:
|
|
478
|
+
# No possibility of problematic duplication.
|
|
479
|
+
new_vals.append(val)
|
|
480
|
+
|
|
481
|
+
return new_vals, eqs
|
|
482
|
+
|
|
483
|
+
# Returns a reconstructed output with no duplicate variable objects
|
|
484
|
+
# (dedup_values) and now necessary equalities between any two previously
|
|
485
|
+
# duplicate variables.
|
|
486
|
+
@staticmethod
|
|
487
|
+
def dedup_output(output: ir.Output) -> List[Union[ir.Output, ir.Lookup]]:
|
|
488
|
+
vals = helpers.output_values(output.aliases)
|
|
489
|
+
deduped_vals, req_lookups = DeduplicateVars.dedup_values(vals)
|
|
490
|
+
# Need the names so we can recombine.
|
|
491
|
+
alias_names = output_names(output.aliases)
|
|
492
|
+
new_output = ir.Output(
|
|
493
|
+
output.engine,
|
|
494
|
+
FrozenOrderedSet(list(zip(alias_names, deduped_vals))),
|
|
495
|
+
output.keys,
|
|
496
|
+
output.annotations,
|
|
497
|
+
)
|
|
498
|
+
return req_lookups + [new_output]
|
|
499
|
+
|
|
500
|
+
# Returns a replacement update with no duplicate variable objects
|
|
501
|
+
# (dedup_values) and now necessary equalities between any two previously
|
|
502
|
+
# duplicate variables.
|
|
503
|
+
@staticmethod
|
|
504
|
+
def dedup_update(update: ir.Update) -> List[Union[ir.Update, ir.Lookup]]:
|
|
505
|
+
deduped_vals, req_lookups = DeduplicateVars.dedup_values(update.args)
|
|
506
|
+
new_update = ir.Update(
|
|
507
|
+
update.engine,
|
|
508
|
+
update.relation,
|
|
509
|
+
tuple(deduped_vals),
|
|
510
|
+
update.effect,
|
|
511
|
+
update.annotations,
|
|
512
|
+
)
|
|
513
|
+
return req_lookups + [new_update]
|
|
514
|
+
|
|
515
|
+
# Does the actual work.
|
|
516
|
+
class VarDeduplicator(visitor.Rewriter):
|
|
517
|
+
def __init__(self):
|
|
518
|
+
super().__init__()
|
|
519
|
+
|
|
520
|
+
# We implement handle_logical instead of handle_update/handle_output
|
|
521
|
+
# because in addition to modifying said update/output we require new
|
|
522
|
+
# lookups (equality between original and deduplicated variables).
|
|
523
|
+
def handle_logical(self, node: ir.Logical, parent: ir.Node):
|
|
524
|
+
# In order to recurse over subtasks.
|
|
525
|
+
node = super().handle_logical(node, parent)
|
|
526
|
+
|
|
527
|
+
new_body = []
|
|
528
|
+
for subtask in node.body:
|
|
529
|
+
if isinstance(subtask, ir.Output):
|
|
530
|
+
new_body.extend(DeduplicateVars.dedup_output(subtask))
|
|
531
|
+
elif isinstance(subtask, ir.Update):
|
|
532
|
+
new_body.extend(DeduplicateVars.dedup_update(subtask))
|
|
533
|
+
else:
|
|
534
|
+
new_body.append(subtask)
|
|
535
|
+
|
|
536
|
+
return ir.Logical(
|
|
537
|
+
node.engine,
|
|
538
|
+
node.hoisted,
|
|
539
|
+
tuple(new_body),
|
|
540
|
+
node.annotations
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
# Generate date arithmetic expressions, such as
|
|
544
|
+
# `rel_primitive_date_add(:day, [date] delta, res_2)` by finding the period
|
|
545
|
+
# expression for the delta and adding the period type to the date arithmetic expression.
|
|
546
|
+
#
|
|
547
|
+
# date_add and it's kin are generated by a period expression, e.g.,
|
|
548
|
+
# `day(delta, res_1)`
|
|
549
|
+
# followed by the date arithmetic expression using the period
|
|
550
|
+
# `date_add([date] res_1 res_2)`
|
|
551
|
+
class PeriodMath(Pass):
|
|
552
|
+
def rewrite(self, model: ir.Model, options:dict={}) -> ir.Model:
|
|
553
|
+
period_rewriter = self.PeriodRewriter()
|
|
554
|
+
model = period_rewriter.walk(model)
|
|
555
|
+
period_math_rewriter = self.PeriodMathRewriter(period_rewriter.period_vars)
|
|
556
|
+
model = period_math_rewriter.walk(model)
|
|
557
|
+
return model
|
|
558
|
+
|
|
559
|
+
# Find all period builtins. We need to make them safe for the emitter (either by
|
|
560
|
+
# translating to a cast, or removing) and store the variable and period type for use
|
|
561
|
+
# in the date/datetime add/subtract expressions.
|
|
562
|
+
class PeriodRewriter(visitor.Rewriter):
|
|
563
|
+
def __init__(self):
|
|
564
|
+
super().__init__()
|
|
565
|
+
self.period_vars: dict[ir.Var, str] = {}
|
|
566
|
+
|
|
567
|
+
def handle_lookup(self, node: ir.Lookup, parent: ir.Node) -> ir.Lookup:
|
|
568
|
+
if not rel_builtins.is_builtin(node.relation):
|
|
569
|
+
return node
|
|
570
|
+
|
|
571
|
+
if node.relation.name not in {
|
|
572
|
+
"year", "month", "week", "day", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond"
|
|
573
|
+
}:
|
|
574
|
+
return node
|
|
575
|
+
|
|
576
|
+
assert len(node.args) == 2, "Expect 2 arguments for period builtins"
|
|
577
|
+
assert isinstance(node.args[1], ir.Var), "Expect result to be a variable"
|
|
578
|
+
period = node.relation.name
|
|
579
|
+
result_var = node.args[1]
|
|
580
|
+
self.period_vars[result_var] = period
|
|
581
|
+
|
|
582
|
+
# Ideally we could now remove the unused and unhandled period type construction
|
|
583
|
+
# but we may also need to cast the original variable to an Int64 for use by the
|
|
584
|
+
# date/datetime add/subtract expressions.
|
|
585
|
+
# TODO: Remove the node entirely where possible and update uses of the result
|
|
586
|
+
return f.lookup(rel_builtins.cast, [types.Int64, node.args[0], result_var])
|
|
587
|
+
|
|
588
|
+
# Update date/datetime add/subtract expressions with period information.
|
|
589
|
+
class PeriodMathRewriter(visitor.Rewriter):
|
|
590
|
+
def __init__(self, period_vars: dict[ir.Var, str]):
|
|
591
|
+
super().__init__()
|
|
592
|
+
self.period_vars: dict[ir.Var, str] = period_vars
|
|
593
|
+
|
|
594
|
+
def handle_lookup(self, node: ir.Lookup, parent: ir.Node) -> ir.Lookup:
|
|
595
|
+
if not rel_builtins.is_builtin(node.relation):
|
|
596
|
+
return node
|
|
597
|
+
|
|
598
|
+
if node.relation.name not in {
|
|
599
|
+
"date_add", "date_subtract", "datetime_add", "datetime_subtract"
|
|
600
|
+
}:
|
|
601
|
+
return node
|
|
602
|
+
|
|
603
|
+
if len(node.args) == 4:
|
|
604
|
+
# We've already visited this lookup
|
|
605
|
+
return node
|
|
606
|
+
|
|
607
|
+
assert isinstance(node.args[1], ir.Var), "Expect period to be a variable"
|
|
608
|
+
period_var = node.args[1]
|
|
609
|
+
assert period_var in self.period_vars, "datemath found, but no vars to insert"
|
|
610
|
+
|
|
611
|
+
period = self.period_vars[period_var]
|
|
612
|
+
|
|
613
|
+
new_args = [f.literal(period, types.Symbol)] + [arg for arg in node.args]
|
|
614
|
+
|
|
615
|
+
return f.lookup(node.relation, new_args)
|
|
616
|
+
|
|
617
|
+
# Rewrite constants to vars in Updates. This results in a more normalized format where
|
|
618
|
+
# updates contain only variables. This allows for easier rewrites in later passes.
|
|
619
|
+
class ConstantsToVars(Pass):
|
|
620
|
+
def rewrite(self, model: ir.Model, options:dict={}) -> ir.Model:
|
|
621
|
+
r = self.ConstantToVarRewriter()
|
|
622
|
+
return r.walk(model)
|
|
623
|
+
|
|
624
|
+
# Return 1) a new list of Values with no duplicates (at the object level) and
|
|
625
|
+
# 2) equalities between any original Value and a deduplicated Value.
|
|
626
|
+
@staticmethod
|
|
627
|
+
def replace_constants_with_vars(vals: Sequence[ir.Value]) -> Tuple[List[ir.Value], List[ir.Lookup]]:
|
|
628
|
+
new_vals = []
|
|
629
|
+
eqs = []
|
|
630
|
+
|
|
631
|
+
for i, val in enumerate(vals):
|
|
632
|
+
if isinstance(val, ir.PyValue) or isinstance(val, ir.Literal):
|
|
633
|
+
# Replace constant with a new Var.
|
|
634
|
+
typ = typer.to_type(val)
|
|
635
|
+
assert isinstance(typ, ir.ScalarType), "can only replace scalar constants with vars"
|
|
636
|
+
new_var = ir.Var(typ, f"{typ.name.lower()}_{i}")
|
|
637
|
+
new_vals.append(new_var)
|
|
638
|
+
eqs.append(f.lookup(rel_builtins.eq, [new_var, val]))
|
|
639
|
+
else:
|
|
640
|
+
new_vals.append(val)
|
|
641
|
+
|
|
642
|
+
return new_vals, eqs
|
|
643
|
+
|
|
644
|
+
@staticmethod
|
|
645
|
+
def dedup_update(update: ir.Update) -> List[Union[ir.Update, ir.Lookup]]:
|
|
646
|
+
deduped_vals, req_lookups = ConstantsToVars.replace_constants_with_vars(update.args)
|
|
647
|
+
new_update = ir.Update(
|
|
648
|
+
update.engine,
|
|
649
|
+
update.relation,
|
|
650
|
+
tuple(deduped_vals),
|
|
651
|
+
update.effect,
|
|
652
|
+
update.annotations,
|
|
653
|
+
)
|
|
654
|
+
return req_lookups + [new_update]
|
|
655
|
+
|
|
656
|
+
# Does the actual work.
|
|
657
|
+
class ConstantToVarRewriter(visitor.Rewriter):
|
|
658
|
+
def __init__(self):
|
|
659
|
+
super().__init__()
|
|
660
|
+
|
|
661
|
+
# We implement handle_logical instead of handle_update because in
|
|
662
|
+
# addition to modifying said update we require new lookups (equality
|
|
663
|
+
# between original and deduplicated variables).
|
|
664
|
+
def handle_logical(self, node: ir.Logical, parent: ir.Node):
|
|
665
|
+
# In order to recurse over subtasks.
|
|
666
|
+
node = super().handle_logical(node, parent)
|
|
667
|
+
|
|
668
|
+
new_body = []
|
|
669
|
+
for subtask in node.body:
|
|
670
|
+
if isinstance(subtask, ir.Update):
|
|
671
|
+
new_body.extend(ConstantsToVars.dedup_update(subtask))
|
|
672
|
+
else:
|
|
673
|
+
new_body.append(subtask)
|
|
674
|
+
|
|
675
|
+
return ir.Logical(
|
|
676
|
+
node.engine,
|
|
677
|
+
node.hoisted,
|
|
678
|
+
tuple(new_body),
|
|
679
|
+
node.annotations
|
|
680
|
+
)
|