relationalai 0.13.0__py3-none-any.whl → 0.13.0.dev0__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.
Files changed (836) hide show
  1. relationalai/__init__.py +1 -256
  2. relationalai/config/__init__.py +56 -0
  3. relationalai/config/config.py +289 -0
  4. relationalai/config/config_fields.py +86 -0
  5. relationalai/config/connections/__init__.py +46 -0
  6. relationalai/config/connections/base.py +23 -0
  7. relationalai/config/connections/duckdb.py +29 -0
  8. relationalai/config/connections/snowflake.py +243 -0
  9. relationalai/config/external/__init__.py +17 -0
  10. relationalai/config/external/dbt_converter.py +101 -0
  11. relationalai/config/external/dbt_models.py +93 -0
  12. relationalai/config/external/snowflake_converter.py +41 -0
  13. relationalai/config/external/snowflake_models.py +85 -0
  14. relationalai/config/external/utils.py +19 -0
  15. relationalai/semantics/__init__.py +146 -22
  16. relationalai/semantics/backends/lqp/annotations.py +11 -0
  17. relationalai/semantics/backends/sql/sql_compiler.py +327 -0
  18. relationalai/semantics/frontend/base.py +1707 -0
  19. relationalai/semantics/frontend/core.py +179 -0
  20. relationalai/semantics/frontend/front_compiler.py +1313 -0
  21. relationalai/semantics/frontend/pprint.py +408 -0
  22. relationalai/semantics/metamodel/__init__.py +6 -40
  23. relationalai/semantics/metamodel/builtins.py +205 -771
  24. relationalai/semantics/metamodel/metamodel.py +437 -0
  25. relationalai/semantics/metamodel/metamodel_analyzer.py +519 -0
  26. relationalai/semantics/metamodel/pprint.py +412 -0
  27. relationalai/semantics/metamodel/rewriter.py +266 -0
  28. relationalai/semantics/metamodel/typer.py +1378 -0
  29. relationalai/semantics/std/__init__.py +60 -40
  30. relationalai/semantics/std/aggregates.py +149 -0
  31. relationalai/semantics/std/common.py +44 -0
  32. relationalai/semantics/std/constraints.py +37 -43
  33. relationalai/semantics/std/datetime.py +246 -135
  34. relationalai/semantics/std/decimals.py +45 -52
  35. relationalai/semantics/std/floats.py +13 -5
  36. relationalai/semantics/std/integers.py +26 -11
  37. relationalai/semantics/std/math.py +183 -112
  38. relationalai/semantics/std/numbers.py +86 -0
  39. relationalai/semantics/std/re.py +80 -62
  40. relationalai/semantics/std/strings.py +117 -60
  41. relationalai/shims/executor.py +147 -0
  42. relationalai/shims/helpers.py +126 -0
  43. relationalai/shims/hoister.py +221 -0
  44. relationalai/shims/mm2v0.py +1290 -0
  45. relationalai/tools/cli/__init__.py +6 -0
  46. relationalai/tools/cli/cli.py +90 -0
  47. relationalai/tools/cli/components/__init__.py +5 -0
  48. relationalai/tools/cli/components/progress_reader.py +1524 -0
  49. relationalai/tools/cli/components/utils.py +58 -0
  50. relationalai/tools/cli/config_template.py +45 -0
  51. relationalai/tools/cli/dev.py +19 -0
  52. relationalai/tools/debugger.py +289 -183
  53. relationalai/tools/typer_debugger.py +93 -0
  54. relationalai/util/dataclasses.py +43 -0
  55. relationalai/util/docutils.py +40 -0
  56. relationalai/util/error.py +199 -0
  57. relationalai/util/format.py +48 -106
  58. relationalai/util/naming.py +145 -0
  59. relationalai/util/python.py +35 -0
  60. relationalai/util/runtime.py +156 -0
  61. relationalai/util/schema.py +197 -0
  62. relationalai/util/source.py +185 -0
  63. relationalai/util/structures.py +163 -0
  64. relationalai/util/tracing.py +261 -0
  65. relationalai-0.13.0.dev0.dist-info/METADATA +46 -0
  66. relationalai-0.13.0.dev0.dist-info/RECORD +488 -0
  67. relationalai-0.13.0.dev0.dist-info/WHEEL +5 -0
  68. relationalai-0.13.0.dev0.dist-info/entry_points.txt +3 -0
  69. relationalai-0.13.0.dev0.dist-info/top_level.txt +2 -0
  70. v0/relationalai/__init__.py +216 -0
  71. v0/relationalai/clients/__init__.py +5 -0
  72. v0/relationalai/clients/azure.py +477 -0
  73. v0/relationalai/clients/client.py +912 -0
  74. v0/relationalai/clients/config.py +673 -0
  75. v0/relationalai/clients/direct_access_client.py +118 -0
  76. v0/relationalai/clients/hash_util.py +31 -0
  77. v0/relationalai/clients/local.py +571 -0
  78. v0/relationalai/clients/profile_polling.py +73 -0
  79. v0/relationalai/clients/result_helpers.py +420 -0
  80. v0/relationalai/clients/snowflake.py +3869 -0
  81. v0/relationalai/clients/types.py +113 -0
  82. v0/relationalai/clients/use_index_poller.py +980 -0
  83. v0/relationalai/clients/util.py +356 -0
  84. v0/relationalai/debugging.py +389 -0
  85. v0/relationalai/dsl.py +1749 -0
  86. v0/relationalai/early_access/builder/__init__.py +30 -0
  87. v0/relationalai/early_access/builder/builder/__init__.py +35 -0
  88. v0/relationalai/early_access/builder/snowflake/__init__.py +12 -0
  89. v0/relationalai/early_access/builder/std/__init__.py +25 -0
  90. v0/relationalai/early_access/builder/std/decimals/__init__.py +12 -0
  91. v0/relationalai/early_access/builder/std/integers/__init__.py +12 -0
  92. v0/relationalai/early_access/builder/std/math/__init__.py +12 -0
  93. v0/relationalai/early_access/builder/std/strings/__init__.py +14 -0
  94. v0/relationalai/early_access/devtools/__init__.py +12 -0
  95. v0/relationalai/early_access/devtools/benchmark_lqp/__init__.py +12 -0
  96. v0/relationalai/early_access/devtools/extract_lqp/__init__.py +12 -0
  97. v0/relationalai/early_access/dsl/adapters/orm/adapter_qb.py +427 -0
  98. v0/relationalai/early_access/dsl/adapters/orm/parser.py +636 -0
  99. v0/relationalai/early_access/dsl/adapters/owl/adapter.py +176 -0
  100. v0/relationalai/early_access/dsl/adapters/owl/parser.py +160 -0
  101. v0/relationalai/early_access/dsl/bindings/common.py +402 -0
  102. v0/relationalai/early_access/dsl/bindings/csv.py +170 -0
  103. v0/relationalai/early_access/dsl/bindings/legacy/binding_models.py +143 -0
  104. v0/relationalai/early_access/dsl/bindings/snowflake.py +64 -0
  105. v0/relationalai/early_access/dsl/codegen/binder.py +411 -0
  106. v0/relationalai/early_access/dsl/codegen/common.py +79 -0
  107. v0/relationalai/early_access/dsl/codegen/helpers.py +23 -0
  108. v0/relationalai/early_access/dsl/codegen/relations.py +700 -0
  109. v0/relationalai/early_access/dsl/codegen/weaver.py +417 -0
  110. v0/relationalai/early_access/dsl/core/builders/__init__.py +47 -0
  111. v0/relationalai/early_access/dsl/core/builders/logic.py +19 -0
  112. v0/relationalai/early_access/dsl/core/builders/scalar_constraint.py +11 -0
  113. v0/relationalai/early_access/dsl/core/constraints/predicate/atomic.py +455 -0
  114. v0/relationalai/early_access/dsl/core/constraints/predicate/universal.py +73 -0
  115. v0/relationalai/early_access/dsl/core/constraints/scalar.py +310 -0
  116. v0/relationalai/early_access/dsl/core/context.py +13 -0
  117. v0/relationalai/early_access/dsl/core/cset.py +132 -0
  118. v0/relationalai/early_access/dsl/core/exprs/__init__.py +116 -0
  119. v0/relationalai/early_access/dsl/core/exprs/relational.py +18 -0
  120. v0/relationalai/early_access/dsl/core/exprs/scalar.py +412 -0
  121. v0/relationalai/early_access/dsl/core/instances.py +44 -0
  122. v0/relationalai/early_access/dsl/core/logic/__init__.py +193 -0
  123. v0/relationalai/early_access/dsl/core/logic/aggregation.py +98 -0
  124. v0/relationalai/early_access/dsl/core/logic/exists.py +223 -0
  125. v0/relationalai/early_access/dsl/core/logic/helper.py +163 -0
  126. v0/relationalai/early_access/dsl/core/namespaces.py +32 -0
  127. v0/relationalai/early_access/dsl/core/relations.py +276 -0
  128. v0/relationalai/early_access/dsl/core/rules.py +112 -0
  129. v0/relationalai/early_access/dsl/core/std/__init__.py +45 -0
  130. v0/relationalai/early_access/dsl/core/temporal/recall.py +6 -0
  131. v0/relationalai/early_access/dsl/core/types/__init__.py +270 -0
  132. v0/relationalai/early_access/dsl/core/types/concepts.py +128 -0
  133. v0/relationalai/early_access/dsl/core/types/constrained/__init__.py +267 -0
  134. v0/relationalai/early_access/dsl/core/types/constrained/nominal.py +143 -0
  135. v0/relationalai/early_access/dsl/core/types/constrained/subtype.py +124 -0
  136. v0/relationalai/early_access/dsl/core/types/standard.py +92 -0
  137. v0/relationalai/early_access/dsl/core/types/unconstrained.py +50 -0
  138. v0/relationalai/early_access/dsl/core/types/variables.py +203 -0
  139. v0/relationalai/early_access/dsl/ir/compiler.py +318 -0
  140. v0/relationalai/early_access/dsl/ir/executor.py +260 -0
  141. v0/relationalai/early_access/dsl/ontologies/constraints.py +88 -0
  142. v0/relationalai/early_access/dsl/ontologies/export.py +30 -0
  143. v0/relationalai/early_access/dsl/ontologies/models.py +453 -0
  144. v0/relationalai/early_access/dsl/ontologies/python_printer.py +303 -0
  145. v0/relationalai/early_access/dsl/ontologies/readings.py +60 -0
  146. v0/relationalai/early_access/dsl/ontologies/relationships.py +322 -0
  147. v0/relationalai/early_access/dsl/ontologies/roles.py +87 -0
  148. v0/relationalai/early_access/dsl/ontologies/subtyping.py +55 -0
  149. v0/relationalai/early_access/dsl/orm/constraints.py +438 -0
  150. v0/relationalai/early_access/dsl/orm/measures/dimensions.py +200 -0
  151. v0/relationalai/early_access/dsl/orm/measures/initializer.py +16 -0
  152. v0/relationalai/early_access/dsl/orm/measures/measure_rules.py +275 -0
  153. v0/relationalai/early_access/dsl/orm/measures/measures.py +299 -0
  154. v0/relationalai/early_access/dsl/orm/measures/role_exprs.py +268 -0
  155. v0/relationalai/early_access/dsl/orm/models.py +256 -0
  156. v0/relationalai/early_access/dsl/orm/object_oriented_printer.py +344 -0
  157. v0/relationalai/early_access/dsl/orm/printer.py +469 -0
  158. v0/relationalai/early_access/dsl/orm/reasoners.py +480 -0
  159. v0/relationalai/early_access/dsl/orm/relations.py +19 -0
  160. v0/relationalai/early_access/dsl/orm/relationships.py +251 -0
  161. v0/relationalai/early_access/dsl/orm/types.py +42 -0
  162. v0/relationalai/early_access/dsl/orm/utils.py +79 -0
  163. v0/relationalai/early_access/dsl/orm/verb.py +204 -0
  164. v0/relationalai/early_access/dsl/physical_metadata/tables.py +133 -0
  165. v0/relationalai/early_access/dsl/relations.py +170 -0
  166. v0/relationalai/early_access/dsl/rulesets.py +69 -0
  167. v0/relationalai/early_access/dsl/schemas/__init__.py +450 -0
  168. v0/relationalai/early_access/dsl/schemas/builder.py +48 -0
  169. v0/relationalai/early_access/dsl/schemas/comp_names.py +51 -0
  170. v0/relationalai/early_access/dsl/schemas/components.py +203 -0
  171. v0/relationalai/early_access/dsl/schemas/contexts.py +156 -0
  172. v0/relationalai/early_access/dsl/schemas/exprs.py +89 -0
  173. v0/relationalai/early_access/dsl/schemas/fragments.py +464 -0
  174. v0/relationalai/early_access/dsl/serialization.py +79 -0
  175. v0/relationalai/early_access/dsl/serialize/exporter.py +163 -0
  176. v0/relationalai/early_access/dsl/snow/api.py +104 -0
  177. v0/relationalai/early_access/dsl/snow/common.py +76 -0
  178. v0/relationalai/early_access/dsl/state_mgmt/__init__.py +129 -0
  179. v0/relationalai/early_access/dsl/state_mgmt/state_charts.py +125 -0
  180. v0/relationalai/early_access/dsl/state_mgmt/transitions.py +130 -0
  181. v0/relationalai/early_access/dsl/types/__init__.py +40 -0
  182. v0/relationalai/early_access/dsl/types/concepts.py +12 -0
  183. v0/relationalai/early_access/dsl/types/entities.py +135 -0
  184. v0/relationalai/early_access/dsl/types/values.py +17 -0
  185. v0/relationalai/early_access/dsl/utils.py +102 -0
  186. v0/relationalai/early_access/graphs/__init__.py +13 -0
  187. v0/relationalai/early_access/lqp/__init__.py +12 -0
  188. v0/relationalai/early_access/lqp/compiler/__init__.py +12 -0
  189. v0/relationalai/early_access/lqp/constructors/__init__.py +18 -0
  190. v0/relationalai/early_access/lqp/executor/__init__.py +12 -0
  191. v0/relationalai/early_access/lqp/ir/__init__.py +12 -0
  192. v0/relationalai/early_access/lqp/passes/__init__.py +12 -0
  193. v0/relationalai/early_access/lqp/pragmas/__init__.py +12 -0
  194. v0/relationalai/early_access/lqp/primitives/__init__.py +12 -0
  195. v0/relationalai/early_access/lqp/types/__init__.py +12 -0
  196. v0/relationalai/early_access/lqp/utils/__init__.py +12 -0
  197. v0/relationalai/early_access/lqp/validators/__init__.py +12 -0
  198. v0/relationalai/early_access/metamodel/__init__.py +58 -0
  199. v0/relationalai/early_access/metamodel/builtins/__init__.py +12 -0
  200. v0/relationalai/early_access/metamodel/compiler/__init__.py +12 -0
  201. v0/relationalai/early_access/metamodel/dependency/__init__.py +12 -0
  202. v0/relationalai/early_access/metamodel/factory/__init__.py +17 -0
  203. v0/relationalai/early_access/metamodel/helpers/__init__.py +12 -0
  204. v0/relationalai/early_access/metamodel/ir/__init__.py +14 -0
  205. v0/relationalai/early_access/metamodel/rewrite/__init__.py +7 -0
  206. v0/relationalai/early_access/metamodel/typer/__init__.py +3 -0
  207. v0/relationalai/early_access/metamodel/typer/typer/__init__.py +12 -0
  208. v0/relationalai/early_access/metamodel/types/__init__.py +15 -0
  209. v0/relationalai/early_access/metamodel/util/__init__.py +15 -0
  210. v0/relationalai/early_access/metamodel/visitor/__init__.py +12 -0
  211. v0/relationalai/early_access/rel/__init__.py +12 -0
  212. v0/relationalai/early_access/rel/executor/__init__.py +12 -0
  213. v0/relationalai/early_access/rel/rel_utils/__init__.py +12 -0
  214. v0/relationalai/early_access/rel/rewrite/__init__.py +7 -0
  215. v0/relationalai/early_access/solvers/__init__.py +19 -0
  216. v0/relationalai/early_access/sql/__init__.py +11 -0
  217. v0/relationalai/early_access/sql/executor/__init__.py +3 -0
  218. v0/relationalai/early_access/sql/rewrite/__init__.py +3 -0
  219. v0/relationalai/early_access/tests/logging/__init__.py +12 -0
  220. v0/relationalai/early_access/tests/test_snapshot_base/__init__.py +12 -0
  221. v0/relationalai/early_access/tests/utils/__init__.py +12 -0
  222. v0/relationalai/environments/__init__.py +35 -0
  223. v0/relationalai/environments/base.py +381 -0
  224. v0/relationalai/environments/colab.py +14 -0
  225. v0/relationalai/environments/generic.py +71 -0
  226. v0/relationalai/environments/ipython.py +68 -0
  227. v0/relationalai/environments/jupyter.py +9 -0
  228. v0/relationalai/environments/snowbook.py +169 -0
  229. v0/relationalai/errors.py +2455 -0
  230. v0/relationalai/experimental/SF.py +38 -0
  231. v0/relationalai/experimental/inspect.py +47 -0
  232. v0/relationalai/experimental/pathfinder/__init__.py +158 -0
  233. v0/relationalai/experimental/pathfinder/api.py +160 -0
  234. v0/relationalai/experimental/pathfinder/automaton.py +584 -0
  235. v0/relationalai/experimental/pathfinder/bridge.py +226 -0
  236. v0/relationalai/experimental/pathfinder/compiler.py +416 -0
  237. v0/relationalai/experimental/pathfinder/datalog.py +214 -0
  238. v0/relationalai/experimental/pathfinder/diagnostics.py +56 -0
  239. v0/relationalai/experimental/pathfinder/filter.py +236 -0
  240. v0/relationalai/experimental/pathfinder/glushkov.py +439 -0
  241. v0/relationalai/experimental/pathfinder/options.py +265 -0
  242. v0/relationalai/experimental/pathfinder/rpq.py +344 -0
  243. v0/relationalai/experimental/pathfinder/transition.py +200 -0
  244. v0/relationalai/experimental/pathfinder/utils.py +26 -0
  245. v0/relationalai/experimental/paths/api.py +143 -0
  246. v0/relationalai/experimental/paths/benchmarks/grid_graph.py +37 -0
  247. v0/relationalai/experimental/paths/examples/basic_example.py +40 -0
  248. v0/relationalai/experimental/paths/examples/minimal_engine_warmup.py +3 -0
  249. v0/relationalai/experimental/paths/examples/movie_example.py +77 -0
  250. v0/relationalai/experimental/paths/examples/paths_benchmark.py +115 -0
  251. v0/relationalai/experimental/paths/examples/paths_example.py +116 -0
  252. v0/relationalai/experimental/paths/examples/pattern_to_automaton.py +28 -0
  253. v0/relationalai/experimental/paths/find_paths_via_automaton.py +85 -0
  254. v0/relationalai/experimental/paths/graph.py +185 -0
  255. v0/relationalai/experimental/paths/path_algorithms/find_paths.py +280 -0
  256. v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +26 -0
  257. v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +111 -0
  258. v0/relationalai/experimental/paths/path_algorithms/single.py +59 -0
  259. v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +39 -0
  260. v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +103 -0
  261. v0/relationalai/experimental/paths/path_algorithms/usp-old.py +130 -0
  262. v0/relationalai/experimental/paths/path_algorithms/usp-tuple.py +183 -0
  263. v0/relationalai/experimental/paths/path_algorithms/usp.py +150 -0
  264. v0/relationalai/experimental/paths/product_graph.py +93 -0
  265. v0/relationalai/experimental/paths/rpq/automaton.py +584 -0
  266. v0/relationalai/experimental/paths/rpq/diagnostics.py +56 -0
  267. v0/relationalai/experimental/paths/rpq/rpq.py +378 -0
  268. v0/relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +90 -0
  269. v0/relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +119 -0
  270. v0/relationalai/experimental/paths/tests/tests_limit_sp_single.py +104 -0
  271. v0/relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +113 -0
  272. v0/relationalai/experimental/paths/tests/tests_limit_walks_single.py +149 -0
  273. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +70 -0
  274. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +64 -0
  275. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +115 -0
  276. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +75 -0
  277. v0/relationalai/experimental/paths/tests/tests_single_paths.py +152 -0
  278. v0/relationalai/experimental/paths/tests/tests_single_walks.py +208 -0
  279. v0/relationalai/experimental/paths/tests/tests_single_walks_undirected.py +297 -0
  280. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +107 -0
  281. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +76 -0
  282. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +76 -0
  283. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +110 -0
  284. v0/relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +229 -0
  285. v0/relationalai/experimental/paths/tests/tests_usp_nsp_single.py +108 -0
  286. v0/relationalai/experimental/paths/tree_agg.py +168 -0
  287. v0/relationalai/experimental/paths/utilities/iterators.py +27 -0
  288. v0/relationalai/experimental/paths/utilities/prefix_sum.py +91 -0
  289. v0/relationalai/experimental/solvers.py +1087 -0
  290. v0/relationalai/loaders/__init__.py +0 -0
  291. v0/relationalai/loaders/csv.py +195 -0
  292. v0/relationalai/loaders/loader.py +177 -0
  293. v0/relationalai/loaders/types.py +23 -0
  294. v0/relationalai/rel_emitter.py +373 -0
  295. v0/relationalai/rel_utils.py +185 -0
  296. v0/relationalai/semantics/__init__.py +29 -0
  297. v0/relationalai/semantics/devtools/benchmark_lqp.py +536 -0
  298. v0/relationalai/semantics/devtools/compilation_manager.py +294 -0
  299. v0/relationalai/semantics/devtools/extract_lqp.py +110 -0
  300. v0/relationalai/semantics/internal/internal.py +3785 -0
  301. v0/relationalai/semantics/internal/snowflake.py +324 -0
  302. v0/relationalai/semantics/lqp/builtins.py +16 -0
  303. v0/relationalai/semantics/lqp/compiler.py +22 -0
  304. v0/relationalai/semantics/lqp/constructors.py +68 -0
  305. v0/relationalai/semantics/lqp/executor.py +469 -0
  306. v0/relationalai/semantics/lqp/intrinsics.py +24 -0
  307. v0/relationalai/semantics/lqp/model2lqp.py +839 -0
  308. v0/relationalai/semantics/lqp/passes.py +680 -0
  309. v0/relationalai/semantics/lqp/primitives.py +252 -0
  310. v0/relationalai/semantics/lqp/result_helpers.py +202 -0
  311. v0/relationalai/semantics/lqp/rewrite/annotate_constraints.py +57 -0
  312. v0/relationalai/semantics/lqp/rewrite/cdc.py +216 -0
  313. v0/relationalai/semantics/lqp/rewrite/extract_common.py +338 -0
  314. v0/relationalai/semantics/lqp/rewrite/extract_keys.py +449 -0
  315. v0/relationalai/semantics/lqp/rewrite/function_annotations.py +114 -0
  316. v0/relationalai/semantics/lqp/rewrite/functional_dependencies.py +314 -0
  317. v0/relationalai/semantics/lqp/rewrite/quantify_vars.py +296 -0
  318. v0/relationalai/semantics/lqp/rewrite/splinter.py +76 -0
  319. v0/relationalai/semantics/lqp/types.py +101 -0
  320. v0/relationalai/semantics/lqp/utils.py +160 -0
  321. v0/relationalai/semantics/lqp/validators.py +57 -0
  322. v0/relationalai/semantics/metamodel/__init__.py +40 -0
  323. v0/relationalai/semantics/metamodel/builtins.py +774 -0
  324. v0/relationalai/semantics/metamodel/compiler.py +133 -0
  325. v0/relationalai/semantics/metamodel/dependency.py +862 -0
  326. v0/relationalai/semantics/metamodel/executor.py +61 -0
  327. v0/relationalai/semantics/metamodel/factory.py +287 -0
  328. v0/relationalai/semantics/metamodel/helpers.py +361 -0
  329. v0/relationalai/semantics/metamodel/rewrite/discharge_constraints.py +39 -0
  330. v0/relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +210 -0
  331. v0/relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +78 -0
  332. v0/relationalai/semantics/metamodel/rewrite/flatten.py +549 -0
  333. v0/relationalai/semantics/metamodel/rewrite/format_outputs.py +165 -0
  334. v0/relationalai/semantics/metamodel/typer/checker.py +353 -0
  335. v0/relationalai/semantics/metamodel/typer/typer.py +1395 -0
  336. v0/relationalai/semantics/metamodel/util.py +505 -0
  337. v0/relationalai/semantics/reasoners/__init__.py +10 -0
  338. v0/relationalai/semantics/reasoners/graph/__init__.py +37 -0
  339. v0/relationalai/semantics/reasoners/graph/core.py +9020 -0
  340. v0/relationalai/semantics/reasoners/optimization/__init__.py +68 -0
  341. v0/relationalai/semantics/reasoners/optimization/common.py +88 -0
  342. v0/relationalai/semantics/reasoners/optimization/solvers_dev.py +568 -0
  343. v0/relationalai/semantics/reasoners/optimization/solvers_pb.py +1163 -0
  344. v0/relationalai/semantics/rel/builtins.py +40 -0
  345. v0/relationalai/semantics/rel/compiler.py +989 -0
  346. v0/relationalai/semantics/rel/executor.py +359 -0
  347. v0/relationalai/semantics/rel/rel.py +482 -0
  348. v0/relationalai/semantics/rel/rel_utils.py +276 -0
  349. v0/relationalai/semantics/snowflake/__init__.py +3 -0
  350. v0/relationalai/semantics/sql/compiler.py +2503 -0
  351. v0/relationalai/semantics/sql/executor/duck_db.py +52 -0
  352. v0/relationalai/semantics/sql/executor/result_helpers.py +64 -0
  353. v0/relationalai/semantics/sql/executor/snowflake.py +145 -0
  354. v0/relationalai/semantics/sql/rewrite/denormalize.py +222 -0
  355. v0/relationalai/semantics/sql/rewrite/double_negation.py +49 -0
  356. v0/relationalai/semantics/sql/rewrite/recursive_union.py +127 -0
  357. v0/relationalai/semantics/sql/rewrite/sort_output_query.py +246 -0
  358. v0/relationalai/semantics/sql/sql.py +504 -0
  359. v0/relationalai/semantics/std/__init__.py +54 -0
  360. v0/relationalai/semantics/std/constraints.py +43 -0
  361. v0/relationalai/semantics/std/datetime.py +363 -0
  362. v0/relationalai/semantics/std/decimals.py +62 -0
  363. v0/relationalai/semantics/std/floats.py +7 -0
  364. v0/relationalai/semantics/std/integers.py +22 -0
  365. v0/relationalai/semantics/std/math.py +141 -0
  366. v0/relationalai/semantics/std/pragmas.py +11 -0
  367. v0/relationalai/semantics/std/re.py +83 -0
  368. v0/relationalai/semantics/std/std.py +14 -0
  369. v0/relationalai/semantics/std/strings.py +63 -0
  370. v0/relationalai/semantics/tests/__init__.py +0 -0
  371. v0/relationalai/semantics/tests/test_snapshot_abstract.py +143 -0
  372. v0/relationalai/semantics/tests/test_snapshot_base.py +9 -0
  373. v0/relationalai/semantics/tests/utils.py +46 -0
  374. v0/relationalai/std/__init__.py +70 -0
  375. v0/relationalai/tools/__init__.py +0 -0
  376. v0/relationalai/tools/cli.py +1940 -0
  377. v0/relationalai/tools/cli_controls.py +1826 -0
  378. v0/relationalai/tools/cli_helpers.py +390 -0
  379. v0/relationalai/tools/debugger.py +183 -0
  380. v0/relationalai/tools/debugger_client.py +109 -0
  381. v0/relationalai/tools/debugger_server.py +302 -0
  382. v0/relationalai/tools/dev.py +685 -0
  383. v0/relationalai/tools/qb_debugger.py +425 -0
  384. v0/relationalai/util/clean_up_databases.py +95 -0
  385. v0/relationalai/util/format.py +123 -0
  386. v0/relationalai/util/list_databases.py +9 -0
  387. v0/relationalai/util/otel_configuration.py +25 -0
  388. v0/relationalai/util/otel_handler.py +484 -0
  389. v0/relationalai/util/snowflake_handler.py +88 -0
  390. v0/relationalai/util/span_format_test.py +43 -0
  391. v0/relationalai/util/span_tracker.py +207 -0
  392. v0/relationalai/util/spans_file_handler.py +72 -0
  393. v0/relationalai/util/tracing_handler.py +34 -0
  394. frontend/debugger/dist/.gitignore +0 -2
  395. frontend/debugger/dist/assets/favicon-Dy0ZgA6N.png +0 -0
  396. frontend/debugger/dist/assets/index-Cssla-O7.js +0 -208
  397. frontend/debugger/dist/assets/index-DlHsYx1V.css +0 -9
  398. frontend/debugger/dist/index.html +0 -17
  399. relationalai/clients/__init__.py +0 -18
  400. relationalai/clients/client.py +0 -912
  401. relationalai/clients/config.py +0 -673
  402. relationalai/clients/direct_access_client.py +0 -118
  403. relationalai/clients/hash_util.py +0 -31
  404. relationalai/clients/local.py +0 -571
  405. relationalai/clients/profile_polling.py +0 -73
  406. relationalai/clients/resources/__init__.py +0 -8
  407. relationalai/clients/resources/azure/azure.py +0 -477
  408. relationalai/clients/resources/snowflake/__init__.py +0 -20
  409. relationalai/clients/resources/snowflake/cli_resources.py +0 -87
  410. relationalai/clients/resources/snowflake/direct_access_resources.py +0 -711
  411. relationalai/clients/resources/snowflake/engine_state_handlers.py +0 -309
  412. relationalai/clients/resources/snowflake/error_handlers.py +0 -199
  413. relationalai/clients/resources/snowflake/export_procedure.py.jinja +0 -249
  414. relationalai/clients/resources/snowflake/resources_factory.py +0 -99
  415. relationalai/clients/resources/snowflake/snowflake.py +0 -3083
  416. relationalai/clients/resources/snowflake/use_index_poller.py +0 -1011
  417. relationalai/clients/resources/snowflake/use_index_resources.py +0 -188
  418. relationalai/clients/resources/snowflake/util.py +0 -387
  419. relationalai/clients/result_helpers.py +0 -420
  420. relationalai/clients/types.py +0 -113
  421. relationalai/clients/util.py +0 -356
  422. relationalai/debugging.py +0 -389
  423. relationalai/dsl.py +0 -1749
  424. relationalai/early_access/builder/__init__.py +0 -30
  425. relationalai/early_access/builder/builder/__init__.py +0 -35
  426. relationalai/early_access/builder/snowflake/__init__.py +0 -12
  427. relationalai/early_access/builder/std/__init__.py +0 -25
  428. relationalai/early_access/builder/std/decimals/__init__.py +0 -12
  429. relationalai/early_access/builder/std/integers/__init__.py +0 -12
  430. relationalai/early_access/builder/std/math/__init__.py +0 -12
  431. relationalai/early_access/builder/std/strings/__init__.py +0 -14
  432. relationalai/early_access/devtools/__init__.py +0 -12
  433. relationalai/early_access/devtools/benchmark_lqp/__init__.py +0 -12
  434. relationalai/early_access/devtools/extract_lqp/__init__.py +0 -12
  435. relationalai/early_access/dsl/adapters/orm/adapter_qb.py +0 -427
  436. relationalai/early_access/dsl/adapters/orm/parser.py +0 -636
  437. relationalai/early_access/dsl/adapters/owl/adapter.py +0 -176
  438. relationalai/early_access/dsl/adapters/owl/parser.py +0 -160
  439. relationalai/early_access/dsl/bindings/common.py +0 -402
  440. relationalai/early_access/dsl/bindings/csv.py +0 -170
  441. relationalai/early_access/dsl/bindings/legacy/binding_models.py +0 -143
  442. relationalai/early_access/dsl/bindings/snowflake.py +0 -64
  443. relationalai/early_access/dsl/codegen/binder.py +0 -411
  444. relationalai/early_access/dsl/codegen/common.py +0 -79
  445. relationalai/early_access/dsl/codegen/helpers.py +0 -23
  446. relationalai/early_access/dsl/codegen/relations.py +0 -700
  447. relationalai/early_access/dsl/codegen/weaver.py +0 -417
  448. relationalai/early_access/dsl/core/builders/__init__.py +0 -47
  449. relationalai/early_access/dsl/core/builders/logic.py +0 -19
  450. relationalai/early_access/dsl/core/builders/scalar_constraint.py +0 -11
  451. relationalai/early_access/dsl/core/constraints/predicate/atomic.py +0 -455
  452. relationalai/early_access/dsl/core/constraints/predicate/universal.py +0 -73
  453. relationalai/early_access/dsl/core/constraints/scalar.py +0 -310
  454. relationalai/early_access/dsl/core/context.py +0 -13
  455. relationalai/early_access/dsl/core/cset.py +0 -132
  456. relationalai/early_access/dsl/core/exprs/__init__.py +0 -116
  457. relationalai/early_access/dsl/core/exprs/relational.py +0 -18
  458. relationalai/early_access/dsl/core/exprs/scalar.py +0 -412
  459. relationalai/early_access/dsl/core/instances.py +0 -44
  460. relationalai/early_access/dsl/core/logic/__init__.py +0 -193
  461. relationalai/early_access/dsl/core/logic/aggregation.py +0 -98
  462. relationalai/early_access/dsl/core/logic/exists.py +0 -223
  463. relationalai/early_access/dsl/core/logic/helper.py +0 -163
  464. relationalai/early_access/dsl/core/namespaces.py +0 -32
  465. relationalai/early_access/dsl/core/relations.py +0 -276
  466. relationalai/early_access/dsl/core/rules.py +0 -112
  467. relationalai/early_access/dsl/core/std/__init__.py +0 -45
  468. relationalai/early_access/dsl/core/temporal/recall.py +0 -6
  469. relationalai/early_access/dsl/core/types/__init__.py +0 -270
  470. relationalai/early_access/dsl/core/types/concepts.py +0 -128
  471. relationalai/early_access/dsl/core/types/constrained/__init__.py +0 -267
  472. relationalai/early_access/dsl/core/types/constrained/nominal.py +0 -143
  473. relationalai/early_access/dsl/core/types/constrained/subtype.py +0 -124
  474. relationalai/early_access/dsl/core/types/standard.py +0 -92
  475. relationalai/early_access/dsl/core/types/unconstrained.py +0 -50
  476. relationalai/early_access/dsl/core/types/variables.py +0 -203
  477. relationalai/early_access/dsl/ir/compiler.py +0 -318
  478. relationalai/early_access/dsl/ir/executor.py +0 -260
  479. relationalai/early_access/dsl/ontologies/constraints.py +0 -88
  480. relationalai/early_access/dsl/ontologies/export.py +0 -30
  481. relationalai/early_access/dsl/ontologies/models.py +0 -453
  482. relationalai/early_access/dsl/ontologies/python_printer.py +0 -303
  483. relationalai/early_access/dsl/ontologies/readings.py +0 -60
  484. relationalai/early_access/dsl/ontologies/relationships.py +0 -322
  485. relationalai/early_access/dsl/ontologies/roles.py +0 -87
  486. relationalai/early_access/dsl/ontologies/subtyping.py +0 -55
  487. relationalai/early_access/dsl/orm/constraints.py +0 -438
  488. relationalai/early_access/dsl/orm/measures/dimensions.py +0 -200
  489. relationalai/early_access/dsl/orm/measures/initializer.py +0 -16
  490. relationalai/early_access/dsl/orm/measures/measure_rules.py +0 -275
  491. relationalai/early_access/dsl/orm/measures/measures.py +0 -299
  492. relationalai/early_access/dsl/orm/measures/role_exprs.py +0 -268
  493. relationalai/early_access/dsl/orm/models.py +0 -256
  494. relationalai/early_access/dsl/orm/object_oriented_printer.py +0 -344
  495. relationalai/early_access/dsl/orm/printer.py +0 -469
  496. relationalai/early_access/dsl/orm/reasoners.py +0 -480
  497. relationalai/early_access/dsl/orm/relations.py +0 -19
  498. relationalai/early_access/dsl/orm/relationships.py +0 -251
  499. relationalai/early_access/dsl/orm/types.py +0 -42
  500. relationalai/early_access/dsl/orm/utils.py +0 -79
  501. relationalai/early_access/dsl/orm/verb.py +0 -204
  502. relationalai/early_access/dsl/physical_metadata/tables.py +0 -133
  503. relationalai/early_access/dsl/relations.py +0 -170
  504. relationalai/early_access/dsl/rulesets.py +0 -69
  505. relationalai/early_access/dsl/schemas/__init__.py +0 -450
  506. relationalai/early_access/dsl/schemas/builder.py +0 -48
  507. relationalai/early_access/dsl/schemas/comp_names.py +0 -51
  508. relationalai/early_access/dsl/schemas/components.py +0 -203
  509. relationalai/early_access/dsl/schemas/contexts.py +0 -156
  510. relationalai/early_access/dsl/schemas/exprs.py +0 -89
  511. relationalai/early_access/dsl/schemas/fragments.py +0 -464
  512. relationalai/early_access/dsl/serialization.py +0 -79
  513. relationalai/early_access/dsl/serialize/exporter.py +0 -163
  514. relationalai/early_access/dsl/snow/api.py +0 -105
  515. relationalai/early_access/dsl/snow/common.py +0 -76
  516. relationalai/early_access/dsl/state_mgmt/__init__.py +0 -129
  517. relationalai/early_access/dsl/state_mgmt/state_charts.py +0 -125
  518. relationalai/early_access/dsl/state_mgmt/transitions.py +0 -130
  519. relationalai/early_access/dsl/types/__init__.py +0 -40
  520. relationalai/early_access/dsl/types/concepts.py +0 -12
  521. relationalai/early_access/dsl/types/entities.py +0 -135
  522. relationalai/early_access/dsl/types/values.py +0 -17
  523. relationalai/early_access/dsl/utils.py +0 -102
  524. relationalai/early_access/graphs/__init__.py +0 -13
  525. relationalai/early_access/lqp/__init__.py +0 -12
  526. relationalai/early_access/lqp/compiler/__init__.py +0 -12
  527. relationalai/early_access/lqp/constructors/__init__.py +0 -18
  528. relationalai/early_access/lqp/executor/__init__.py +0 -12
  529. relationalai/early_access/lqp/ir/__init__.py +0 -12
  530. relationalai/early_access/lqp/passes/__init__.py +0 -12
  531. relationalai/early_access/lqp/pragmas/__init__.py +0 -12
  532. relationalai/early_access/lqp/primitives/__init__.py +0 -12
  533. relationalai/early_access/lqp/types/__init__.py +0 -12
  534. relationalai/early_access/lqp/utils/__init__.py +0 -12
  535. relationalai/early_access/lqp/validators/__init__.py +0 -12
  536. relationalai/early_access/metamodel/__init__.py +0 -58
  537. relationalai/early_access/metamodel/builtins/__init__.py +0 -12
  538. relationalai/early_access/metamodel/compiler/__init__.py +0 -12
  539. relationalai/early_access/metamodel/dependency/__init__.py +0 -12
  540. relationalai/early_access/metamodel/factory/__init__.py +0 -17
  541. relationalai/early_access/metamodel/helpers/__init__.py +0 -12
  542. relationalai/early_access/metamodel/ir/__init__.py +0 -14
  543. relationalai/early_access/metamodel/rewrite/__init__.py +0 -7
  544. relationalai/early_access/metamodel/typer/__init__.py +0 -3
  545. relationalai/early_access/metamodel/typer/typer/__init__.py +0 -12
  546. relationalai/early_access/metamodel/types/__init__.py +0 -15
  547. relationalai/early_access/metamodel/util/__init__.py +0 -15
  548. relationalai/early_access/metamodel/visitor/__init__.py +0 -12
  549. relationalai/early_access/rel/__init__.py +0 -12
  550. relationalai/early_access/rel/executor/__init__.py +0 -12
  551. relationalai/early_access/rel/rel_utils/__init__.py +0 -12
  552. relationalai/early_access/rel/rewrite/__init__.py +0 -7
  553. relationalai/early_access/solvers/__init__.py +0 -19
  554. relationalai/early_access/sql/__init__.py +0 -11
  555. relationalai/early_access/sql/executor/__init__.py +0 -3
  556. relationalai/early_access/sql/rewrite/__init__.py +0 -3
  557. relationalai/early_access/tests/logging/__init__.py +0 -12
  558. relationalai/early_access/tests/test_snapshot_base/__init__.py +0 -12
  559. relationalai/early_access/tests/utils/__init__.py +0 -12
  560. relationalai/environments/__init__.py +0 -35
  561. relationalai/environments/base.py +0 -381
  562. relationalai/environments/colab.py +0 -14
  563. relationalai/environments/generic.py +0 -71
  564. relationalai/environments/ipython.py +0 -68
  565. relationalai/environments/jupyter.py +0 -9
  566. relationalai/environments/snowbook.py +0 -169
  567. relationalai/errors.py +0 -2478
  568. relationalai/experimental/SF.py +0 -38
  569. relationalai/experimental/inspect.py +0 -47
  570. relationalai/experimental/pathfinder/__init__.py +0 -158
  571. relationalai/experimental/pathfinder/api.py +0 -160
  572. relationalai/experimental/pathfinder/automaton.py +0 -584
  573. relationalai/experimental/pathfinder/bridge.py +0 -226
  574. relationalai/experimental/pathfinder/compiler.py +0 -416
  575. relationalai/experimental/pathfinder/datalog.py +0 -214
  576. relationalai/experimental/pathfinder/diagnostics.py +0 -56
  577. relationalai/experimental/pathfinder/filter.py +0 -236
  578. relationalai/experimental/pathfinder/glushkov.py +0 -439
  579. relationalai/experimental/pathfinder/options.py +0 -265
  580. relationalai/experimental/pathfinder/pathfinder-v0.7.0.rel +0 -1951
  581. relationalai/experimental/pathfinder/rpq.py +0 -344
  582. relationalai/experimental/pathfinder/transition.py +0 -200
  583. relationalai/experimental/pathfinder/utils.py +0 -26
  584. relationalai/experimental/paths/README.md +0 -107
  585. relationalai/experimental/paths/api.py +0 -143
  586. relationalai/experimental/paths/benchmarks/grid_graph.py +0 -37
  587. relationalai/experimental/paths/code_organization.md +0 -2
  588. relationalai/experimental/paths/examples/Movies.ipynb +0 -16328
  589. relationalai/experimental/paths/examples/basic_example.py +0 -40
  590. relationalai/experimental/paths/examples/minimal_engine_warmup.py +0 -3
  591. relationalai/experimental/paths/examples/movie_example.py +0 -77
  592. relationalai/experimental/paths/examples/movies_data/actedin.csv +0 -193
  593. relationalai/experimental/paths/examples/movies_data/directed.csv +0 -45
  594. relationalai/experimental/paths/examples/movies_data/follows.csv +0 -7
  595. relationalai/experimental/paths/examples/movies_data/movies.csv +0 -39
  596. relationalai/experimental/paths/examples/movies_data/person.csv +0 -134
  597. relationalai/experimental/paths/examples/movies_data/produced.csv +0 -16
  598. relationalai/experimental/paths/examples/movies_data/ratings.csv +0 -10
  599. relationalai/experimental/paths/examples/movies_data/wrote.csv +0 -11
  600. relationalai/experimental/paths/examples/paths_benchmark.py +0 -115
  601. relationalai/experimental/paths/examples/paths_example.py +0 -116
  602. relationalai/experimental/paths/examples/pattern_to_automaton.py +0 -28
  603. relationalai/experimental/paths/find_paths_via_automaton.py +0 -85
  604. relationalai/experimental/paths/graph.py +0 -185
  605. relationalai/experimental/paths/path_algorithms/find_paths.py +0 -280
  606. relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +0 -26
  607. relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +0 -111
  608. relationalai/experimental/paths/path_algorithms/single.py +0 -59
  609. relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +0 -39
  610. relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +0 -103
  611. relationalai/experimental/paths/path_algorithms/usp-old.py +0 -130
  612. relationalai/experimental/paths/path_algorithms/usp-tuple.py +0 -183
  613. relationalai/experimental/paths/path_algorithms/usp.py +0 -150
  614. relationalai/experimental/paths/product_graph.py +0 -93
  615. relationalai/experimental/paths/rpq/automaton.py +0 -584
  616. relationalai/experimental/paths/rpq/diagnostics.py +0 -56
  617. relationalai/experimental/paths/rpq/rpq.py +0 -378
  618. relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +0 -90
  619. relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +0 -119
  620. relationalai/experimental/paths/tests/tests_limit_sp_single.py +0 -104
  621. relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +0 -113
  622. relationalai/experimental/paths/tests/tests_limit_walks_single.py +0 -149
  623. relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +0 -70
  624. relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +0 -64
  625. relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +0 -115
  626. relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +0 -75
  627. relationalai/experimental/paths/tests/tests_single_paths.py +0 -152
  628. relationalai/experimental/paths/tests/tests_single_walks.py +0 -208
  629. relationalai/experimental/paths/tests/tests_single_walks_undirected.py +0 -297
  630. relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +0 -107
  631. relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +0 -76
  632. relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +0 -76
  633. relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +0 -110
  634. relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +0 -229
  635. relationalai/experimental/paths/tests/tests_usp_nsp_single.py +0 -108
  636. relationalai/experimental/paths/tree_agg.py +0 -168
  637. relationalai/experimental/paths/utilities/iterators.py +0 -27
  638. relationalai/experimental/paths/utilities/prefix_sum.py +0 -91
  639. relationalai/experimental/solvers.py +0 -1087
  640. relationalai/loaders/csv.py +0 -195
  641. relationalai/loaders/loader.py +0 -177
  642. relationalai/loaders/types.py +0 -23
  643. relationalai/rel_emitter.py +0 -373
  644. relationalai/rel_utils.py +0 -185
  645. relationalai/semantics/designs/query_builder/identify_by.md +0 -106
  646. relationalai/semantics/devtools/benchmark_lqp.py +0 -535
  647. relationalai/semantics/devtools/compilation_manager.py +0 -294
  648. relationalai/semantics/devtools/extract_lqp.py +0 -110
  649. relationalai/semantics/internal/internal.py +0 -3785
  650. relationalai/semantics/internal/snowflake.py +0 -325
  651. relationalai/semantics/lqp/README.md +0 -34
  652. relationalai/semantics/lqp/builtins.py +0 -16
  653. relationalai/semantics/lqp/compiler.py +0 -22
  654. relationalai/semantics/lqp/constructors.py +0 -68
  655. relationalai/semantics/lqp/executor.py +0 -469
  656. relationalai/semantics/lqp/intrinsics.py +0 -24
  657. relationalai/semantics/lqp/model2lqp.py +0 -877
  658. relationalai/semantics/lqp/passes.py +0 -680
  659. relationalai/semantics/lqp/primitives.py +0 -252
  660. relationalai/semantics/lqp/result_helpers.py +0 -202
  661. relationalai/semantics/lqp/rewrite/annotate_constraints.py +0 -57
  662. relationalai/semantics/lqp/rewrite/cdc.py +0 -216
  663. relationalai/semantics/lqp/rewrite/extract_common.py +0 -338
  664. relationalai/semantics/lqp/rewrite/extract_keys.py +0 -506
  665. relationalai/semantics/lqp/rewrite/function_annotations.py +0 -114
  666. relationalai/semantics/lqp/rewrite/functional_dependencies.py +0 -314
  667. relationalai/semantics/lqp/rewrite/quantify_vars.py +0 -296
  668. relationalai/semantics/lqp/rewrite/splinter.py +0 -76
  669. relationalai/semantics/lqp/types.py +0 -101
  670. relationalai/semantics/lqp/utils.py +0 -160
  671. relationalai/semantics/lqp/validators.py +0 -57
  672. relationalai/semantics/metamodel/compiler.py +0 -133
  673. relationalai/semantics/metamodel/dependency.py +0 -862
  674. relationalai/semantics/metamodel/executor.py +0 -61
  675. relationalai/semantics/metamodel/factory.py +0 -287
  676. relationalai/semantics/metamodel/helpers.py +0 -361
  677. relationalai/semantics/metamodel/rewrite/discharge_constraints.py +0 -39
  678. relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +0 -210
  679. relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +0 -78
  680. relationalai/semantics/metamodel/rewrite/flatten.py +0 -554
  681. relationalai/semantics/metamodel/rewrite/format_outputs.py +0 -165
  682. relationalai/semantics/metamodel/typer/checker.py +0 -353
  683. relationalai/semantics/metamodel/typer/typer.py +0 -1395
  684. relationalai/semantics/metamodel/util.py +0 -506
  685. relationalai/semantics/reasoners/__init__.py +0 -10
  686. relationalai/semantics/reasoners/graph/README.md +0 -620
  687. relationalai/semantics/reasoners/graph/__init__.py +0 -37
  688. relationalai/semantics/reasoners/graph/core.py +0 -9019
  689. relationalai/semantics/reasoners/graph/design/beyond_demand_transform.md +0 -797
  690. relationalai/semantics/reasoners/graph/tests/README.md +0 -21
  691. relationalai/semantics/reasoners/optimization/__init__.py +0 -68
  692. relationalai/semantics/reasoners/optimization/common.py +0 -88
  693. relationalai/semantics/reasoners/optimization/solvers_dev.py +0 -568
  694. relationalai/semantics/reasoners/optimization/solvers_pb.py +0 -1163
  695. relationalai/semantics/rel/builtins.py +0 -40
  696. relationalai/semantics/rel/compiler.py +0 -989
  697. relationalai/semantics/rel/executor.py +0 -362
  698. relationalai/semantics/rel/rel.py +0 -482
  699. relationalai/semantics/rel/rel_utils.py +0 -276
  700. relationalai/semantics/snowflake/__init__.py +0 -3
  701. relationalai/semantics/sql/compiler.py +0 -2503
  702. relationalai/semantics/sql/executor/duck_db.py +0 -52
  703. relationalai/semantics/sql/executor/result_helpers.py +0 -64
  704. relationalai/semantics/sql/executor/snowflake.py +0 -149
  705. relationalai/semantics/sql/rewrite/denormalize.py +0 -222
  706. relationalai/semantics/sql/rewrite/double_negation.py +0 -49
  707. relationalai/semantics/sql/rewrite/recursive_union.py +0 -127
  708. relationalai/semantics/sql/rewrite/sort_output_query.py +0 -246
  709. relationalai/semantics/sql/sql.py +0 -504
  710. relationalai/semantics/std/pragmas.py +0 -11
  711. relationalai/semantics/std/std.py +0 -14
  712. relationalai/semantics/tests/test_snapshot_abstract.py +0 -143
  713. relationalai/semantics/tests/test_snapshot_base.py +0 -9
  714. relationalai/semantics/tests/utils.py +0 -46
  715. relationalai/std/__init__.py +0 -70
  716. relationalai/tools/cli.py +0 -1936
  717. relationalai/tools/cli_controls.py +0 -1826
  718. relationalai/tools/cli_helpers.py +0 -398
  719. relationalai/tools/debugger_client.py +0 -109
  720. relationalai/tools/debugger_server.py +0 -302
  721. relationalai/tools/dev.py +0 -685
  722. relationalai/tools/notes +0 -7
  723. relationalai/tools/qb_debugger.py +0 -425
  724. relationalai/util/clean_up_databases.py +0 -95
  725. relationalai/util/list_databases.py +0 -9
  726. relationalai/util/otel_configuration.py +0 -26
  727. relationalai/util/otel_handler.py +0 -484
  728. relationalai/util/snowflake_handler.py +0 -88
  729. relationalai/util/span_format_test.py +0 -43
  730. relationalai/util/span_tracker.py +0 -207
  731. relationalai/util/spans_file_handler.py +0 -72
  732. relationalai/util/tracing_handler.py +0 -34
  733. relationalai-0.13.0.dist-info/METADATA +0 -74
  734. relationalai-0.13.0.dist-info/RECORD +0 -458
  735. relationalai-0.13.0.dist-info/WHEEL +0 -4
  736. relationalai-0.13.0.dist-info/entry_points.txt +0 -3
  737. relationalai-0.13.0.dist-info/licenses/LICENSE +0 -202
  738. relationalai_test_util/__init__.py +0 -4
  739. relationalai_test_util/fixtures.py +0 -229
  740. relationalai_test_util/snapshot.py +0 -252
  741. relationalai_test_util/traceback.py +0 -118
  742. /relationalai/{analysis → semantics/frontend}/__init__.py +0 -0
  743. /relationalai/{auth/__init__.py → semantics/metamodel/metamodel_compiler.py} +0 -0
  744. /relationalai/{early_access → shims}/__init__.py +0 -0
  745. {relationalai/early_access/dsl/adapters → v0/relationalai/analysis}/__init__.py +0 -0
  746. {relationalai → v0/relationalai}/analysis/mechanistic.py +0 -0
  747. {relationalai → v0/relationalai}/analysis/whynot.py +0 -0
  748. {relationalai/early_access/dsl/adapters/orm → v0/relationalai/auth}/__init__.py +0 -0
  749. {relationalai → v0/relationalai}/auth/jwt_generator.py +0 -0
  750. {relationalai → v0/relationalai}/auth/oauth_callback_server.py +0 -0
  751. {relationalai → v0/relationalai}/auth/token_handler.py +0 -0
  752. {relationalai → v0/relationalai}/auth/util.py +0 -0
  753. {relationalai/clients/resources/snowflake → v0/relationalai/clients}/cache_store.py +0 -0
  754. {relationalai → v0/relationalai}/compiler.py +0 -0
  755. {relationalai → v0/relationalai}/dependencies.py +0 -0
  756. {relationalai → v0/relationalai}/docutils.py +0 -0
  757. {relationalai/early_access/dsl/adapters/owl → v0/relationalai/early_access}/__init__.py +0 -0
  758. {relationalai → v0/relationalai}/early_access/dsl/__init__.py +0 -0
  759. {relationalai/early_access/dsl/bindings → v0/relationalai/early_access/dsl/adapters}/__init__.py +0 -0
  760. {relationalai/early_access/dsl/bindings/legacy → v0/relationalai/early_access/dsl/adapters/orm}/__init__.py +0 -0
  761. {relationalai → v0/relationalai}/early_access/dsl/adapters/orm/model.py +0 -0
  762. {relationalai/early_access/dsl/codegen → v0/relationalai/early_access/dsl/adapters/owl}/__init__.py +0 -0
  763. {relationalai → v0/relationalai}/early_access/dsl/adapters/owl/model.py +0 -0
  764. {relationalai/early_access/dsl/core/temporal → v0/relationalai/early_access/dsl/bindings}/__init__.py +0 -0
  765. {relationalai/early_access/dsl/ir → v0/relationalai/early_access/dsl/bindings/legacy}/__init__.py +0 -0
  766. {relationalai/early_access/dsl/ontologies → v0/relationalai/early_access/dsl/codegen}/__init__.py +0 -0
  767. {relationalai → v0/relationalai}/early_access/dsl/constants.py +0 -0
  768. {relationalai → v0/relationalai}/early_access/dsl/core/__init__.py +0 -0
  769. {relationalai → v0/relationalai}/early_access/dsl/core/constraints/__init__.py +0 -0
  770. {relationalai → v0/relationalai}/early_access/dsl/core/constraints/predicate/__init__.py +0 -0
  771. {relationalai → v0/relationalai}/early_access/dsl/core/stack.py +0 -0
  772. {relationalai/early_access/dsl/orm → v0/relationalai/early_access/dsl/core/temporal}/__init__.py +0 -0
  773. {relationalai → v0/relationalai}/early_access/dsl/core/utils.py +0 -0
  774. {relationalai/early_access/dsl/orm/measures → v0/relationalai/early_access/dsl/ir}/__init__.py +0 -0
  775. {relationalai/early_access/dsl/physical_metadata → v0/relationalai/early_access/dsl/ontologies}/__init__.py +0 -0
  776. {relationalai → v0/relationalai}/early_access/dsl/ontologies/raw_source.py +0 -0
  777. {relationalai/early_access/dsl/serialize → v0/relationalai/early_access/dsl/orm}/__init__.py +0 -0
  778. {relationalai/early_access/dsl/snow → v0/relationalai/early_access/dsl/orm/measures}/__init__.py +0 -0
  779. {relationalai → v0/relationalai}/early_access/dsl/orm/reasoner_errors.py +0 -0
  780. {relationalai/loaders → v0/relationalai/early_access/dsl/physical_metadata}/__init__.py +0 -0
  781. {relationalai/semantics/tests → v0/relationalai/early_access/dsl/serialize}/__init__.py +0 -0
  782. {relationalai → v0/relationalai}/early_access/dsl/serialize/binding_model.py +0 -0
  783. {relationalai → v0/relationalai}/early_access/dsl/serialize/model.py +0 -0
  784. {relationalai/tools → v0/relationalai/early_access/dsl/snow}/__init__.py +0 -0
  785. {relationalai → v0/relationalai}/early_access/tests/__init__.py +0 -0
  786. {relationalai → v0/relationalai}/environments/ci.py +0 -0
  787. {relationalai → v0/relationalai}/environments/hex.py +0 -0
  788. {relationalai → v0/relationalai}/environments/terminal.py +0 -0
  789. {relationalai → v0/relationalai}/experimental/__init__.py +0 -0
  790. {relationalai → v0/relationalai}/experimental/graphs.py +0 -0
  791. {relationalai → v0/relationalai}/experimental/paths/__init__.py +0 -0
  792. {relationalai → v0/relationalai}/experimental/paths/benchmarks/__init__.py +0 -0
  793. {relationalai → v0/relationalai}/experimental/paths/path_algorithms/__init__.py +0 -0
  794. {relationalai → v0/relationalai}/experimental/paths/rpq/__init__.py +0 -0
  795. {relationalai → v0/relationalai}/experimental/paths/rpq/filter.py +0 -0
  796. {relationalai → v0/relationalai}/experimental/paths/rpq/glushkov.py +0 -0
  797. {relationalai → v0/relationalai}/experimental/paths/rpq/transition.py +0 -0
  798. {relationalai → v0/relationalai}/experimental/paths/utilities/__init__.py +0 -0
  799. {relationalai → v0/relationalai}/experimental/paths/utilities/utilities.py +0 -0
  800. {relationalai → v0/relationalai}/metagen.py +0 -0
  801. {relationalai → v0/relationalai}/metamodel.py +0 -0
  802. {relationalai → v0/relationalai}/rel.py +0 -0
  803. {relationalai → v0/relationalai}/semantics/devtools/__init__.py +0 -0
  804. {relationalai → v0/relationalai}/semantics/internal/__init__.py +0 -0
  805. {relationalai → v0/relationalai}/semantics/internal/annotations.py +0 -0
  806. {relationalai → v0/relationalai}/semantics/lqp/__init__.py +0 -0
  807. {relationalai → v0/relationalai}/semantics/lqp/ir.py +0 -0
  808. {relationalai → v0/relationalai}/semantics/lqp/pragmas.py +0 -0
  809. {relationalai → v0/relationalai}/semantics/lqp/rewrite/__init__.py +0 -0
  810. {relationalai → v0/relationalai}/semantics/metamodel/dataflow.py +0 -0
  811. {relationalai → v0/relationalai}/semantics/metamodel/ir.py +0 -0
  812. {relationalai → v0/relationalai}/semantics/metamodel/rewrite/__init__.py +0 -0
  813. {relationalai → v0/relationalai}/semantics/metamodel/typer/__init__.py +0 -0
  814. {relationalai → v0/relationalai}/semantics/metamodel/types.py +0 -0
  815. {relationalai → v0/relationalai}/semantics/metamodel/visitor.py +0 -0
  816. {relationalai → v0/relationalai}/semantics/reasoners/experimental/__init__.py +0 -0
  817. {relationalai → v0/relationalai}/semantics/rel/__init__.py +0 -0
  818. {relationalai → v0/relationalai}/semantics/sql/__init__.py +0 -0
  819. {relationalai → v0/relationalai}/semantics/sql/executor/__init__.py +0 -0
  820. {relationalai → v0/relationalai}/semantics/sql/rewrite/__init__.py +0 -0
  821. {relationalai → v0/relationalai}/semantics/tests/logging.py +0 -0
  822. {relationalai → v0/relationalai}/std/aggregates.py +0 -0
  823. {relationalai → v0/relationalai}/std/dates.py +0 -0
  824. {relationalai → v0/relationalai}/std/graphs.py +0 -0
  825. {relationalai → v0/relationalai}/std/inspect.py +0 -0
  826. {relationalai → v0/relationalai}/std/math.py +0 -0
  827. {relationalai → v0/relationalai}/std/re.py +0 -0
  828. {relationalai → v0/relationalai}/std/strings.py +0 -0
  829. {relationalai → v0/relationalai}/tools/cleanup_snapshots.py +0 -0
  830. {relationalai → v0/relationalai}/tools/constants.py +0 -0
  831. {relationalai → v0/relationalai}/tools/query_utils.py +0 -0
  832. {relationalai → v0/relationalai}/tools/snapshot_viewer.py +0 -0
  833. {relationalai → v0/relationalai}/util/__init__.py +0 -0
  834. {relationalai → v0/relationalai}/util/constants.py +0 -0
  835. {relationalai → v0/relationalai}/util/graph.py +0 -0
  836. {relationalai → v0/relationalai}/util/timeout.py +0 -0
@@ -0,0 +1,1290 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import defaultdict
4
+ from dataclasses import dataclass, field, replace as dc_replace
5
+ from typing import Dict, Sequence as seq, Iterable
6
+ from enum import Enum
7
+ from math import pi
8
+
9
+ # PyRel imports
10
+ from ..util.naming import sanitize
11
+ from ..semantics.metamodel import metamodel as mm
12
+ from ..semantics.metamodel.builtins import builtins as b, is_abstract
13
+ from ..semantics.metamodel.metamodel_analyzer import Normalize
14
+ # ensure std libs are loaded
15
+ from ..semantics.metamodel.metamodel_analyzer import VarFinder
16
+ from ..semantics.metamodel.rewriter import Walker
17
+ from ..semantics.std import aggregates, common, math, numbers, re, strings, decimals, datetime, floats
18
+ from ..semantics.backends.lqp import annotations as lqp_annotations
19
+
20
+ # V0 imports
21
+ from v0.relationalai.semantics.metamodel import ir as v0, builtins as v0_builtins, types as v0_types, factory as f
22
+ from v0.relationalai.semantics.metamodel.util import FrozenOrderedSet, frozen, ordered_set, filter_by_type, OrderedSet
23
+ from v0.relationalai.semantics.internal.internal import literal_value_to_type
24
+
25
+ from .hoister import Hoister
26
+ from .helpers import is_output_update, is_main_output
27
+
28
+ #------------------------------------------------------
29
+ # Simplified translation API
30
+ #------------------------------------------------------
31
+ def translate(model: mm.Model) -> v0.Model:
32
+ return Translator().translate_model(model)
33
+
34
+ #------------------------------------------------------
35
+ # Implementation
36
+ #------------------------------------------------------
37
+ class Context(Enum):
38
+ # when translating tasks (i.e. runtime behavior)
39
+ TASK = 1
40
+ # when translating the static structure of the model (types, relations, etc.)
41
+ MODEL = 2
42
+
43
+ @dataclass
44
+ class Translator():
45
+
46
+ stack: list[mm.Node] = field(default_factory=list)
47
+
48
+ # maps from mm.Node id to the v0.Node created for it
49
+ # for Context=TASK
50
+ task_map: Dict[int, v0.Node] = field(default_factory=dict)
51
+ # for Context=MODEL
52
+ model_map: Dict[int, v0.Node] = field(default_factory=dict)
53
+
54
+ # map from a var that is bound to a table, to the list of vars that were used to construct
55
+ # this var. This var is going to be used as a key to an output.
56
+ key_map: Dict[mm.Var, seq[v0.Var]] = field(default_factory=dict)
57
+
58
+ # map from a var that is bound to a data, to the data itself. This is used to translate
59
+ # lookups on this var into v0 Data nodes.
60
+ data_map: Dict[mm.Var, mm.Var] = field(default_factory=dict)
61
+
62
+ # map from a var that is bound to an external table, to the vars of its fields
63
+ column_map: defaultdict[mm.Var, dict[mm.Relation, v0.Value]] = field(default_factory=lambda: defaultdict(dict))
64
+
65
+ # used tables
66
+ used_tables: OrderedSet[mm.Table] = field(default_factory=lambda: ordered_set())
67
+
68
+ # when translating a relation that has multiple readings, we need to translate to multiple
69
+ # relations in v0, and we need to add rules to populate those relations. We also need rules
70
+ # to populate super types from sub types.
71
+ maintenance_rules: list[v0.Logical] = field(default_factory=list)
72
+
73
+ # outputs that are exports
74
+ exports: set[v0.Output] = field(default_factory=set)
75
+
76
+ hoister = Hoister()
77
+ normalize = Normalize()
78
+
79
+ def get(self, ctx: Context, node: mm.Node):
80
+ if ctx == Context.MODEL:
81
+ return self.model_map.get(node.id, None)
82
+ else:
83
+ return self.task_map.get(node.id, None)
84
+ def set(self, ctx: Context, node: mm.Node, value: v0.Node):
85
+ if ctx == Context.MODEL:
86
+ self.model_map[node.id] = value # type: ignore
87
+ else:
88
+ self.task_map[node.id] = value # type: ignore
89
+
90
+ def translate_node(self, node: mm.Node, parent=None, ctx=Context.TASK) -> v0.Node|seq[v0.Node]:
91
+ x = self.get(ctx, node)
92
+ if x is not None:
93
+ return x
94
+
95
+ source_class_name = node.__class__.__name__.lower()
96
+ translator = getattr(self, f"translate_{source_class_name}", None)
97
+ if translator is None:
98
+ raise NotImplementedError(f"No translator for node type: {source_class_name}")
99
+
100
+ if parent:
101
+ self.stack.append(parent)
102
+ result = translator(node, parent, ctx)
103
+ if parent:
104
+ self.stack.pop()
105
+
106
+ self.set(ctx, node, result)
107
+ return result
108
+
109
+ def translate_value(self, value: mm.Value, parent, ctx) -> v0.Value:
110
+ # Value = _Union[Var, Literal, Type, Relation, seq["Value"], None]
111
+ if value is None:
112
+ return None
113
+ elif isinstance(value, mm.ScalarType) or isinstance(value, mm.Relation):
114
+ return self.translate_node(value, parent, Context.MODEL) # type: ignore
115
+ elif isinstance(value, seq):
116
+ return self.translate_seq(value, parent, ctx) # type: ignore
117
+ return self.translate_node(value, parent, ctx) # type: ignore
118
+
119
+
120
+ def translate_seq(self, nodes: seq[mm.Node], parent, ctx) -> tuple[v0.Node,...]:
121
+ res = []
122
+ for n in nodes:
123
+ x = self.translate_node(n, parent, ctx)
124
+ # flat map would be great here
125
+ if isinstance(x, list) or isinstance(x, tuple):
126
+ res.extend(x)
127
+ elif x is not None:
128
+ res.append(x)
129
+ return tuple(res)
130
+
131
+ def translate_frozen(self, nodes: seq[mm.Node], parent, ctx) -> FrozenOrderedSet[v0.Node]:
132
+ return frozen(*self.translate_seq(nodes, parent, ctx))
133
+
134
+
135
+ #-----------------------------------------------------------------------------
136
+ # Capabilities, Reasoners
137
+ #-----------------------------------------------------------------------------
138
+
139
+ def translate_capability(self, c: mm.Capability, parent: mm.Reasoner, ctx) -> v0.Capability:
140
+ return v0.Capability(name=c.name)
141
+
142
+ def translate_reasoner(self, r: mm.Reasoner|None, parent, ctx) -> v0.Engine|None:
143
+ if r is None:
144
+ return None
145
+ return v0.Engine(
146
+ name=f"{r.id}", # no name field in v0, so use id
147
+ platform=r.type,
148
+ info=r.info,
149
+ capabilities=self.translate_frozen(r.capabilities, r, ctx), # type: ignore
150
+ relations=self.translate_frozen(r.relations, r, ctx), # type: ignore
151
+ annotations=self.translate_frozen(r.annotations, r, ctx) # type: ignore
152
+ )
153
+
154
+ # -----------------------------------------------------------------------------
155
+ # Relation
156
+ # -----------------------------------------------------------------------------
157
+
158
+ def translate_field(self, f: mm.Field, parent, ctx) -> v0.Field:
159
+ return v0.Field(
160
+ name=f.name,
161
+ type=self.translate_node(f.type, f, Context.MODEL), # type: ignore
162
+ input=f.input,
163
+ )
164
+
165
+ def translate_reading(self, r: mm.Reading, parent: mm.Relation, ctx) -> v0.Relation:
166
+ # Readings in v0 are represented as separate Relation nodes with different field orders
167
+ fields = []
168
+ for i in r.field_order:
169
+ fields.append(self.translate_field(parent.fields[i], r, ctx))
170
+
171
+ # this is not totally correct, we are translating the parent's overloads here, but
172
+ # the order of fields would be different. However, it's unlikely we will have multiple
173
+ # readings AND overloads in the same relation, so this is acceptable for now.
174
+ return v0.Relation(
175
+ name=f"{parent.name}_{parent.readings.index(r)}",
176
+ fields=tuple(fields),
177
+ requires=frozen(),
178
+ annotations=frozen(),
179
+ overloads=self.translate_frozen(parent.overloads, parent, ctx), # type: ignore
180
+ )
181
+
182
+ def translate_overload(self, o: mm.Overload, parent: mm.Relation, ctx) -> v0.Relation:
183
+ # Overloads in v0 are represented as separate Relation nodes with different types
184
+ fields = []
185
+ for field, typ in zip(parent.fields, o.types):
186
+ fields.append(
187
+ v0.Field(name=field.name, type=self.translate_node(typ, field, ctx), input=field.input) # type: ignore
188
+ )
189
+ return v0.Relation(
190
+ name=parent.name,
191
+ fields=tuple(fields),
192
+ requires=frozen(),
193
+ annotations=frozen(),
194
+ overloads=frozen()
195
+ )
196
+
197
+ # map builtin relations by name
198
+ BUILTIN_RELATION_MAP = {}
199
+ RENAMES = {
200
+ "degrees": "rad2deg",
201
+ "radians": "deg2rad",
202
+ "len": "num_chars",
203
+ "power": "pow",
204
+ "^": "pow",
205
+ "like": "like_match",
206
+ "regex_escape": "escape_regex_metachars",
207
+ }
208
+ for lib in ["core", "aggregates", "common", "datetime", "floats", "math", "numbers", "strings", "re", "lqp"]:
209
+ for x in b._libraries[lib].data.values():
210
+ v0_name = RENAMES.get(x.name, x.name)
211
+ if v0_name in v0_builtins.builtin_relations_by_name:
212
+ BUILTIN_RELATION_MAP[x] = v0_builtins.builtin_relations_by_name[v0_name]
213
+
214
+ def translate_unresolvedrelation(self, r: mm.Relation, parent, ctx):
215
+ # remove unresolved relations from the model as they are not needed
216
+ return None
217
+
218
+ def translate_relation(self, r: mm.Relation, parent, ctx):
219
+ if r in self.BUILTIN_RELATION_MAP:
220
+ return self.BUILTIN_RELATION_MAP[r]
221
+
222
+ if r is b.numbers.parse_number:
223
+ if isinstance(parent, mm.Lookup):
224
+ assert(isinstance(parent.args[1], mm.Var))
225
+ out_type = parent.args[1].type
226
+ assert(isinstance(out_type, mm.NumberType))
227
+ if out_type.scale == 0:
228
+ return v0_builtins.parse_int128 if out_type.precision > 19 else v0_builtins.parse_int64
229
+ else:
230
+ return v0_builtins.parse_decimal
231
+
232
+ # relations can be accessed by any context; if it exists in the other context, use it
233
+ other_ctx = Context.MODEL if ctx == Context.TASK else Context.TASK
234
+ x = self.get(other_ctx, r)
235
+ if x is not None:
236
+ return x # type: ignore
237
+
238
+ if len(r.readings) > 1:
239
+ # if there are multiple readings, create a relation per reading
240
+ relations = self.translate_seq(r.readings, r, ctx) # type: ignore
241
+
242
+ # also create a rule to populate the other readings from the main relation
243
+ main_relation = relations[0]
244
+ assert isinstance(main_relation, v0.Relation)
245
+ main_relation_args = tuple(v0.Var(type=field.type, name=field.name) for field in main_relation.fields)
246
+ for reading in r.readings[1:]:
247
+ relation = relations[r.readings.index(reading)]
248
+ assert isinstance(relation, v0.Relation)
249
+ # lookup from main_relation and derive into this relation
250
+ self.maintenance_rules.append(v0.Logical(
251
+ engine=None,
252
+ hoisted=(),
253
+ body=(
254
+ v0.Lookup(
255
+ engine=None,
256
+ relation=main_relation,
257
+ args=main_relation_args,
258
+ annotations=frozen(),
259
+ ),
260
+ v0.Update(
261
+ engine=None,
262
+ relation=relation,
263
+ args=tuple([main_relation_args[idx] for idx in reading.field_order]),
264
+ effect=v0.Effect.derive,
265
+ annotations=frozen(),
266
+ )
267
+ ),
268
+ annotations=frozen(),
269
+ ))
270
+ return relations
271
+ else:
272
+ # if there are no readings or a single reading, create a single relation
273
+
274
+ # if this is a placeholder relation, fill overloads with all non-placeholder relations
275
+ # with the same name
276
+ overloads = ordered_set()
277
+ if all(field.type == b.core.Any for field in r.fields):
278
+ for rr in self.relations_by_name[r.name]:
279
+ if any(field.type != b.core.Any for field in rr.fields):
280
+ x = self.translate_relation(rr, r, ctx)
281
+ if isinstance(x, v0.Relation):
282
+ overloads.add(x)
283
+ else:
284
+ overloads.update(x) # type: ignore
285
+ overloads.update(self.translate_frozen(r.overloads, r, ctx)) # type: ignore
286
+
287
+ return v0.Relation(
288
+ name=r.name,
289
+ fields=self.translate_frozen(r.fields, r, ctx), # type: ignore
290
+ requires=self.translate_frozen(r.requires, r, ctx), # type: ignore
291
+ annotations=self.translate_frozen(r.annotations, r, ctx), # type: ignore
292
+ overloads=overloads.frozen(), # type: ignore
293
+ )
294
+
295
+ def translate_unresolvedrelation(self, r: mm.UnresolvedRelation, parent, ctx):
296
+ # treat unresolved relations the same as normal relations for now
297
+ return self.translate_relation(r, parent, ctx)
298
+
299
+ #------------------------------------------------------
300
+ # Annotation
301
+ #------------------------------------------------------
302
+
303
+ def translate_annotation(self, a: mm.Annotation, parent, ctx) -> v0.Annotation:
304
+ if a.relation.name in v0_builtins.builtin_annotations_by_name:
305
+ return getattr(v0_builtins, a.relation.name + "_annotation") # type: ignore
306
+
307
+ return v0.Annotation(
308
+ relation=self.translate_node(a.relation, a, Context.MODEL), # type: ignore
309
+ args=tuple(self.translate_value(arg, a, ctx) for arg in a.args)
310
+ )
311
+
312
+ #-----------------------------------------------------------------------------
313
+ # Types
314
+ #-----------------------------------------------------------------------------
315
+
316
+ BUILTIN_TYPE_MAP = {
317
+ # Abstract types (should be removed once our typer is done because they should not
318
+ # show up in the typed metamodel.)
319
+ b.core.Any: v0_types.Any,
320
+ # b.core.AnyEntity: v0_types.AnyEntity,
321
+ b.core.Number: v0_types.Number, # v0 typer can figure the rest out
322
+ # Concrete types
323
+ b.core.Boolean: v0_types.Bool,
324
+ b.core.String: v0_types.String,
325
+ b.core.Date: v0_types.Date,
326
+ b.core.DateTime: v0_types.DateTime,
327
+ b.core.Float: v0_types.Float,
328
+ }
329
+
330
+ def translate_scalartype(self, t: mm.ScalarType, parent: mm.Node, ctx) -> v0.ScalarType|v0.Relation|None:
331
+ if t in self.BUILTIN_TYPE_MAP:
332
+ return self.BUILTIN_TYPE_MAP[t]
333
+
334
+ if ctx == Context.TASK:
335
+ # in task context, this is a lookup or update on a concept population relation
336
+ # TODO - removing this filter for now
337
+ actual_type = self.translate_node(t, t, Context.MODEL)
338
+ assert isinstance(actual_type, v0.ScalarType)
339
+ fields = [v0.Field(name="entity", type=actual_type, input=False)] # type: ignore
340
+ annotations = [v0_builtins.concept_relation_annotation]
341
+ if isinstance(t, mm.Table):
342
+ annotations.append(v0_builtins.external_annotation)
343
+ annotations.append(v0_builtins.from_cdc_annotation)
344
+ for col in t.columns:
345
+ fields.append(v0.Field(
346
+ name=col.name,
347
+ type=self.translate_node(col.fields[-1].type, col, Context.MODEL), # type: ignore
348
+ input=False
349
+ ))
350
+
351
+ type_relation = v0.Relation(
352
+ name=t.name,
353
+ fields=tuple(fields), # type: ignore
354
+ requires=frozen(),
355
+ annotations=frozen(*annotations), # type: ignore
356
+ overloads=frozen()
357
+ )
358
+ for super_type in t.super_types:
359
+ super_rel = self.translate_node(super_type, t, Context.TASK)
360
+ if not super_rel:
361
+ continue
362
+ assert isinstance(super_rel, v0.Relation)
363
+ v = v0.Var(type=actual_type, name=type_relation.name.lower())
364
+ self.maintenance_rules.append(v0.Logical(
365
+ engine=None,
366
+ hoisted=(),
367
+ body=(
368
+ v0.Lookup(
369
+ engine=None,
370
+ relation=type_relation,
371
+ args=(v,),
372
+ annotations=frozen(),
373
+ ),
374
+ v0.Update(
375
+ engine=None,
376
+ relation=super_rel,
377
+ args=(v,),
378
+ effect=v0.Effect.derive,
379
+ annotations=frozen(),
380
+ )
381
+ ),
382
+ annotations=frozen(),
383
+ ))
384
+ return type_relation
385
+
386
+ extends=[]
387
+ if isinstance(t, mm.Table):
388
+ extends.append(v0_types.RowId)
389
+
390
+ for st in t.super_types:
391
+ # for now make all value types extending number be Int64, we will fix this with a new typer
392
+ if st == b.core.Number:
393
+ translated_st = v0_types.Number
394
+ else:
395
+ translated_st = self.translate_node(st, t, ctx)
396
+ extends.append(translated_st)
397
+
398
+ return v0.ScalarType(
399
+ name=t.name,
400
+ super_types=frozen(*extends), # type: ignore
401
+ # super_types=self.translate_frozen(t.super_types, t, ctx), # type: ignore
402
+ annotations=self.translate_frozen(t.annotations, t, ctx) # type: ignore
403
+ )
404
+
405
+ def translate_numbertype(self, t: mm.NumberType, parent, ctx):
406
+ if t.scale == 0:
407
+ return v0_types.Int128 if t.precision > 19 else v0_types.Int64
408
+ return v0.DecimalType(
409
+ name=t.name,
410
+ precision=t.precision,
411
+ scale=t.scale,
412
+ super_types=frozen(),
413
+ annotations=self.translate_frozen(t.annotations, t, ctx) # type: ignore
414
+ )
415
+
416
+ def translate_uniontype(self, t: mm.UnionType, parent, ctx) -> v0.UnionType:
417
+ return v0.UnionType(
418
+ types=self.translate_frozen(t.types, t, ctx), # type: ignore
419
+ )
420
+
421
+ def translate_listtype(self, t: mm.ListType, parent, ctx) -> v0.ListType:
422
+ return v0.ListType(
423
+ element_type=self.translate_node(t.element_type, t, ctx), # type: ignore
424
+ )
425
+
426
+ def translate_tupletype(self, t: mm.TupleType, parent, ctx) -> v0.TupleType:
427
+ return v0.TupleType(
428
+ types=self.translate_seq(t.element_types, t, ctx), # type: ignore
429
+ )
430
+
431
+
432
+ #------------------------------------------------------
433
+ # Table
434
+ #------------------------------------------------------
435
+
436
+ # TODO - this depends on what is using it, it may become an Output
437
+ # class Table(ScalarType):
438
+ # columns: seq[Relation] = tuple_field()
439
+ # uri: str = ""
440
+
441
+ def translate_table(self, t: mm.Table, parent, ctx):
442
+ return self.translate_scalartype(t, parent, ctx)
443
+
444
+
445
+ # -----------------------------------------------------------------------------
446
+ # Values
447
+ # -----------------------------------------------------------------------------
448
+
449
+ # Primitive = _Union[str, int, float, bool, _dt.datetime, None]
450
+
451
+ def translate_var(self, v: mm.Var, parent, ctx) -> v0.Var:
452
+ if isinstance(parent, mm.Lookup):
453
+ root_type = parent.relation.fields[0].type
454
+ root_arg = parent.args[0]
455
+ if isinstance(root_arg, mm.Var) \
456
+ and isinstance(root_type, mm.Table) \
457
+ and (existing := self.column_map[root_arg].get(parent.relation)):
458
+ return existing # type: ignore
459
+
460
+ return v0.Var(
461
+ type=self.translate_node(v.type, v, Context.MODEL), # type: ignore
462
+ name=v.name
463
+ )
464
+
465
+ def translate_literal(self, l: mm.Literal, parent, ctx) -> v0.Literal:
466
+ typ = None
467
+ if l.type is None or is_abstract(l.type):
468
+ # force int64 for literals, it can be widened later if needed
469
+ if type(l.value) == int:
470
+ typ = v0_types.Int64
471
+ else:
472
+ # using v0's map of literal to type
473
+ typ = literal_value_to_type(l.value)
474
+ else:
475
+ typ = self.translate_node(l.type, l, Context.MODEL)
476
+ if type is None:
477
+ pass
478
+ return v0.Literal(
479
+ type=typ, # type: ignore
480
+ value=l.value
481
+ )
482
+
483
+ # Value = _Union[Var, Literal, Type, Relation, seq["Value"], None]
484
+
485
+ # # -----------------------------------------------------------------------------
486
+ # # Tasks (process algebra)
487
+ # # -----------------------------------------------------------------------------
488
+
489
+ # @dataclass(frozen=True, kw_only=True)
490
+ # class Task(Node):
491
+ # reasoner: Optional[Reasoner] = None
492
+
493
+ # -----------------------------
494
+ # Control Flow
495
+ # -----------------------------
496
+
497
+ def _merge_outputs(self, children: seq[v0.Node], outputs:list[v0.Output]):
498
+ # We need to always rewrite the outputs, even if there's only one, because
499
+ # we may need to mark it as an export and handle the NO_KEYS case.
500
+ # if len(outputs) < 2:
501
+ # return children
502
+
503
+ children = list(children)
504
+
505
+ # merge all outputs, accumulating keys and aliases
506
+ keys = ordered_set()
507
+ aliases = ordered_set()
508
+ for output in outputs:
509
+ assert isinstance(output, v0.Output)
510
+ children.remove(output)
511
+ if output.keys is not None:
512
+ keys.update(output.keys)
513
+ aliases.update(output.aliases)
514
+
515
+ # add a single, merged output
516
+ is_export = any(output in self.exports for output in outputs)
517
+ annos = (v0_builtins.export_annotation,) if is_export else ()
518
+ if is_export and not keys:
519
+ key_var = v0.Var(type=v0_types.Hash, name="export_key")
520
+ vals = [alias[1] for alias in aliases]
521
+ children.append(v0.Construct(
522
+ engine=None,
523
+ values=(v0.Literal(type=v0_types.String, value="NO_KEYS"), *vals),
524
+ id_var=key_var,
525
+ ))
526
+ keys.add(key_var)
527
+
528
+ children.append(
529
+ v0.Output(
530
+ engine=None,
531
+ aliases=frozen(*aliases),
532
+ keys=frozen(*keys),
533
+ annotations=frozen(*annos)
534
+ )
535
+ )
536
+ return tuple(children)
537
+
538
+ def get_outputs(self, children: seq[v0.Node]) -> list[v0.Output]:
539
+ return list(filter(lambda o: isinstance(o, v0.Output), children)) # type: ignore
540
+
541
+ def translate_logical(self, l: mm.Logical, parent, ctx):
542
+ # first process children
543
+ children = self.translate_seq(l.body, l, ctx)
544
+
545
+ # inline logicals if possible
546
+ new_children = []
547
+ for c in children:
548
+ if isinstance(c, v0.Logical) and not c.hoisted and len(c.body) == 1:
549
+ new_children.extend(c.body)
550
+ else:
551
+ new_children.append(c)
552
+ # children = children if len(children) == len(new_children) else tuple(new_children)
553
+ children = tuple(new_children)
554
+
555
+ # compute variables to hoist, wrapping in Default if the logical is optional
556
+ if l.optional:
557
+ hoisted = tuple([v0.Default(self.translate_node(v, l, ctx), None) for v in self.hoister.hoisted(l)]) # type: ignore
558
+ else:
559
+ hoisted = tuple([self.translate_node(v, l, ctx) for v in self.hoister.hoisted(l)]) # type: ignore
560
+
561
+ # Nots can never hoist variables upwards
562
+ if isinstance(parent, mm.Not):
563
+ hoisted = ()
564
+
565
+ # if there are no outputs, just return the logical
566
+ outputs = self.get_outputs(children)
567
+ if not outputs:
568
+ return v0.Logical(
569
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
570
+ hoisted=hoisted, # type: ignore
571
+ body=children, # type: ignore
572
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
573
+ )
574
+
575
+
576
+ # if there's a main output here, we need to merge all outputs as a single one
577
+ has_main_output = any(is_main_output(c) for c in l.body)
578
+ if has_main_output:
579
+ return v0.Logical(
580
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
581
+ hoisted=hoisted, # type: ignore
582
+ body=self._merge_outputs(children, outputs), # type: ignore
583
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
584
+ )
585
+ else:
586
+ # this logical has an output but it's not the main one; so we return the outputs
587
+ # side-by-side with the logical. This assumes that the parent is a logical that
588
+ # will splat these tasks and we will eventually get into a logical with a main
589
+ # output that will merge them all.
590
+
591
+ # remove outputs from children
592
+ children = tuple([c for c in children if not isinstance(c, v0.Output)])
593
+ if not children:
594
+ return outputs
595
+
596
+ # if this is an optional logical but we're not hoisting anything and not updating,
597
+ # then it's effectively a no-op since it cannot affect the query. Just return the outputs.
598
+ # this is important because the LQP stack blows up if there's a logical with no effect
599
+ if l.optional and not hoisted and not any(isinstance(c, v0.Update) for c in children):
600
+ return outputs
601
+
602
+ # return outputs + a logical with the other children
603
+ outputs.append(
604
+ v0.Logical(
605
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
606
+ hoisted=hoisted, # type: ignore
607
+ body=children, # type: ignore
608
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
609
+ ))
610
+ return outputs
611
+
612
+
613
+
614
+
615
+ def translate_sequence(self, s: mm.Sequence, parent, ctx) -> v0.Sequence:
616
+ return v0.Sequence(
617
+ engine=self.translate_reasoner(s.reasoner, s, Context.MODEL),
618
+ hoisted=self.translate_seq(self.hoister.hoisted(s), s, ctx), # type: ignore
619
+ tasks=self.translate_seq(s.tasks, s, ctx), # type: ignore
620
+ annotations=self.translate_frozen(s.annotations, s, ctx) # type: ignore
621
+ )
622
+
623
+ def translate_union(self, u: mm.Union, parent, ctx) -> v0.Union:
624
+ return v0.Union(
625
+ engine=self.translate_reasoner(u.reasoner, u, Context.MODEL),
626
+ hoisted=self.translate_seq(self.hoister.hoisted(u), u, ctx), # type: ignore
627
+ tasks=self.translate_seq(u.tasks, u, ctx), # type: ignore
628
+ annotations=self.translate_frozen(u.annotations, u, ctx) # type: ignore
629
+ )
630
+
631
+ def translate_match(self, m: mm.Match, parent, ctx) -> v0.Match:
632
+ return v0.Match(
633
+ engine=self.translate_reasoner(m.reasoner, m, Context.MODEL),
634
+ hoisted=self.translate_seq(self.hoister.hoisted(m), m, ctx), # type: ignore
635
+ tasks=self.translate_seq(m.tasks, m, ctx), # type: ignore
636
+ annotations=self.translate_frozen(m.annotations, m, ctx) # type: ignore
637
+ )
638
+
639
+ def translate_until(self, u: mm.Until, parent, ctx) -> v0.Until:
640
+ return v0.Until(
641
+ engine=self.translate_reasoner(u.reasoner, u, Context.MODEL),
642
+ hoisted=self.translate_seq(self.hoister.hoisted(u), u, ctx), # type: ignore
643
+ check=self.translate_node(u.check, u, ctx), # type: ignore
644
+ body=self.translate_node(u.body, u, ctx), # type: ignore
645
+ annotations=self.translate_frozen(u.annotations, u, ctx) # type: ignore
646
+ )
647
+
648
+ def translate_wait(self, w: mm.Wait, parent, ctx) -> v0.Wait:
649
+ return v0.Wait(
650
+ engine=self.translate_reasoner(w.reasoner, w, Context.MODEL),
651
+ hoisted=self.translate_seq(self.hoister.hoisted(w), w, ctx), # type: ignore
652
+ check=self.translate_node(w.check, w, ctx), # type: ignore
653
+ annotations=self.translate_frozen(w.annotations, w, ctx) # type: ignore
654
+ )
655
+
656
+ def translate_loop(self, l: mm.Loop, parent, ctx) -> v0.Loop:
657
+ # TODO - loop is incompatible because over has multiple vars, so this is a best
658
+ # attempt (does not matter much as this is not used in practice)
659
+ return v0.Loop(
660
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
661
+ hoisted=self.translate_seq(self.hoister.hoisted(l), l, ctx), # type: ignore
662
+ iter=self.translate_node(l.over[0], l, ctx), # type: ignore
663
+ body=self.translate_node(l.body, l, ctx), # type: ignore
664
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
665
+ )
666
+
667
+ def translate_break(self, b: mm.Break, parent, ctx) -> v0.Break:
668
+ return v0.Break(
669
+ engine=self.translate_reasoner(b.reasoner, b, Context.MODEL),
670
+ check=self.translate_node(b.check, b, ctx), # type: ignore
671
+ annotations=self.translate_frozen(b.annotations, b, ctx) # type: ignore
672
+ )
673
+
674
+ # -----------------------------
675
+ # Constraints
676
+ # -----------------------------
677
+
678
+ def translate_require(self, r: mm.Require, parent, ctx) -> v0.Require|None:
679
+ return None
680
+ # check = v0.Check(
681
+ # check=self.translate_node(r.check, r, ctx), # type: ignore
682
+ # error=self.translate_node(r.error, r, ctx) if r.error else None, # type: ignore
683
+ # annotations=self.translate_frozen(r.annotations, r, ctx) # type: ignore
684
+ # )
685
+ # return v0.Require(
686
+ # engine=self.translate_reasoner(r.reasoner, r, Context.MODEL),
687
+ # domain=self.translate_node(r.domain, r, ctx), # type: ignore
688
+ # checks=tuple([check]), # type: ignore
689
+ # annotations=self.translate_frozen(r.annotations, r, ctx) # type: ignore
690
+ # )
691
+
692
+ # -----------------------------
693
+ # Quantifiers
694
+ # -----------------------------
695
+
696
+ def translate_not(self, n: mm.Not, parent, ctx) -> v0.Not:
697
+ return v0.Not(
698
+ engine=self.translate_reasoner(n.reasoner, n, Context.MODEL),
699
+ task=self.translate_node(n.task, n, ctx), # type: ignore
700
+ annotations=self.translate_frozen(n.annotations, n, ctx) # type: ignore
701
+ )
702
+
703
+ def translate_exists(self, e: mm.Exists, parent, ctx) -> v0.Exists:
704
+ return v0.Exists(
705
+ engine=self.translate_reasoner(e.reasoner, e, Context.MODEL),
706
+ vars=self.translate_seq(e.vars, e, ctx), # type: ignore
707
+ task=self.translate_node(e.task, e, ctx), # type: ignore
708
+ annotations=self.translate_frozen(e.annotations, e, ctx) # type: ignore
709
+ )
710
+
711
+ # -----------------------------
712
+ # Relation Ops
713
+ # -----------------------------
714
+
715
+ def translate_effect(self, e: mm.Effect, parent, ctx) -> v0.Effect:
716
+ if e == mm.Effect.derive:
717
+ return v0.Effect.derive
718
+ elif e == mm.Effect.insert:
719
+ return v0.Effect.insert
720
+ elif e == mm.Effect.delete:
721
+ return v0.Effect.delete
722
+
723
+ def translate_lookup(self, l: mm.Lookup, parent, ctx):
724
+ # Data Node lookups
725
+ if isinstance(l.relation, mm.Data):
726
+ vars = [self.translate_value(l.args[0], l, ctx)]
727
+ for col in l.relation.columns:
728
+ v = v0.Var(
729
+ type=self.translate_node(col.fields[-1].type, col, Context.MODEL), # type: ignore
730
+ name=f"{col.name}"
731
+ )
732
+ vars.append(v)
733
+ assert isinstance(l.args[0], mm.Var)
734
+ self.column_map[l.args[0]][col] = v
735
+ return v0.Data(
736
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
737
+ data=l.relation.data,
738
+ vars=frozen(*vars) # type: ignore
739
+ )
740
+ elif l.args and l.args[0] in self.column_map and l.relation in self.column_map[l.args[0]]: # type: ignore
741
+ assert isinstance(l.args[0], mm.Var)
742
+ var = self.translate_value(l.args[1], l, ctx)
743
+ col_var = self.column_map[l.args[0]][l.relation] # ensure entry exists
744
+ if var != col_var:
745
+ return v0.Lookup(
746
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
747
+ relation=v0_builtins.eq,
748
+ args=(var, col_var), # type: ignore
749
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
750
+ )
751
+ else:
752
+ return None
753
+
754
+ relation, args = self._resolve_reading(l, ctx)
755
+ if relation is None:
756
+ return None
757
+
758
+ # External Table Column lookups
759
+ # we have to take the 6nf column relations and pull them into a single wide lookup
760
+ # making sure that the variable get mapped correctly. To match the expectations of
761
+ # v0, we also have to make sure that if we're looking up the table row itself, that
762
+ # it is wrapped in its own logical
763
+ root_type = l.relation.fields[0].type
764
+ if isinstance(root_type, mm.Table):
765
+ self.used_tables.add(root_type)
766
+ assert isinstance(l.args[0], mm.Var)
767
+ is_col = l.relation in root_type.columns
768
+ is_table = l.relation == root_type
769
+ if is_col:
770
+ self.column_map[l.args[0]][l.relation] = args[-1]
771
+ # we always lookup the full table, so replace the relation and args
772
+ relation = self.translate_node(root_type, l, ctx)
773
+
774
+ # this is a lookup on the table itself or the columns, translate to the column vars
775
+ if is_col or is_table:
776
+ mapped = self.column_map.get(l.args[0], {})
777
+ col_args = []
778
+ for col in root_type.columns:
779
+ v = mapped.setdefault(col, v0.Var(
780
+ type=self.translate_node(col.fields[-1].type, col, Context.MODEL), # type: ignore
781
+ name=f"{col.name}"
782
+ ))
783
+ col_args.append(v)
784
+ args = tuple([args[0], *col_args]) # type: ignore
785
+
786
+ # Specific rewrites
787
+ rewrite = self.rewrite_lookup(l, parent, ctx)
788
+ if rewrite is None:
789
+ # General translation
790
+ rewrite = v0.Lookup(
791
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
792
+ relation=relation, # type: ignore
793
+ args=args,
794
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
795
+ )
796
+
797
+ return rewrite
798
+
799
+
800
+ def translate_update(self, u: mm.Update, parent, ctx) -> v0.Update|v0.Output|None:
801
+ if isinstance(u.relation, mm.Table):
802
+ # ignore updates to tables for now
803
+ return None
804
+
805
+ if is_output_update(u):
806
+ # this is an output, the last arg is the value for the output column, the other
807
+ # args are part of the key
808
+
809
+ # get the list of key vars created during construction
810
+ keys = list(self.key_map[u.args[0]]) # type: ignore
811
+ # if there are no keys in the key map, this is a constructor of output without
812
+ # keys; we still need to remove the output from the args, so count is 1
813
+ arg_count = len(keys) if keys else 1
814
+ # append any other args used for the key
815
+ for arg in u.args[arg_count:-1]:
816
+ x = self.translate_value(arg, u, ctx)
817
+ keys.append(x) # type: ignore
818
+ if any(anno.relation is b.core["output_value_is_key"] for anno in u.annotations):
819
+ # if the output_value_is_key annotation is present, add the output value to the keys
820
+ keys.append(self.translate_value(u.args[-1], u, ctx)) # type: ignore
821
+
822
+ # there will be a single alias here, the output column
823
+ aliases = ordered_set((u.relation.name, self.translate_value(u.args[-1], u, ctx))).frozen()
824
+
825
+ out = v0.Output(
826
+ engine=self.translate_reasoner(u.reasoner, u, Context.MODEL),
827
+ keys=frozen(*keys), # type: ignore
828
+ aliases=aliases,
829
+ annotations=self.translate_frozen(u.annotations, u, ctx) # type: ignore
830
+ )
831
+ table = u.relation.fields[0].type
832
+ if isinstance(table, mm.Table) and not table.uri.startswith("dataframe://"):
833
+ self.exports.add(out)
834
+ return out
835
+ else:
836
+ relation, args = self._resolve_reading(u, ctx)
837
+
838
+ return v0.Update(
839
+ engine=self.translate_reasoner(u.reasoner, u, Context.MODEL),
840
+ relation=relation, # type: ignore
841
+ args=args,
842
+ effect=self.translate_effect(u.effect, u, ctx),
843
+ annotations=self.translate_frozen(u.annotations, u, ctx) # type: ignore
844
+ )
845
+
846
+ def _resolve_reading(self, task: mm.Lookup|mm.Update, ctx):
847
+ relation = self.translate_node(task.relation, task, ctx)
848
+ args = tuple(self.translate_value(arg, task, ctx) for arg in task.args)
849
+ if isinstance(relation, seq):
850
+ # Updates should always write to the root so that the reading maintenance rules
851
+ # can populate the other readings
852
+ if task.reading_hint is not None and isinstance(task, mm.Lookup):
853
+ relation = relation[task.relation.readings.index(task.reading_hint)]
854
+ args = tuple([args[i] for i in task.reading_hint.field_order])
855
+ else:
856
+ relation = relation[0]
857
+
858
+ return relation, args
859
+
860
+
861
+ def translate_aggregate(self, a: mm.Aggregate, parent, ctx) -> v0.Aggregate:
862
+
863
+ # hoist the return variables (those that are not inputs to the aggregation)
864
+ return_args = []
865
+ for field, arg in zip(a.aggregation.fields, a.args):
866
+ if not field.input:
867
+ return_args.append(arg)
868
+ hoisted=self.translate_seq(return_args, a, ctx)
869
+
870
+ # body must contain the aggregate body plus the aggregate itself
871
+ body = self.translate_node(a.body, a, ctx)
872
+ body = list(body.body if isinstance(body, v0.Logical) else [body])
873
+
874
+ # construct the aggregate node
875
+ engine = self.translate_reasoner(a.reasoner, a, Context.MODEL)
876
+ aggregation = self.translate_node(a.aggregation, a, ctx)
877
+ projection = self.translate_seq(a.projection, a, ctx)
878
+ group = self.translate_seq(a.group, a, ctx)
879
+ args = tuple(self.translate_value(arg, a, ctx) for arg in a.args)
880
+ annotations = self.translate_frozen(a.annotations, a, ctx)
881
+
882
+ v0_agg = None
883
+ if a.aggregation == b.aggregates.rank:
884
+ assert isinstance(args[0], tuple)
885
+ assert isinstance(args[1], tuple)
886
+ v0_agg = v0.Rank(engine, projection, group, args[0], tuple(l.value for l in args[1]), args[-1], 0, annotations,) # type: ignore
887
+ elif a.aggregation == b.aggregates.limit:
888
+ assert isinstance(args[0], v0.Literal)
889
+ assert isinstance(args[1], tuple)
890
+ assert isinstance(args[2], tuple)
891
+ result = v0.Var(type=v0_types.Int64, name="limit_result")
892
+ v0_agg = v0.Rank(engine, projection, group, args[1], tuple(l.value for l in args[2]), result, args[0].value, annotations,) # type: ignore
893
+ else:
894
+ v0_agg = v0.Aggregate(engine, aggregation, projection, group, args, annotations) # type: ignore
895
+
896
+ body.append(v0_agg)
897
+ return v0.Logical(
898
+ engine=None,
899
+ hoisted=hoisted, # type: ignore
900
+ body=tuple(body) # type: ignore
901
+ )
902
+
903
+ def translate_construct(self, c: mm.Construct, parent, ctx) -> v0.Construct|None:
904
+ if isinstance(c.id_var.type, mm.Table):
905
+ # we are constructing the key for an output. If there are no values, there is no
906
+ # key in v0, so we can just ignore this
907
+ if not c.values:
908
+ self.key_map[c.id_var] = []
909
+ return None
910
+ # now create a new v0 var to represent the hashed key, record that this key is
911
+ # to be used by updates, and generate the constructor
912
+ v = v0.Var(type=v0_types.Hash, name=c.id_var.name)
913
+ self.key_map[c.id_var] = [v]
914
+ values = [v0_types.Hash]
915
+ values.extend(self.translate_seq(c.values, c, ctx)) # type: ignore
916
+ return v0.Construct(
917
+ engine=self.translate_reasoner(c.reasoner, c, Context.MODEL),
918
+ values=tuple(values), # type: ignore
919
+ id_var=v,
920
+ annotations=self.translate_frozen(c.annotations, c, ctx) # type: ignore
921
+ )
922
+ return v0.Construct(
923
+ engine=self.translate_reasoner(c.reasoner, c, Context.MODEL),
924
+ values=self.translate_seq(c.values, c, ctx), # type: ignore
925
+ id_var=self.translate_node(c.id_var, c, ctx), # type: ignore
926
+ annotations=self.translate_frozen(c.annotations, c, ctx) # type: ignore
927
+ )
928
+
929
+
930
+ def translate_data(self, d: mm.Data, parent, ctx):
931
+ if isinstance(parent, mm.Field) or isinstance(parent, mm.Var):
932
+ return v0_types.Int128
933
+
934
+ # -----------------------------------------------------------------------------
935
+ # Model
936
+ # -----------------------------------------------------------------------------
937
+
938
+ def translate_model(self, source_model: mm.Model, parent=None, ctx=None) -> v0.Model:
939
+ try:
940
+ # first analyze the model to compute variables that need to be hoisted
941
+ self.hoister.analyze(source_model)
942
+
943
+ self.relations_by_name = defaultdict(list)
944
+ for r in source_model.relations:
945
+ self.relations_by_name[r.name].append(r)
946
+
947
+ # translate root first as it may create relations from types (e.g. concept populations)
948
+ root = self.translate_node(source_model.root, source_model, Context.TASK)
949
+
950
+ # translate all declared relations
951
+ relations:OrderedSet[v0.Relation] = ordered_set(*self.translate_seq(source_model.relations, source_model, Context.MODEL)) # type: ignore
952
+ # add relations created during task translation
953
+ relations.update(filter_by_type(self.task_map.values(), v0.Relation)) # type: ignore
954
+ # v0 needs all overloads also added to the model
955
+ for r in list(relations):
956
+ relations.update(r.overloads) # type: ignore
957
+
958
+ # if there are reading maintenance rules, add them as well
959
+ if self.maintenance_rules:
960
+ root = v0.Logical(
961
+ engine=None,
962
+ hoisted=(),
963
+ body=(
964
+ root, # type: ignore
965
+ *self.maintenance_rules
966
+ ),
967
+ annotations=frozen()
968
+ )
969
+ engines=self.translate_frozen(source_model.reasoners, source_model, Context.MODEL) # type: ignore
970
+ types=self.translate_frozen(source_model.types, source_model, Context.MODEL) # type: ignore
971
+
972
+ return v0.Model(
973
+ engines=engines, # type: ignore
974
+ relations=relations.frozen(), # type: ignore
975
+ types=types, # type: ignore
976
+ root=root # type: ignore
977
+ )
978
+ finally:
979
+ self.hoister.clear()
980
+
981
+ # -----------------------------------------------------------------------------
982
+ # Translate query
983
+ # -----------------------------------------------------------------------------
984
+
985
+ def translate_query(self, source_query: mm.Task) -> v0.Logical:
986
+ try:
987
+ # first analyze the model to compute variables that need to be hoisted
988
+ self.hoister.analyze_task(source_query)
989
+
990
+ # translate the query logical
991
+ return self.translate_node(source_query, source_query, Context.TASK) # type: ignore
992
+ finally:
993
+ self.hoister.clear()
994
+
995
+ # -----------------------------------------------------------------------------
996
+ # Library-specific rewrites
997
+ # -----------------------------------------------------------------------------
998
+
999
+ def adjust_index(self, l: mm.Lookup, indices: list[int], ctx, args=None, no_outputs=False):
1000
+ """ Rewrite the lookup such that the args at `indices` are adjusted to convert from
1001
+ 0-based indexing (as in the mm) to 1-based indexing (as in v0's backend).
1002
+
1003
+ If the field at the given index is input, we increment the arg by 1 before passing
1004
+ it to the lookup. If the field is output, we create a tmp var to hold the result
1005
+ of the lookup, and then create a subsequent task to decrement the tmp var by 1.
1006
+
1007
+ `args` can be used to provide a different set of args than l.args, in case they need
1008
+ reordering (e.g. strings.split).
1009
+ """
1010
+ if args is None:
1011
+ args = l.args
1012
+ # vars to hold the result from the v0 lookup
1013
+ tmps = {}
1014
+ for i in indices:
1015
+ index_type = l.relation.fields[i].type
1016
+ tmps[i] = mm.Var(type=index_type, name=f"tmp")
1017
+ # insert tmp at index
1018
+ replaced_args = []
1019
+ for i, arg in enumerate(args):
1020
+ if i in indices:
1021
+ replaced_args.append(tmps[i])
1022
+ else:
1023
+ replaced_args.append(arg)
1024
+ # translate the lookup
1025
+ lookup = v0.Lookup(
1026
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
1027
+ relation=self.translate_node(l.relation), # type: ignore
1028
+ args=tuple(self.translate_value(arg, l, ctx) for arg in replaced_args),
1029
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
1030
+ )
1031
+ # subtract 1 from the index to convert from 1-based to 0-based
1032
+ tasks = []
1033
+ for index in indices:
1034
+ arg = args[index]
1035
+ if isinstance(arg, mm.Literal):
1036
+ if l.relation.fields[index].input:
1037
+ new = mm.Literal(arg.type, arg.value + 1) # type: ignore
1038
+ else:
1039
+ new = mm.Literal(arg.type, arg.value + 1) # type: ignore
1040
+ tasks.append(v0.Lookup(
1041
+ engine=None,
1042
+ relation=v0_builtins.eq, # type: ignore
1043
+ args=(
1044
+ self.translate_value(tmps[index], lookup, ctx),
1045
+ self.translate_value(new, lookup, ctx),
1046
+ )
1047
+ ))
1048
+ elif l.relation.fields[index].input:
1049
+ tasks.append(v0.Lookup(
1050
+ engine=None,
1051
+ relation=v0_builtins.plus, # type: ignore
1052
+ args=(
1053
+ self.translate_value(args[index], lookup, ctx),
1054
+ v0.Literal(v0_types.Int128, 1),
1055
+ self.translate_value(tmps[index], lookup, ctx),
1056
+ ),
1057
+ )
1058
+ )
1059
+ else:
1060
+ tasks.append(v0.Lookup(
1061
+ engine=None,
1062
+ relation=v0_builtins.minus, # type: ignore
1063
+ args=(
1064
+ self.translate_value(tmps[index], lookup, ctx),
1065
+ v0.Literal(v0_types.Int128, 1),
1066
+ self.translate_value(args[index], lookup, ctx),
1067
+ ),
1068
+ )
1069
+ )
1070
+ # do casts
1071
+ tasks.extend(self.cast(lookup, ctx, no_outputs=no_outputs))
1072
+
1073
+ return tasks
1074
+
1075
+ def decrement(self, l: mm.Lookup, index: int, ctx):
1076
+ """ Rewrite the lookup such that the arg at `index` is decremented by 1 before the
1077
+ lookup. """
1078
+ tmp = self.translate_value(mm.Var(type=b.core.Number, name="tmp"), l, ctx)
1079
+ # lookup(..., tmp, ...)
1080
+ new = v0.Lookup(
1081
+ engine=None,
1082
+ relation=self.translate_node(l.relation), # type: ignore
1083
+ args=tuple(self.translate_value(arg, l, ctx) if i != index else tmp for i, arg in enumerate(l.args)),
1084
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
1085
+ )
1086
+ casted = self.cast(new, ctx)
1087
+ return (
1088
+ # tmp = l.args[index] - 1
1089
+ v0.Lookup(
1090
+ engine=None,
1091
+ relation=v0_builtins.minus, # type: ignore
1092
+ args=(
1093
+ self.translate_value(l.args[index], l, ctx),
1094
+ v0.Literal(v0_types.Int128, 1),
1095
+ tmp,
1096
+ ),
1097
+ ),
1098
+ *casted
1099
+ )
1100
+
1101
+ def cast(self, l: v0.Lookup, ctx, no_outputs=False):
1102
+ # note that everything here is in v0
1103
+ inputs = []
1104
+ outputs = []
1105
+ args = []
1106
+ for arg, field in zip(l.args, l.relation.fields):
1107
+ target_type = field.type
1108
+ if target_type is None or not isinstance(arg, (v0.Var, v0.Literal)) or arg.type == target_type:
1109
+ args.append(arg)
1110
+ continue
1111
+ if field.input:
1112
+ cast_var = v0.Var(type=target_type, name="cast_var")
1113
+ args.append(cast_var)
1114
+ inputs.append(v0.Lookup(
1115
+ engine=None,
1116
+ relation=v0_builtins.cast, # type: ignore
1117
+ args=(target_type, arg, cast_var),
1118
+ ))
1119
+ elif not no_outputs:
1120
+ cast_var = v0.Var(type=target_type, name="cast_var")
1121
+ args.append(cast_var)
1122
+ outputs.append(v0.Lookup(
1123
+ engine=None,
1124
+ relation=v0_builtins.cast, # type: ignore
1125
+ args=(arg.type, cast_var, arg),
1126
+ ))
1127
+ else:
1128
+ # This is ridiculous, but there are cases where we need to force the type
1129
+ # of the var, but not through an actual cast operation. E.g. due to the way
1130
+ # the LQP stack handles dates.
1131
+ object.__setattr__(arg, 'type', target_type)
1132
+ args.append(arg)
1133
+
1134
+ lookup = v0.Lookup(
1135
+ engine=l.engine,
1136
+ relation=l.relation,
1137
+ args=tuple(args),
1138
+ annotations=l.annotations
1139
+ )
1140
+ if no_outputs:
1141
+ outputs = []
1142
+ return [*inputs, lookup, *outputs]
1143
+
1144
+ def rewrite_lookup(self, l: mm.Lookup, parent, ctx):
1145
+ """ Special cases for v1 builtins that either have some different shape in v0 or
1146
+ do not exist as a primitive in the engine, so we want to compose the result so that
1147
+ LQP works. Return None if no rewrite is needed.
1148
+
1149
+ Note that this type of adjustment will need to be made by emitters anyways, so we
1150
+ will want to have a good API for them. But in that case, they should do
1151
+ transformations still in the mm, whereas this is doing it during translation to v0.
1152
+ """
1153
+
1154
+ # -----------------------------------------------------------------------------
1155
+ # Common
1156
+ # -----------------------------------------------------------------------------
1157
+ if l.relation == b.common.range:
1158
+ # python/PyRel range has inclusive start but exclusive stop, whereas LQP/Rel has
1159
+ # inclusive stop, so we have to decrement the stop index by 1
1160
+ # tmp, lookup = self.decrement(l, 1, ctx)
1161
+ # return [tmp] + self.cast(lookup, [v0_types.Int64, v0_types.Int64, v0_types.Int64, v0_types.Int64], ctx)
1162
+ return self.decrement(l, 1, ctx)
1163
+
1164
+ elif l.relation == b.core.cast:
1165
+ return v0.Lookup(
1166
+ engine=self.translate_reasoner(l.reasoner, l, Context.TASK),
1167
+ relation=v0_builtins.builtin_relations_by_name["cast"], # type: ignore
1168
+ args=(
1169
+ self.translate_value(l.args[0], l, Context.MODEL),
1170
+ self.translate_value(l.args[1], l, Context.TASK),
1171
+ self.translate_value(l.args[2], l, Context.TASK)
1172
+ ),
1173
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
1174
+ )
1175
+
1176
+ # -----------------------------------------------------------------------------
1177
+ # Strings
1178
+ # -----------------------------------------------------------------------------
1179
+
1180
+ elif l.relation == b.strings.len:
1181
+ lookup = v0.Lookup(
1182
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
1183
+ relation=v0_builtins.builtin_relations_by_name["num_chars"], # type: ignore
1184
+ args=(
1185
+ self.translate_value(l.args[0], l, ctx),
1186
+ self.translate_value(l.args[1], l, ctx),
1187
+ ),
1188
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
1189
+ )
1190
+ return self.cast(lookup, ctx)
1191
+
1192
+ elif l.relation == b.strings.split:
1193
+ # swap first two args because that's how rel and v0 expect them
1194
+ args = l.args[1], l.args[0], l.args[2], l.args[3]
1195
+ return self.adjust_index(l, [2], ctx, args=args)
1196
+
1197
+ elif l.relation == b.strings.substring:
1198
+ return self.adjust_index(l, [1], ctx)
1199
+
1200
+ # -----------------------------------------------------------------------------
1201
+ # RE
1202
+ # -----------------------------------------------------------------------------
1203
+ elif l.relation == b.re.regex_match_all:
1204
+ return self.adjust_index(l, [2], ctx)
1205
+
1206
+ # -----------------------------------------------------------------------------
1207
+ # Math
1208
+ # -----------------------------------------------------------------------------
1209
+ elif l.relation == b.math.degrees:
1210
+ # degrees(radians, x) = /(radians, (pi/180.0), x)
1211
+ return v0.Lookup(
1212
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
1213
+ relation=v0_builtins.builtin_relations_by_name["/"], # type: ignore
1214
+ args=(
1215
+ self.translate_value(l.args[0], l, ctx),
1216
+ v0.Literal(v0_types.Float, pi / 180.0),
1217
+ self.translate_value(l.args[1], l, ctx)
1218
+ ),
1219
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
1220
+ )
1221
+ elif l.relation == b.math.radians:
1222
+ # radians(degrees, x) = /(degrees, (180.0/pi), x)
1223
+ return v0.Lookup(
1224
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
1225
+ relation=v0_builtins.builtin_relations_by_name["/"], # type: ignore
1226
+ args=(
1227
+ self.translate_value(l.args[0], l, ctx),
1228
+ v0.Literal(v0_types.Float, 180.0 / pi),
1229
+ self.translate_value(l.args[1], l, ctx)
1230
+ ),
1231
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
1232
+ )
1233
+
1234
+ # -----------------------------------------------------------------------------
1235
+ # Datetime
1236
+ # -----------------------------------------------------------------------------
1237
+ #
1238
+ # elif l.relation == b.datetime.date_range:
1239
+ # return self.rewrite_date_range(l, parent, ctx)
1240
+ # elif l.relation == b.datetime.datetime_range:
1241
+ # pass
1242
+
1243
+ elif l.relation == b.datetime.date_add:
1244
+ return v0.Lookup(
1245
+ engine=self.translate_reasoner(l.reasoner, l, Context.MODEL),
1246
+ relation=self.translate_relation(l.relation, l, ctx), # type: ignore
1247
+ args=self.translate_seq(l.args, l, ctx), # type: ignore
1248
+ annotations=self.translate_frozen(l.annotations, l, ctx) # type: ignore
1249
+ )
1250
+
1251
+ if b.datetime[l.relation.name] is l.relation:
1252
+ return self.adjust_index(l, [], ctx, no_outputs=True)
1253
+
1254
+ v0_rel = self.translate_node(l.relation, l, ctx)
1255
+ if isinstance(v0_rel, v0.Relation) and any(f.type == v0_types.Int64 for f in v0_rel.fields):
1256
+ return self.adjust_index(l, [], ctx)
1257
+
1258
+ return None
1259
+
1260
+
1261
+ # TODO - Currently implemented in the std.datetime itself.
1262
+ # def rewrite_date_range(self, l: mm.Lookup, parent, ctx: Context):
1263
+ # start, end, freq, date = l.args
1264
+ # result = []
1265
+
1266
+ # range_end = num_days = mm.Var(type=b.core.Number, name="num_days")
1267
+ # result.append(mm.Lookup(b.datetime.dates_period_days, (start, end, num_days)))
1268
+
1269
+ # assert isinstance(freq, mm.Literal) and isinstance(freq.value, str)
1270
+ # if freq.value in ["W", "M", "Y"]:
1271
+ # range_end = mm.Var(type=b.core.Number, name="range_end")
1272
+ # x = mm.Var(type=b.core.Number, name="x")
1273
+ # result.append(mm.Lookup(b.core.mul, (num_days, mm.Literal(b.core.Float, _days[freq.value]), x)))
1274
+ # result.append(mm.Lookup(b.math.ceil, (x, range_end)))
1275
+
1276
+ # # date_range is inclusive. add 1 since std.range is exclusive
1277
+ # tmp = mm.Var(type=b.core.Number, name="tmp")
1278
+ # result.append(mm.Lookup(b.core["+"], (range_end, mm.Literal(b.core.Number, 1), tmp)))
1279
+ # ix = mm.Var(type=b.core.Number, name="ix")
1280
+ # result.append(mm.Lookup(b.common.range, (mm.Literal(b.core.Number, 0), tmp, mm.Literal(b.core.Number, 1), ix)))
1281
+
1282
+ # tmp2 = mm.Var(type=b.core.Number, name="tmp2")
1283
+ # result.append(mm.Lookup(_periods[freq.value], (ix, tmp2)))
1284
+ # result.append(mm.Lookup(b.datetime.date_add, (start, tmp2, date)))
1285
+
1286
+ # result.append(mm.Lookup(b.core[">="], (end, date)))
1287
+
1288
+ # return self.translate_node(mm.Logical(
1289
+ # body=tuple(result)
1290
+ # ))