relationalai 0.13.5__py3-none-any.whl → 1.0.0a2__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 (856) 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/config/shims.py +1 -0
  16. relationalai/semantics/__init__.py +146 -22
  17. relationalai/semantics/backends/lqp/annotations.py +11 -0
  18. relationalai/semantics/backends/sql/sql_compiler.py +327 -0
  19. relationalai/semantics/frontend/base.py +1719 -0
  20. relationalai/semantics/frontend/core.py +179 -0
  21. relationalai/semantics/frontend/front_compiler.py +1316 -0
  22. relationalai/semantics/frontend/pprint.py +408 -0
  23. relationalai/semantics/metamodel/__init__.py +6 -40
  24. relationalai/semantics/metamodel/builtins.py +206 -772
  25. relationalai/semantics/metamodel/metamodel.py +465 -0
  26. relationalai/semantics/metamodel/metamodel_analyzer.py +519 -0
  27. relationalai/semantics/metamodel/pprint.py +414 -0
  28. relationalai/semantics/metamodel/rewriter.py +266 -0
  29. relationalai/semantics/metamodel/typer.py +1213 -0
  30. relationalai/semantics/std/__init__.py +60 -40
  31. relationalai/semantics/std/aggregates.py +148 -0
  32. relationalai/semantics/std/common.py +44 -0
  33. relationalai/semantics/std/constraints.py +37 -43
  34. relationalai/semantics/std/datetime.py +249 -135
  35. relationalai/semantics/std/decimals.py +45 -52
  36. relationalai/semantics/std/floats.py +13 -5
  37. relationalai/semantics/std/integers.py +26 -11
  38. relationalai/semantics/std/math.py +183 -112
  39. relationalai/semantics/std/numbers.py +86 -0
  40. relationalai/semantics/std/re.py +80 -62
  41. relationalai/semantics/std/strings.py +101 -46
  42. relationalai/shims/executor.py +179 -0
  43. relationalai/shims/helpers.py +126 -0
  44. relationalai/shims/hoister.py +221 -0
  45. relationalai/shims/mm2v0.py +1394 -0
  46. relationalai/tools/cli/__init__.py +6 -0
  47. relationalai/tools/cli/cli.py +90 -0
  48. relationalai/tools/cli/components/__init__.py +5 -0
  49. relationalai/tools/cli/components/progress_reader.py +1524 -0
  50. relationalai/tools/cli/components/utils.py +58 -0
  51. relationalai/tools/cli/config_template.py +45 -0
  52. relationalai/tools/cli/dev.py +19 -0
  53. relationalai/tools/debugger.py +289 -183
  54. relationalai/tools/typer_debugger.py +93 -0
  55. relationalai/util/dataclasses.py +43 -0
  56. relationalai/util/docutils.py +40 -0
  57. relationalai/util/error.py +199 -0
  58. relationalai/util/format.py +48 -109
  59. relationalai/util/naming.py +145 -0
  60. relationalai/util/python.py +35 -0
  61. relationalai/util/runtime.py +156 -0
  62. relationalai/util/schema.py +197 -0
  63. relationalai/util/source.py +185 -0
  64. relationalai/util/structures.py +163 -0
  65. relationalai/util/tracing.py +261 -0
  66. relationalai-1.0.0a2.dist-info/METADATA +44 -0
  67. relationalai-1.0.0a2.dist-info/RECORD +489 -0
  68. relationalai-1.0.0a2.dist-info/WHEEL +5 -0
  69. relationalai-1.0.0a2.dist-info/entry_points.txt +3 -0
  70. relationalai-1.0.0a2.dist-info/top_level.txt +2 -0
  71. v0/relationalai/__init__.py +216 -0
  72. v0/relationalai/clients/__init__.py +5 -0
  73. v0/relationalai/clients/azure.py +477 -0
  74. v0/relationalai/clients/client.py +912 -0
  75. v0/relationalai/clients/config.py +673 -0
  76. v0/relationalai/clients/direct_access_client.py +118 -0
  77. v0/relationalai/clients/hash_util.py +31 -0
  78. v0/relationalai/clients/local.py +571 -0
  79. v0/relationalai/clients/profile_polling.py +73 -0
  80. v0/relationalai/clients/result_helpers.py +420 -0
  81. v0/relationalai/clients/snowflake.py +3869 -0
  82. v0/relationalai/clients/types.py +113 -0
  83. v0/relationalai/clients/use_index_poller.py +980 -0
  84. v0/relationalai/clients/util.py +356 -0
  85. v0/relationalai/debugging.py +389 -0
  86. v0/relationalai/dsl.py +1749 -0
  87. v0/relationalai/early_access/builder/__init__.py +30 -0
  88. v0/relationalai/early_access/builder/builder/__init__.py +35 -0
  89. v0/relationalai/early_access/builder/snowflake/__init__.py +12 -0
  90. v0/relationalai/early_access/builder/std/__init__.py +25 -0
  91. v0/relationalai/early_access/builder/std/decimals/__init__.py +12 -0
  92. v0/relationalai/early_access/builder/std/integers/__init__.py +12 -0
  93. v0/relationalai/early_access/builder/std/math/__init__.py +12 -0
  94. v0/relationalai/early_access/builder/std/strings/__init__.py +14 -0
  95. v0/relationalai/early_access/devtools/__init__.py +12 -0
  96. v0/relationalai/early_access/devtools/benchmark_lqp/__init__.py +12 -0
  97. v0/relationalai/early_access/devtools/extract_lqp/__init__.py +12 -0
  98. v0/relationalai/early_access/dsl/adapters/orm/adapter_qb.py +427 -0
  99. v0/relationalai/early_access/dsl/adapters/orm/parser.py +636 -0
  100. v0/relationalai/early_access/dsl/adapters/owl/adapter.py +176 -0
  101. v0/relationalai/early_access/dsl/adapters/owl/parser.py +160 -0
  102. v0/relationalai/early_access/dsl/bindings/common.py +402 -0
  103. v0/relationalai/early_access/dsl/bindings/csv.py +170 -0
  104. v0/relationalai/early_access/dsl/bindings/legacy/binding_models.py +143 -0
  105. v0/relationalai/early_access/dsl/bindings/snowflake.py +64 -0
  106. v0/relationalai/early_access/dsl/codegen/binder.py +411 -0
  107. v0/relationalai/early_access/dsl/codegen/common.py +79 -0
  108. v0/relationalai/early_access/dsl/codegen/helpers.py +23 -0
  109. v0/relationalai/early_access/dsl/codegen/relations.py +700 -0
  110. v0/relationalai/early_access/dsl/codegen/weaver.py +417 -0
  111. v0/relationalai/early_access/dsl/core/builders/__init__.py +47 -0
  112. v0/relationalai/early_access/dsl/core/builders/logic.py +19 -0
  113. v0/relationalai/early_access/dsl/core/builders/scalar_constraint.py +11 -0
  114. v0/relationalai/early_access/dsl/core/constraints/predicate/atomic.py +455 -0
  115. v0/relationalai/early_access/dsl/core/constraints/predicate/universal.py +73 -0
  116. v0/relationalai/early_access/dsl/core/constraints/scalar.py +310 -0
  117. v0/relationalai/early_access/dsl/core/context.py +13 -0
  118. v0/relationalai/early_access/dsl/core/cset.py +132 -0
  119. v0/relationalai/early_access/dsl/core/exprs/__init__.py +116 -0
  120. v0/relationalai/early_access/dsl/core/exprs/relational.py +18 -0
  121. v0/relationalai/early_access/dsl/core/exprs/scalar.py +412 -0
  122. v0/relationalai/early_access/dsl/core/instances.py +44 -0
  123. v0/relationalai/early_access/dsl/core/logic/__init__.py +193 -0
  124. v0/relationalai/early_access/dsl/core/logic/aggregation.py +98 -0
  125. v0/relationalai/early_access/dsl/core/logic/exists.py +223 -0
  126. v0/relationalai/early_access/dsl/core/logic/helper.py +163 -0
  127. v0/relationalai/early_access/dsl/core/namespaces.py +32 -0
  128. v0/relationalai/early_access/dsl/core/relations.py +276 -0
  129. v0/relationalai/early_access/dsl/core/rules.py +112 -0
  130. v0/relationalai/early_access/dsl/core/std/__init__.py +45 -0
  131. v0/relationalai/early_access/dsl/core/temporal/recall.py +6 -0
  132. v0/relationalai/early_access/dsl/core/types/__init__.py +270 -0
  133. v0/relationalai/early_access/dsl/core/types/concepts.py +128 -0
  134. v0/relationalai/early_access/dsl/core/types/constrained/__init__.py +267 -0
  135. v0/relationalai/early_access/dsl/core/types/constrained/nominal.py +143 -0
  136. v0/relationalai/early_access/dsl/core/types/constrained/subtype.py +124 -0
  137. v0/relationalai/early_access/dsl/core/types/standard.py +92 -0
  138. v0/relationalai/early_access/dsl/core/types/unconstrained.py +50 -0
  139. v0/relationalai/early_access/dsl/core/types/variables.py +203 -0
  140. v0/relationalai/early_access/dsl/ir/compiler.py +318 -0
  141. v0/relationalai/early_access/dsl/ir/executor.py +260 -0
  142. v0/relationalai/early_access/dsl/ontologies/constraints.py +88 -0
  143. v0/relationalai/early_access/dsl/ontologies/export.py +30 -0
  144. v0/relationalai/early_access/dsl/ontologies/models.py +453 -0
  145. v0/relationalai/early_access/dsl/ontologies/python_printer.py +303 -0
  146. v0/relationalai/early_access/dsl/ontologies/readings.py +60 -0
  147. v0/relationalai/early_access/dsl/ontologies/relationships.py +322 -0
  148. v0/relationalai/early_access/dsl/ontologies/roles.py +87 -0
  149. v0/relationalai/early_access/dsl/ontologies/subtyping.py +55 -0
  150. v0/relationalai/early_access/dsl/orm/constraints.py +438 -0
  151. v0/relationalai/early_access/dsl/orm/measures/dimensions.py +200 -0
  152. v0/relationalai/early_access/dsl/orm/measures/initializer.py +16 -0
  153. v0/relationalai/early_access/dsl/orm/measures/measure_rules.py +275 -0
  154. v0/relationalai/early_access/dsl/orm/measures/measures.py +299 -0
  155. v0/relationalai/early_access/dsl/orm/measures/role_exprs.py +268 -0
  156. v0/relationalai/early_access/dsl/orm/models.py +256 -0
  157. v0/relationalai/early_access/dsl/orm/object_oriented_printer.py +344 -0
  158. v0/relationalai/early_access/dsl/orm/printer.py +469 -0
  159. v0/relationalai/early_access/dsl/orm/reasoners.py +480 -0
  160. v0/relationalai/early_access/dsl/orm/relations.py +19 -0
  161. v0/relationalai/early_access/dsl/orm/relationships.py +251 -0
  162. v0/relationalai/early_access/dsl/orm/types.py +42 -0
  163. v0/relationalai/early_access/dsl/orm/utils.py +79 -0
  164. v0/relationalai/early_access/dsl/orm/verb.py +204 -0
  165. v0/relationalai/early_access/dsl/physical_metadata/tables.py +133 -0
  166. v0/relationalai/early_access/dsl/relations.py +170 -0
  167. v0/relationalai/early_access/dsl/rulesets.py +69 -0
  168. v0/relationalai/early_access/dsl/schemas/__init__.py +450 -0
  169. v0/relationalai/early_access/dsl/schemas/builder.py +48 -0
  170. v0/relationalai/early_access/dsl/schemas/comp_names.py +51 -0
  171. v0/relationalai/early_access/dsl/schemas/components.py +203 -0
  172. v0/relationalai/early_access/dsl/schemas/contexts.py +156 -0
  173. v0/relationalai/early_access/dsl/schemas/exprs.py +89 -0
  174. v0/relationalai/early_access/dsl/schemas/fragments.py +464 -0
  175. v0/relationalai/early_access/dsl/serialization.py +79 -0
  176. v0/relationalai/early_access/dsl/serialize/exporter.py +163 -0
  177. v0/relationalai/early_access/dsl/snow/api.py +104 -0
  178. v0/relationalai/early_access/dsl/snow/common.py +76 -0
  179. v0/relationalai/early_access/dsl/state_mgmt/__init__.py +129 -0
  180. v0/relationalai/early_access/dsl/state_mgmt/state_charts.py +125 -0
  181. v0/relationalai/early_access/dsl/state_mgmt/transitions.py +130 -0
  182. v0/relationalai/early_access/dsl/types/__init__.py +40 -0
  183. v0/relationalai/early_access/dsl/types/concepts.py +12 -0
  184. v0/relationalai/early_access/dsl/types/entities.py +135 -0
  185. v0/relationalai/early_access/dsl/types/values.py +17 -0
  186. v0/relationalai/early_access/dsl/utils.py +102 -0
  187. v0/relationalai/early_access/graphs/__init__.py +13 -0
  188. v0/relationalai/early_access/lqp/__init__.py +12 -0
  189. v0/relationalai/early_access/lqp/compiler/__init__.py +12 -0
  190. v0/relationalai/early_access/lqp/constructors/__init__.py +18 -0
  191. v0/relationalai/early_access/lqp/executor/__init__.py +12 -0
  192. v0/relationalai/early_access/lqp/ir/__init__.py +12 -0
  193. v0/relationalai/early_access/lqp/passes/__init__.py +12 -0
  194. v0/relationalai/early_access/lqp/pragmas/__init__.py +12 -0
  195. v0/relationalai/early_access/lqp/primitives/__init__.py +12 -0
  196. v0/relationalai/early_access/lqp/types/__init__.py +12 -0
  197. v0/relationalai/early_access/lqp/utils/__init__.py +12 -0
  198. v0/relationalai/early_access/lqp/validators/__init__.py +12 -0
  199. v0/relationalai/early_access/metamodel/__init__.py +58 -0
  200. v0/relationalai/early_access/metamodel/builtins/__init__.py +12 -0
  201. v0/relationalai/early_access/metamodel/compiler/__init__.py +12 -0
  202. v0/relationalai/early_access/metamodel/dependency/__init__.py +12 -0
  203. v0/relationalai/early_access/metamodel/factory/__init__.py +17 -0
  204. v0/relationalai/early_access/metamodel/helpers/__init__.py +12 -0
  205. v0/relationalai/early_access/metamodel/ir/__init__.py +14 -0
  206. v0/relationalai/early_access/metamodel/rewrite/__init__.py +7 -0
  207. v0/relationalai/early_access/metamodel/typer/__init__.py +3 -0
  208. v0/relationalai/early_access/metamodel/typer/typer/__init__.py +12 -0
  209. v0/relationalai/early_access/metamodel/types/__init__.py +15 -0
  210. v0/relationalai/early_access/metamodel/util/__init__.py +15 -0
  211. v0/relationalai/early_access/metamodel/visitor/__init__.py +12 -0
  212. v0/relationalai/early_access/rel/__init__.py +12 -0
  213. v0/relationalai/early_access/rel/executor/__init__.py +12 -0
  214. v0/relationalai/early_access/rel/rel_utils/__init__.py +12 -0
  215. v0/relationalai/early_access/rel/rewrite/__init__.py +7 -0
  216. v0/relationalai/early_access/solvers/__init__.py +19 -0
  217. v0/relationalai/early_access/sql/__init__.py +11 -0
  218. v0/relationalai/early_access/sql/executor/__init__.py +3 -0
  219. v0/relationalai/early_access/sql/rewrite/__init__.py +3 -0
  220. v0/relationalai/early_access/tests/logging/__init__.py +12 -0
  221. v0/relationalai/early_access/tests/test_snapshot_base/__init__.py +12 -0
  222. v0/relationalai/early_access/tests/utils/__init__.py +12 -0
  223. v0/relationalai/environments/__init__.py +35 -0
  224. v0/relationalai/environments/base.py +381 -0
  225. v0/relationalai/environments/colab.py +14 -0
  226. v0/relationalai/environments/generic.py +71 -0
  227. v0/relationalai/environments/ipython.py +68 -0
  228. v0/relationalai/environments/jupyter.py +9 -0
  229. v0/relationalai/environments/snowbook.py +169 -0
  230. v0/relationalai/errors.py +2478 -0
  231. v0/relationalai/experimental/SF.py +38 -0
  232. v0/relationalai/experimental/inspect.py +47 -0
  233. v0/relationalai/experimental/pathfinder/__init__.py +158 -0
  234. v0/relationalai/experimental/pathfinder/api.py +160 -0
  235. v0/relationalai/experimental/pathfinder/automaton.py +584 -0
  236. v0/relationalai/experimental/pathfinder/bridge.py +226 -0
  237. v0/relationalai/experimental/pathfinder/compiler.py +416 -0
  238. v0/relationalai/experimental/pathfinder/datalog.py +214 -0
  239. v0/relationalai/experimental/pathfinder/diagnostics.py +56 -0
  240. v0/relationalai/experimental/pathfinder/filter.py +236 -0
  241. v0/relationalai/experimental/pathfinder/glushkov.py +439 -0
  242. v0/relationalai/experimental/pathfinder/options.py +265 -0
  243. v0/relationalai/experimental/pathfinder/rpq.py +344 -0
  244. v0/relationalai/experimental/pathfinder/transition.py +200 -0
  245. v0/relationalai/experimental/pathfinder/utils.py +26 -0
  246. v0/relationalai/experimental/paths/api.py +143 -0
  247. v0/relationalai/experimental/paths/benchmarks/grid_graph.py +37 -0
  248. v0/relationalai/experimental/paths/examples/basic_example.py +40 -0
  249. v0/relationalai/experimental/paths/examples/minimal_engine_warmup.py +3 -0
  250. v0/relationalai/experimental/paths/examples/movie_example.py +77 -0
  251. v0/relationalai/experimental/paths/examples/paths_benchmark.py +115 -0
  252. v0/relationalai/experimental/paths/examples/paths_example.py +116 -0
  253. v0/relationalai/experimental/paths/examples/pattern_to_automaton.py +28 -0
  254. v0/relationalai/experimental/paths/find_paths_via_automaton.py +85 -0
  255. v0/relationalai/experimental/paths/graph.py +185 -0
  256. v0/relationalai/experimental/paths/path_algorithms/find_paths.py +280 -0
  257. v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +26 -0
  258. v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +111 -0
  259. v0/relationalai/experimental/paths/path_algorithms/single.py +59 -0
  260. v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +39 -0
  261. v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +103 -0
  262. v0/relationalai/experimental/paths/path_algorithms/usp-old.py +130 -0
  263. v0/relationalai/experimental/paths/path_algorithms/usp-tuple.py +183 -0
  264. v0/relationalai/experimental/paths/path_algorithms/usp.py +150 -0
  265. v0/relationalai/experimental/paths/product_graph.py +93 -0
  266. v0/relationalai/experimental/paths/rpq/automaton.py +584 -0
  267. v0/relationalai/experimental/paths/rpq/diagnostics.py +56 -0
  268. v0/relationalai/experimental/paths/rpq/rpq.py +378 -0
  269. v0/relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +90 -0
  270. v0/relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +119 -0
  271. v0/relationalai/experimental/paths/tests/tests_limit_sp_single.py +104 -0
  272. v0/relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +113 -0
  273. v0/relationalai/experimental/paths/tests/tests_limit_walks_single.py +149 -0
  274. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +70 -0
  275. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +64 -0
  276. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +115 -0
  277. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +75 -0
  278. v0/relationalai/experimental/paths/tests/tests_single_paths.py +152 -0
  279. v0/relationalai/experimental/paths/tests/tests_single_walks.py +208 -0
  280. v0/relationalai/experimental/paths/tests/tests_single_walks_undirected.py +297 -0
  281. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +107 -0
  282. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +76 -0
  283. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +76 -0
  284. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +110 -0
  285. v0/relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +229 -0
  286. v0/relationalai/experimental/paths/tests/tests_usp_nsp_single.py +108 -0
  287. v0/relationalai/experimental/paths/tree_agg.py +168 -0
  288. v0/relationalai/experimental/paths/utilities/iterators.py +27 -0
  289. v0/relationalai/experimental/paths/utilities/prefix_sum.py +91 -0
  290. v0/relationalai/experimental/solvers.py +1087 -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 +325 -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 +474 -0
  306. v0/relationalai/semantics/lqp/intrinsics.py +24 -0
  307. v0/relationalai/semantics/lqp/ir.py +124 -0
  308. v0/relationalai/semantics/lqp/model2lqp.py +877 -0
  309. v0/relationalai/semantics/lqp/passes.py +680 -0
  310. v0/relationalai/semantics/lqp/primitives.py +252 -0
  311. v0/relationalai/semantics/lqp/result_helpers.py +202 -0
  312. v0/relationalai/semantics/lqp/rewrite/__init__.py +18 -0
  313. v0/relationalai/semantics/lqp/rewrite/annotate_constraints.py +57 -0
  314. v0/relationalai/semantics/lqp/rewrite/cdc.py +216 -0
  315. v0/relationalai/semantics/lqp/rewrite/extract_common.py +338 -0
  316. v0/relationalai/semantics/lqp/rewrite/extract_keys.py +490 -0
  317. v0/relationalai/semantics/lqp/rewrite/function_annotations.py +114 -0
  318. v0/relationalai/semantics/lqp/rewrite/functional_dependencies.py +314 -0
  319. v0/relationalai/semantics/lqp/rewrite/quantify_vars.py +296 -0
  320. v0/relationalai/semantics/lqp/rewrite/splinter.py +76 -0
  321. v0/relationalai/semantics/lqp/types.py +101 -0
  322. v0/relationalai/semantics/lqp/utils.py +160 -0
  323. v0/relationalai/semantics/lqp/validators.py +57 -0
  324. v0/relationalai/semantics/metamodel/__init__.py +40 -0
  325. v0/relationalai/semantics/metamodel/builtins.py +776 -0
  326. v0/relationalai/semantics/metamodel/compiler.py +133 -0
  327. v0/relationalai/semantics/metamodel/dependency.py +862 -0
  328. v0/relationalai/semantics/metamodel/executor.py +61 -0
  329. v0/relationalai/semantics/metamodel/factory.py +287 -0
  330. v0/relationalai/semantics/metamodel/helpers.py +361 -0
  331. v0/relationalai/semantics/metamodel/ir.py +923 -0
  332. v0/relationalai/semantics/metamodel/rewrite/__init__.py +7 -0
  333. v0/relationalai/semantics/metamodel/rewrite/discharge_constraints.py +39 -0
  334. v0/relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +210 -0
  335. v0/relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +78 -0
  336. v0/relationalai/semantics/metamodel/rewrite/flatten.py +554 -0
  337. v0/relationalai/semantics/metamodel/rewrite/format_outputs.py +165 -0
  338. v0/relationalai/semantics/metamodel/typer/checker.py +353 -0
  339. v0/relationalai/semantics/metamodel/typer/typer.py +1395 -0
  340. v0/relationalai/semantics/metamodel/util.py +505 -0
  341. v0/relationalai/semantics/metamodel/visitor.py +944 -0
  342. v0/relationalai/semantics/reasoners/__init__.py +10 -0
  343. v0/relationalai/semantics/reasoners/graph/__init__.py +37 -0
  344. v0/relationalai/semantics/reasoners/graph/core.py +9019 -0
  345. v0/relationalai/semantics/reasoners/optimization/__init__.py +68 -0
  346. v0/relationalai/semantics/reasoners/optimization/common.py +88 -0
  347. v0/relationalai/semantics/reasoners/optimization/solvers_dev.py +568 -0
  348. v0/relationalai/semantics/reasoners/optimization/solvers_pb.py +1163 -0
  349. v0/relationalai/semantics/rel/builtins.py +40 -0
  350. v0/relationalai/semantics/rel/compiler.py +989 -0
  351. v0/relationalai/semantics/rel/executor.py +359 -0
  352. v0/relationalai/semantics/rel/rel.py +482 -0
  353. v0/relationalai/semantics/rel/rel_utils.py +276 -0
  354. v0/relationalai/semantics/snowflake/__init__.py +3 -0
  355. v0/relationalai/semantics/sql/compiler.py +2503 -0
  356. v0/relationalai/semantics/sql/executor/duck_db.py +52 -0
  357. v0/relationalai/semantics/sql/executor/result_helpers.py +64 -0
  358. v0/relationalai/semantics/sql/executor/snowflake.py +145 -0
  359. v0/relationalai/semantics/sql/rewrite/denormalize.py +222 -0
  360. v0/relationalai/semantics/sql/rewrite/double_negation.py +49 -0
  361. v0/relationalai/semantics/sql/rewrite/recursive_union.py +127 -0
  362. v0/relationalai/semantics/sql/rewrite/sort_output_query.py +246 -0
  363. v0/relationalai/semantics/sql/sql.py +504 -0
  364. v0/relationalai/semantics/std/__init__.py +54 -0
  365. v0/relationalai/semantics/std/constraints.py +43 -0
  366. v0/relationalai/semantics/std/datetime.py +363 -0
  367. v0/relationalai/semantics/std/decimals.py +62 -0
  368. v0/relationalai/semantics/std/floats.py +7 -0
  369. v0/relationalai/semantics/std/integers.py +22 -0
  370. v0/relationalai/semantics/std/math.py +141 -0
  371. v0/relationalai/semantics/std/pragmas.py +11 -0
  372. v0/relationalai/semantics/std/re.py +83 -0
  373. v0/relationalai/semantics/std/std.py +14 -0
  374. v0/relationalai/semantics/std/strings.py +63 -0
  375. v0/relationalai/semantics/tests/__init__.py +0 -0
  376. v0/relationalai/semantics/tests/test_snapshot_abstract.py +143 -0
  377. v0/relationalai/semantics/tests/test_snapshot_base.py +9 -0
  378. v0/relationalai/semantics/tests/utils.py +46 -0
  379. v0/relationalai/std/__init__.py +70 -0
  380. v0/relationalai/tools/__init__.py +0 -0
  381. v0/relationalai/tools/cli.py +1940 -0
  382. v0/relationalai/tools/cli_controls.py +1826 -0
  383. v0/relationalai/tools/cli_helpers.py +390 -0
  384. v0/relationalai/tools/debugger.py +183 -0
  385. v0/relationalai/tools/debugger_client.py +109 -0
  386. v0/relationalai/tools/debugger_server.py +302 -0
  387. v0/relationalai/tools/dev.py +685 -0
  388. v0/relationalai/tools/qb_debugger.py +425 -0
  389. v0/relationalai/util/clean_up_databases.py +95 -0
  390. v0/relationalai/util/format.py +123 -0
  391. v0/relationalai/util/list_databases.py +9 -0
  392. v0/relationalai/util/otel_configuration.py +25 -0
  393. v0/relationalai/util/otel_handler.py +484 -0
  394. v0/relationalai/util/snowflake_handler.py +88 -0
  395. v0/relationalai/util/span_format_test.py +43 -0
  396. v0/relationalai/util/span_tracker.py +207 -0
  397. v0/relationalai/util/spans_file_handler.py +72 -0
  398. v0/relationalai/util/tracing_handler.py +34 -0
  399. frontend/debugger/dist/.gitignore +0 -2
  400. frontend/debugger/dist/assets/favicon-Dy0ZgA6N.png +0 -0
  401. frontend/debugger/dist/assets/index-Cssla-O7.js +0 -208
  402. frontend/debugger/dist/assets/index-DlHsYx1V.css +0 -9
  403. frontend/debugger/dist/index.html +0 -17
  404. relationalai/clients/__init__.py +0 -18
  405. relationalai/clients/client.py +0 -946
  406. relationalai/clients/config.py +0 -673
  407. relationalai/clients/direct_access_client.py +0 -118
  408. relationalai/clients/exec_txn_poller.py +0 -153
  409. relationalai/clients/hash_util.py +0 -31
  410. relationalai/clients/local.py +0 -594
  411. relationalai/clients/profile_polling.py +0 -73
  412. relationalai/clients/resources/__init__.py +0 -8
  413. relationalai/clients/resources/azure/azure.py +0 -502
  414. relationalai/clients/resources/snowflake/__init__.py +0 -20
  415. relationalai/clients/resources/snowflake/cli_resources.py +0 -98
  416. relationalai/clients/resources/snowflake/direct_access_resources.py +0 -739
  417. relationalai/clients/resources/snowflake/engine_service.py +0 -381
  418. relationalai/clients/resources/snowflake/engine_state_handlers.py +0 -315
  419. relationalai/clients/resources/snowflake/error_handlers.py +0 -240
  420. relationalai/clients/resources/snowflake/export_procedure.py.jinja +0 -249
  421. relationalai/clients/resources/snowflake/resources_factory.py +0 -99
  422. relationalai/clients/resources/snowflake/snowflake.py +0 -3193
  423. relationalai/clients/resources/snowflake/use_index_poller.py +0 -1019
  424. relationalai/clients/resources/snowflake/use_index_resources.py +0 -188
  425. relationalai/clients/resources/snowflake/util.py +0 -387
  426. relationalai/clients/result_helpers.py +0 -420
  427. relationalai/clients/types.py +0 -118
  428. relationalai/clients/util.py +0 -356
  429. relationalai/debugging.py +0 -389
  430. relationalai/dsl.py +0 -1749
  431. relationalai/early_access/builder/__init__.py +0 -30
  432. relationalai/early_access/builder/builder/__init__.py +0 -35
  433. relationalai/early_access/builder/snowflake/__init__.py +0 -12
  434. relationalai/early_access/builder/std/__init__.py +0 -25
  435. relationalai/early_access/builder/std/decimals/__init__.py +0 -12
  436. relationalai/early_access/builder/std/integers/__init__.py +0 -12
  437. relationalai/early_access/builder/std/math/__init__.py +0 -12
  438. relationalai/early_access/builder/std/strings/__init__.py +0 -14
  439. relationalai/early_access/devtools/__init__.py +0 -12
  440. relationalai/early_access/devtools/benchmark_lqp/__init__.py +0 -12
  441. relationalai/early_access/devtools/extract_lqp/__init__.py +0 -12
  442. relationalai/early_access/dsl/adapters/orm/adapter_qb.py +0 -427
  443. relationalai/early_access/dsl/adapters/orm/parser.py +0 -636
  444. relationalai/early_access/dsl/adapters/owl/adapter.py +0 -176
  445. relationalai/early_access/dsl/adapters/owl/parser.py +0 -160
  446. relationalai/early_access/dsl/bindings/common.py +0 -402
  447. relationalai/early_access/dsl/bindings/csv.py +0 -170
  448. relationalai/early_access/dsl/bindings/legacy/binding_models.py +0 -143
  449. relationalai/early_access/dsl/bindings/snowflake.py +0 -64
  450. relationalai/early_access/dsl/codegen/binder.py +0 -411
  451. relationalai/early_access/dsl/codegen/common.py +0 -79
  452. relationalai/early_access/dsl/codegen/helpers.py +0 -23
  453. relationalai/early_access/dsl/codegen/relations.py +0 -700
  454. relationalai/early_access/dsl/codegen/weaver.py +0 -417
  455. relationalai/early_access/dsl/core/builders/__init__.py +0 -47
  456. relationalai/early_access/dsl/core/builders/logic.py +0 -19
  457. relationalai/early_access/dsl/core/builders/scalar_constraint.py +0 -11
  458. relationalai/early_access/dsl/core/constraints/predicate/atomic.py +0 -455
  459. relationalai/early_access/dsl/core/constraints/predicate/universal.py +0 -73
  460. relationalai/early_access/dsl/core/constraints/scalar.py +0 -310
  461. relationalai/early_access/dsl/core/context.py +0 -13
  462. relationalai/early_access/dsl/core/cset.py +0 -132
  463. relationalai/early_access/dsl/core/exprs/__init__.py +0 -116
  464. relationalai/early_access/dsl/core/exprs/relational.py +0 -18
  465. relationalai/early_access/dsl/core/exprs/scalar.py +0 -412
  466. relationalai/early_access/dsl/core/instances.py +0 -44
  467. relationalai/early_access/dsl/core/logic/__init__.py +0 -193
  468. relationalai/early_access/dsl/core/logic/aggregation.py +0 -98
  469. relationalai/early_access/dsl/core/logic/exists.py +0 -223
  470. relationalai/early_access/dsl/core/logic/helper.py +0 -163
  471. relationalai/early_access/dsl/core/namespaces.py +0 -32
  472. relationalai/early_access/dsl/core/relations.py +0 -276
  473. relationalai/early_access/dsl/core/rules.py +0 -112
  474. relationalai/early_access/dsl/core/std/__init__.py +0 -45
  475. relationalai/early_access/dsl/core/temporal/recall.py +0 -6
  476. relationalai/early_access/dsl/core/types/__init__.py +0 -270
  477. relationalai/early_access/dsl/core/types/concepts.py +0 -128
  478. relationalai/early_access/dsl/core/types/constrained/__init__.py +0 -267
  479. relationalai/early_access/dsl/core/types/constrained/nominal.py +0 -143
  480. relationalai/early_access/dsl/core/types/constrained/subtype.py +0 -124
  481. relationalai/early_access/dsl/core/types/standard.py +0 -92
  482. relationalai/early_access/dsl/core/types/unconstrained.py +0 -50
  483. relationalai/early_access/dsl/core/types/variables.py +0 -203
  484. relationalai/early_access/dsl/ir/compiler.py +0 -318
  485. relationalai/early_access/dsl/ir/executor.py +0 -260
  486. relationalai/early_access/dsl/ontologies/constraints.py +0 -88
  487. relationalai/early_access/dsl/ontologies/export.py +0 -30
  488. relationalai/early_access/dsl/ontologies/models.py +0 -453
  489. relationalai/early_access/dsl/ontologies/python_printer.py +0 -303
  490. relationalai/early_access/dsl/ontologies/readings.py +0 -60
  491. relationalai/early_access/dsl/ontologies/relationships.py +0 -322
  492. relationalai/early_access/dsl/ontologies/roles.py +0 -87
  493. relationalai/early_access/dsl/ontologies/subtyping.py +0 -55
  494. relationalai/early_access/dsl/orm/constraints.py +0 -438
  495. relationalai/early_access/dsl/orm/measures/dimensions.py +0 -200
  496. relationalai/early_access/dsl/orm/measures/initializer.py +0 -16
  497. relationalai/early_access/dsl/orm/measures/measure_rules.py +0 -275
  498. relationalai/early_access/dsl/orm/measures/measures.py +0 -299
  499. relationalai/early_access/dsl/orm/measures/role_exprs.py +0 -268
  500. relationalai/early_access/dsl/orm/models.py +0 -256
  501. relationalai/early_access/dsl/orm/object_oriented_printer.py +0 -344
  502. relationalai/early_access/dsl/orm/printer.py +0 -469
  503. relationalai/early_access/dsl/orm/reasoners.py +0 -480
  504. relationalai/early_access/dsl/orm/relations.py +0 -19
  505. relationalai/early_access/dsl/orm/relationships.py +0 -251
  506. relationalai/early_access/dsl/orm/types.py +0 -42
  507. relationalai/early_access/dsl/orm/utils.py +0 -79
  508. relationalai/early_access/dsl/orm/verb.py +0 -204
  509. relationalai/early_access/dsl/physical_metadata/tables.py +0 -133
  510. relationalai/early_access/dsl/relations.py +0 -170
  511. relationalai/early_access/dsl/rulesets.py +0 -69
  512. relationalai/early_access/dsl/schemas/__init__.py +0 -450
  513. relationalai/early_access/dsl/schemas/builder.py +0 -48
  514. relationalai/early_access/dsl/schemas/comp_names.py +0 -51
  515. relationalai/early_access/dsl/schemas/components.py +0 -203
  516. relationalai/early_access/dsl/schemas/contexts.py +0 -156
  517. relationalai/early_access/dsl/schemas/exprs.py +0 -89
  518. relationalai/early_access/dsl/schemas/fragments.py +0 -464
  519. relationalai/early_access/dsl/serialization.py +0 -79
  520. relationalai/early_access/dsl/serialize/exporter.py +0 -163
  521. relationalai/early_access/dsl/snow/api.py +0 -105
  522. relationalai/early_access/dsl/snow/common.py +0 -76
  523. relationalai/early_access/dsl/state_mgmt/__init__.py +0 -129
  524. relationalai/early_access/dsl/state_mgmt/state_charts.py +0 -125
  525. relationalai/early_access/dsl/state_mgmt/transitions.py +0 -130
  526. relationalai/early_access/dsl/types/__init__.py +0 -40
  527. relationalai/early_access/dsl/types/concepts.py +0 -12
  528. relationalai/early_access/dsl/types/entities.py +0 -135
  529. relationalai/early_access/dsl/types/values.py +0 -17
  530. relationalai/early_access/dsl/utils.py +0 -102
  531. relationalai/early_access/graphs/__init__.py +0 -13
  532. relationalai/early_access/lqp/__init__.py +0 -12
  533. relationalai/early_access/lqp/compiler/__init__.py +0 -12
  534. relationalai/early_access/lqp/constructors/__init__.py +0 -18
  535. relationalai/early_access/lqp/executor/__init__.py +0 -12
  536. relationalai/early_access/lqp/ir/__init__.py +0 -12
  537. relationalai/early_access/lqp/passes/__init__.py +0 -12
  538. relationalai/early_access/lqp/pragmas/__init__.py +0 -12
  539. relationalai/early_access/lqp/primitives/__init__.py +0 -12
  540. relationalai/early_access/lqp/types/__init__.py +0 -12
  541. relationalai/early_access/lqp/utils/__init__.py +0 -12
  542. relationalai/early_access/lqp/validators/__init__.py +0 -12
  543. relationalai/early_access/metamodel/__init__.py +0 -58
  544. relationalai/early_access/metamodel/builtins/__init__.py +0 -12
  545. relationalai/early_access/metamodel/compiler/__init__.py +0 -12
  546. relationalai/early_access/metamodel/dependency/__init__.py +0 -12
  547. relationalai/early_access/metamodel/factory/__init__.py +0 -17
  548. relationalai/early_access/metamodel/helpers/__init__.py +0 -12
  549. relationalai/early_access/metamodel/ir/__init__.py +0 -14
  550. relationalai/early_access/metamodel/rewrite/__init__.py +0 -7
  551. relationalai/early_access/metamodel/typer/__init__.py +0 -3
  552. relationalai/early_access/metamodel/typer/typer/__init__.py +0 -12
  553. relationalai/early_access/metamodel/types/__init__.py +0 -15
  554. relationalai/early_access/metamodel/util/__init__.py +0 -15
  555. relationalai/early_access/metamodel/visitor/__init__.py +0 -12
  556. relationalai/early_access/rel/__init__.py +0 -12
  557. relationalai/early_access/rel/executor/__init__.py +0 -12
  558. relationalai/early_access/rel/rel_utils/__init__.py +0 -12
  559. relationalai/early_access/rel/rewrite/__init__.py +0 -7
  560. relationalai/early_access/solvers/__init__.py +0 -19
  561. relationalai/early_access/sql/__init__.py +0 -11
  562. relationalai/early_access/sql/executor/__init__.py +0 -3
  563. relationalai/early_access/sql/rewrite/__init__.py +0 -3
  564. relationalai/early_access/tests/logging/__init__.py +0 -12
  565. relationalai/early_access/tests/test_snapshot_base/__init__.py +0 -12
  566. relationalai/early_access/tests/utils/__init__.py +0 -12
  567. relationalai/environments/__init__.py +0 -35
  568. relationalai/environments/base.py +0 -381
  569. relationalai/environments/colab.py +0 -14
  570. relationalai/environments/generic.py +0 -71
  571. relationalai/environments/ipython.py +0 -68
  572. relationalai/environments/jupyter.py +0 -9
  573. relationalai/environments/snowbook.py +0 -169
  574. relationalai/errors.py +0 -2496
  575. relationalai/experimental/SF.py +0 -38
  576. relationalai/experimental/inspect.py +0 -47
  577. relationalai/experimental/pathfinder/__init__.py +0 -158
  578. relationalai/experimental/pathfinder/api.py +0 -160
  579. relationalai/experimental/pathfinder/automaton.py +0 -584
  580. relationalai/experimental/pathfinder/bridge.py +0 -226
  581. relationalai/experimental/pathfinder/compiler.py +0 -416
  582. relationalai/experimental/pathfinder/datalog.py +0 -214
  583. relationalai/experimental/pathfinder/diagnostics.py +0 -56
  584. relationalai/experimental/pathfinder/filter.py +0 -236
  585. relationalai/experimental/pathfinder/glushkov.py +0 -439
  586. relationalai/experimental/pathfinder/options.py +0 -265
  587. relationalai/experimental/pathfinder/pathfinder-v0.7.0.rel +0 -1951
  588. relationalai/experimental/pathfinder/rpq.py +0 -344
  589. relationalai/experimental/pathfinder/transition.py +0 -200
  590. relationalai/experimental/pathfinder/utils.py +0 -26
  591. relationalai/experimental/paths/README.md +0 -107
  592. relationalai/experimental/paths/api.py +0 -143
  593. relationalai/experimental/paths/benchmarks/grid_graph.py +0 -37
  594. relationalai/experimental/paths/code_organization.md +0 -2
  595. relationalai/experimental/paths/examples/Movies.ipynb +0 -16328
  596. relationalai/experimental/paths/examples/basic_example.py +0 -40
  597. relationalai/experimental/paths/examples/minimal_engine_warmup.py +0 -3
  598. relationalai/experimental/paths/examples/movie_example.py +0 -77
  599. relationalai/experimental/paths/examples/movies_data/actedin.csv +0 -193
  600. relationalai/experimental/paths/examples/movies_data/directed.csv +0 -45
  601. relationalai/experimental/paths/examples/movies_data/follows.csv +0 -7
  602. relationalai/experimental/paths/examples/movies_data/movies.csv +0 -39
  603. relationalai/experimental/paths/examples/movies_data/person.csv +0 -134
  604. relationalai/experimental/paths/examples/movies_data/produced.csv +0 -16
  605. relationalai/experimental/paths/examples/movies_data/ratings.csv +0 -10
  606. relationalai/experimental/paths/examples/movies_data/wrote.csv +0 -11
  607. relationalai/experimental/paths/examples/paths_benchmark.py +0 -115
  608. relationalai/experimental/paths/examples/paths_example.py +0 -116
  609. relationalai/experimental/paths/examples/pattern_to_automaton.py +0 -28
  610. relationalai/experimental/paths/find_paths_via_automaton.py +0 -85
  611. relationalai/experimental/paths/graph.py +0 -185
  612. relationalai/experimental/paths/path_algorithms/find_paths.py +0 -280
  613. relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +0 -26
  614. relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +0 -111
  615. relationalai/experimental/paths/path_algorithms/single.py +0 -59
  616. relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +0 -39
  617. relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +0 -103
  618. relationalai/experimental/paths/path_algorithms/usp-old.py +0 -130
  619. relationalai/experimental/paths/path_algorithms/usp-tuple.py +0 -183
  620. relationalai/experimental/paths/path_algorithms/usp.py +0 -150
  621. relationalai/experimental/paths/product_graph.py +0 -93
  622. relationalai/experimental/paths/rpq/automaton.py +0 -584
  623. relationalai/experimental/paths/rpq/diagnostics.py +0 -56
  624. relationalai/experimental/paths/rpq/rpq.py +0 -378
  625. relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +0 -90
  626. relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +0 -119
  627. relationalai/experimental/paths/tests/tests_limit_sp_single.py +0 -104
  628. relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +0 -113
  629. relationalai/experimental/paths/tests/tests_limit_walks_single.py +0 -149
  630. relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +0 -70
  631. relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +0 -64
  632. relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +0 -115
  633. relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +0 -75
  634. relationalai/experimental/paths/tests/tests_single_paths.py +0 -152
  635. relationalai/experimental/paths/tests/tests_single_walks.py +0 -208
  636. relationalai/experimental/paths/tests/tests_single_walks_undirected.py +0 -297
  637. relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +0 -107
  638. relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +0 -76
  639. relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +0 -76
  640. relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +0 -110
  641. relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +0 -229
  642. relationalai/experimental/paths/tests/tests_usp_nsp_single.py +0 -108
  643. relationalai/experimental/paths/tree_agg.py +0 -168
  644. relationalai/experimental/paths/utilities/iterators.py +0 -27
  645. relationalai/experimental/paths/utilities/prefix_sum.py +0 -91
  646. relationalai/experimental/solvers.py +0 -1095
  647. relationalai/loaders/csv.py +0 -195
  648. relationalai/loaders/loader.py +0 -177
  649. relationalai/loaders/types.py +0 -23
  650. relationalai/rel_emitter.py +0 -373
  651. relationalai/rel_utils.py +0 -185
  652. relationalai/semantics/designs/query_builder/identify_by.md +0 -106
  653. relationalai/semantics/devtools/benchmark_lqp.py +0 -535
  654. relationalai/semantics/devtools/compilation_manager.py +0 -294
  655. relationalai/semantics/devtools/extract_lqp.py +0 -110
  656. relationalai/semantics/internal/internal.py +0 -3785
  657. relationalai/semantics/internal/snowflake.py +0 -329
  658. relationalai/semantics/lqp/README.md +0 -34
  659. relationalai/semantics/lqp/algorithms.py +0 -173
  660. relationalai/semantics/lqp/builtins.py +0 -213
  661. relationalai/semantics/lqp/compiler.py +0 -22
  662. relationalai/semantics/lqp/constructors.py +0 -68
  663. relationalai/semantics/lqp/executor.py +0 -518
  664. relationalai/semantics/lqp/export_rewriter.py +0 -40
  665. relationalai/semantics/lqp/intrinsics.py +0 -24
  666. relationalai/semantics/lqp/ir.py +0 -150
  667. relationalai/semantics/lqp/model2lqp.py +0 -1056
  668. relationalai/semantics/lqp/passes.py +0 -38
  669. relationalai/semantics/lqp/primitives.py +0 -252
  670. relationalai/semantics/lqp/result_helpers.py +0 -266
  671. relationalai/semantics/lqp/rewrite/__init__.py +0 -32
  672. relationalai/semantics/lqp/rewrite/algorithm.py +0 -385
  673. relationalai/semantics/lqp/rewrite/annotate_constraints.py +0 -69
  674. relationalai/semantics/lqp/rewrite/cdc.py +0 -216
  675. relationalai/semantics/lqp/rewrite/constants_to_vars.py +0 -70
  676. relationalai/semantics/lqp/rewrite/deduplicate_vars.py +0 -104
  677. relationalai/semantics/lqp/rewrite/eliminate_data.py +0 -108
  678. relationalai/semantics/lqp/rewrite/extract_common.py +0 -340
  679. relationalai/semantics/lqp/rewrite/extract_keys.py +0 -577
  680. relationalai/semantics/lqp/rewrite/flatten_script.py +0 -301
  681. relationalai/semantics/lqp/rewrite/function_annotations.py +0 -114
  682. relationalai/semantics/lqp/rewrite/functional_dependencies.py +0 -348
  683. relationalai/semantics/lqp/rewrite/period_math.py +0 -77
  684. relationalai/semantics/lqp/rewrite/quantify_vars.py +0 -339
  685. relationalai/semantics/lqp/rewrite/splinter.py +0 -76
  686. relationalai/semantics/lqp/rewrite/unify_definitions.py +0 -323
  687. relationalai/semantics/lqp/types.py +0 -101
  688. relationalai/semantics/lqp/utils.py +0 -170
  689. relationalai/semantics/lqp/validators.py +0 -70
  690. relationalai/semantics/metamodel/compiler.py +0 -134
  691. relationalai/semantics/metamodel/dependency.py +0 -880
  692. relationalai/semantics/metamodel/executor.py +0 -78
  693. relationalai/semantics/metamodel/factory.py +0 -287
  694. relationalai/semantics/metamodel/helpers.py +0 -368
  695. relationalai/semantics/metamodel/ir.py +0 -924
  696. relationalai/semantics/metamodel/rewrite/__init__.py +0 -8
  697. relationalai/semantics/metamodel/rewrite/discharge_constraints.py +0 -39
  698. relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +0 -220
  699. relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +0 -78
  700. relationalai/semantics/metamodel/rewrite/flatten.py +0 -590
  701. relationalai/semantics/metamodel/rewrite/format_outputs.py +0 -256
  702. relationalai/semantics/metamodel/rewrite/handle_aggregations_and_ranks.py +0 -237
  703. relationalai/semantics/metamodel/typer/checker.py +0 -355
  704. relationalai/semantics/metamodel/typer/typer.py +0 -1396
  705. relationalai/semantics/metamodel/util.py +0 -506
  706. relationalai/semantics/metamodel/visitor.py +0 -945
  707. relationalai/semantics/reasoners/__init__.py +0 -10
  708. relationalai/semantics/reasoners/graph/README.md +0 -620
  709. relationalai/semantics/reasoners/graph/__init__.py +0 -37
  710. relationalai/semantics/reasoners/graph/core.py +0 -9019
  711. relationalai/semantics/reasoners/graph/design/beyond_demand_transform.md +0 -797
  712. relationalai/semantics/reasoners/graph/tests/README.md +0 -21
  713. relationalai/semantics/reasoners/optimization/__init__.py +0 -68
  714. relationalai/semantics/reasoners/optimization/common.py +0 -88
  715. relationalai/semantics/reasoners/optimization/solvers_dev.py +0 -568
  716. relationalai/semantics/reasoners/optimization/solvers_pb.py +0 -1407
  717. relationalai/semantics/rel/builtins.py +0 -40
  718. relationalai/semantics/rel/compiler.py +0 -994
  719. relationalai/semantics/rel/executor.py +0 -363
  720. relationalai/semantics/rel/rel.py +0 -482
  721. relationalai/semantics/rel/rel_utils.py +0 -276
  722. relationalai/semantics/snowflake/__init__.py +0 -3
  723. relationalai/semantics/sql/compiler.py +0 -2503
  724. relationalai/semantics/sql/executor/duck_db.py +0 -52
  725. relationalai/semantics/sql/executor/result_helpers.py +0 -64
  726. relationalai/semantics/sql/executor/snowflake.py +0 -149
  727. relationalai/semantics/sql/rewrite/denormalize.py +0 -222
  728. relationalai/semantics/sql/rewrite/double_negation.py +0 -49
  729. relationalai/semantics/sql/rewrite/recursive_union.py +0 -127
  730. relationalai/semantics/sql/rewrite/sort_output_query.py +0 -246
  731. relationalai/semantics/sql/sql.py +0 -504
  732. relationalai/semantics/std/pragmas.py +0 -11
  733. relationalai/semantics/std/std.py +0 -14
  734. relationalai/semantics/tests/lqp/algorithms.py +0 -345
  735. relationalai/semantics/tests/test_snapshot_abstract.py +0 -144
  736. relationalai/semantics/tests/test_snapshot_base.py +0 -9
  737. relationalai/semantics/tests/utils.py +0 -46
  738. relationalai/std/__init__.py +0 -70
  739. relationalai/tools/cli.py +0 -2089
  740. relationalai/tools/cli_controls.py +0 -1975
  741. relationalai/tools/cli_helpers.py +0 -802
  742. relationalai/tools/debugger_client.py +0 -109
  743. relationalai/tools/debugger_server.py +0 -302
  744. relationalai/tools/dev.py +0 -685
  745. relationalai/tools/notes +0 -7
  746. relationalai/tools/qb_debugger.py +0 -425
  747. relationalai/tools/txn_progress.py +0 -188
  748. relationalai/util/clean_up_databases.py +0 -95
  749. relationalai/util/list_databases.py +0 -9
  750. relationalai/util/otel_configuration.py +0 -26
  751. relationalai/util/otel_handler.py +0 -484
  752. relationalai/util/snowflake_handler.py +0 -88
  753. relationalai/util/span_format_test.py +0 -43
  754. relationalai/util/span_tracker.py +0 -207
  755. relationalai/util/spans_file_handler.py +0 -72
  756. relationalai/util/tracing_handler.py +0 -34
  757. relationalai-0.13.5.dist-info/METADATA +0 -74
  758. relationalai-0.13.5.dist-info/RECORD +0 -473
  759. relationalai-0.13.5.dist-info/WHEEL +0 -4
  760. relationalai-0.13.5.dist-info/entry_points.txt +0 -3
  761. relationalai-0.13.5.dist-info/licenses/LICENSE +0 -202
  762. relationalai_test_util/__init__.py +0 -4
  763. relationalai_test_util/fixtures.py +0 -233
  764. relationalai_test_util/snapshot.py +0 -252
  765. relationalai_test_util/traceback.py +0 -118
  766. /relationalai/{analysis → semantics/frontend}/__init__.py +0 -0
  767. /relationalai/{auth/__init__.py → semantics/metamodel/metamodel_compiler.py} +0 -0
  768. /relationalai/{early_access → shims}/__init__.py +0 -0
  769. {relationalai/early_access/dsl/adapters → v0/relationalai/analysis}/__init__.py +0 -0
  770. {relationalai → v0/relationalai}/analysis/mechanistic.py +0 -0
  771. {relationalai → v0/relationalai}/analysis/whynot.py +0 -0
  772. {relationalai/early_access/dsl/adapters/orm → v0/relationalai/auth}/__init__.py +0 -0
  773. {relationalai → v0/relationalai}/auth/jwt_generator.py +0 -0
  774. {relationalai → v0/relationalai}/auth/oauth_callback_server.py +0 -0
  775. {relationalai → v0/relationalai}/auth/token_handler.py +0 -0
  776. {relationalai → v0/relationalai}/auth/util.py +0 -0
  777. {relationalai/clients/resources/snowflake → v0/relationalai/clients}/cache_store.py +0 -0
  778. {relationalai → v0/relationalai}/compiler.py +0 -0
  779. {relationalai → v0/relationalai}/dependencies.py +0 -0
  780. {relationalai → v0/relationalai}/docutils.py +0 -0
  781. {relationalai/early_access/dsl/adapters/owl → v0/relationalai/early_access}/__init__.py +0 -0
  782. {relationalai → v0/relationalai}/early_access/dsl/__init__.py +0 -0
  783. {relationalai/early_access/dsl/bindings → v0/relationalai/early_access/dsl/adapters}/__init__.py +0 -0
  784. {relationalai/early_access/dsl/bindings/legacy → v0/relationalai/early_access/dsl/adapters/orm}/__init__.py +0 -0
  785. {relationalai → v0/relationalai}/early_access/dsl/adapters/orm/model.py +0 -0
  786. {relationalai/early_access/dsl/codegen → v0/relationalai/early_access/dsl/adapters/owl}/__init__.py +0 -0
  787. {relationalai → v0/relationalai}/early_access/dsl/adapters/owl/model.py +0 -0
  788. {relationalai/early_access/dsl/core/temporal → v0/relationalai/early_access/dsl/bindings}/__init__.py +0 -0
  789. {relationalai/early_access/dsl/ir → v0/relationalai/early_access/dsl/bindings/legacy}/__init__.py +0 -0
  790. {relationalai/early_access/dsl/ontologies → v0/relationalai/early_access/dsl/codegen}/__init__.py +0 -0
  791. {relationalai → v0/relationalai}/early_access/dsl/constants.py +0 -0
  792. {relationalai → v0/relationalai}/early_access/dsl/core/__init__.py +0 -0
  793. {relationalai → v0/relationalai}/early_access/dsl/core/constraints/__init__.py +0 -0
  794. {relationalai → v0/relationalai}/early_access/dsl/core/constraints/predicate/__init__.py +0 -0
  795. {relationalai → v0/relationalai}/early_access/dsl/core/stack.py +0 -0
  796. {relationalai/early_access/dsl/orm → v0/relationalai/early_access/dsl/core/temporal}/__init__.py +0 -0
  797. {relationalai → v0/relationalai}/early_access/dsl/core/utils.py +0 -0
  798. {relationalai/early_access/dsl/orm/measures → v0/relationalai/early_access/dsl/ir}/__init__.py +0 -0
  799. {relationalai/early_access/dsl/physical_metadata → v0/relationalai/early_access/dsl/ontologies}/__init__.py +0 -0
  800. {relationalai → v0/relationalai}/early_access/dsl/ontologies/raw_source.py +0 -0
  801. {relationalai/early_access/dsl/serialize → v0/relationalai/early_access/dsl/orm}/__init__.py +0 -0
  802. {relationalai/early_access/dsl/snow → v0/relationalai/early_access/dsl/orm/measures}/__init__.py +0 -0
  803. {relationalai → v0/relationalai}/early_access/dsl/orm/reasoner_errors.py +0 -0
  804. {relationalai/loaders → v0/relationalai/early_access/dsl/physical_metadata}/__init__.py +0 -0
  805. {relationalai/semantics/tests → v0/relationalai/early_access/dsl/serialize}/__init__.py +0 -0
  806. {relationalai → v0/relationalai}/early_access/dsl/serialize/binding_model.py +0 -0
  807. {relationalai → v0/relationalai}/early_access/dsl/serialize/model.py +0 -0
  808. {relationalai/semantics/tests/lqp → v0/relationalai/early_access/dsl/snow}/__init__.py +0 -0
  809. {relationalai → v0/relationalai}/early_access/tests/__init__.py +0 -0
  810. {relationalai → v0/relationalai}/environments/ci.py +0 -0
  811. {relationalai → v0/relationalai}/environments/hex.py +0 -0
  812. {relationalai → v0/relationalai}/environments/terminal.py +0 -0
  813. {relationalai → v0/relationalai}/experimental/__init__.py +0 -0
  814. {relationalai → v0/relationalai}/experimental/graphs.py +0 -0
  815. {relationalai → v0/relationalai}/experimental/paths/__init__.py +0 -0
  816. {relationalai → v0/relationalai}/experimental/paths/benchmarks/__init__.py +0 -0
  817. {relationalai → v0/relationalai}/experimental/paths/path_algorithms/__init__.py +0 -0
  818. {relationalai → v0/relationalai}/experimental/paths/rpq/__init__.py +0 -0
  819. {relationalai → v0/relationalai}/experimental/paths/rpq/filter.py +0 -0
  820. {relationalai → v0/relationalai}/experimental/paths/rpq/glushkov.py +0 -0
  821. {relationalai → v0/relationalai}/experimental/paths/rpq/transition.py +0 -0
  822. {relationalai → v0/relationalai}/experimental/paths/utilities/__init__.py +0 -0
  823. {relationalai → v0/relationalai}/experimental/paths/utilities/utilities.py +0 -0
  824. {relationalai/tools → v0/relationalai/loaders}/__init__.py +0 -0
  825. {relationalai → v0/relationalai}/metagen.py +0 -0
  826. {relationalai → v0/relationalai}/metamodel.py +0 -0
  827. {relationalai → v0/relationalai}/rel.py +0 -0
  828. {relationalai → v0/relationalai}/semantics/devtools/__init__.py +0 -0
  829. {relationalai → v0/relationalai}/semantics/internal/__init__.py +0 -0
  830. {relationalai → v0/relationalai}/semantics/internal/annotations.py +0 -0
  831. {relationalai → v0/relationalai}/semantics/lqp/__init__.py +0 -0
  832. {relationalai → v0/relationalai}/semantics/lqp/pragmas.py +0 -0
  833. {relationalai → v0/relationalai}/semantics/metamodel/dataflow.py +0 -0
  834. {relationalai → v0/relationalai}/semantics/metamodel/typer/__init__.py +0 -0
  835. {relationalai → v0/relationalai}/semantics/metamodel/types.py +0 -0
  836. {relationalai → v0/relationalai}/semantics/reasoners/experimental/__init__.py +0 -0
  837. {relationalai → v0/relationalai}/semantics/rel/__init__.py +0 -0
  838. {relationalai → v0/relationalai}/semantics/sql/__init__.py +0 -0
  839. {relationalai → v0/relationalai}/semantics/sql/executor/__init__.py +0 -0
  840. {relationalai → v0/relationalai}/semantics/sql/rewrite/__init__.py +0 -0
  841. {relationalai → v0/relationalai}/semantics/tests/logging.py +0 -0
  842. {relationalai → v0/relationalai}/std/aggregates.py +0 -0
  843. {relationalai → v0/relationalai}/std/dates.py +0 -0
  844. {relationalai → v0/relationalai}/std/graphs.py +0 -0
  845. {relationalai → v0/relationalai}/std/inspect.py +0 -0
  846. {relationalai → v0/relationalai}/std/math.py +0 -0
  847. {relationalai → v0/relationalai}/std/re.py +0 -0
  848. {relationalai → v0/relationalai}/std/strings.py +0 -0
  849. {relationalai → v0/relationalai}/tools/cleanup_snapshots.py +0 -0
  850. {relationalai → v0/relationalai}/tools/constants.py +0 -0
  851. {relationalai → v0/relationalai}/tools/query_utils.py +0 -0
  852. {relationalai → v0/relationalai}/tools/snapshot_viewer.py +0 -0
  853. {relationalai → v0/relationalai}/util/__init__.py +0 -0
  854. {relationalai → v0/relationalai}/util/constants.py +0 -0
  855. {relationalai → v0/relationalai}/util/graph.py +0 -0
  856. {relationalai → v0/relationalai}/util/timeout.py +0 -0
relationalai/dsl.py DELETED
@@ -1,1749 +0,0 @@
1
- from __future__ import annotations
2
- import base64
3
- from enum import Enum
4
- import inspect
5
- from itertools import zip_longest
6
- import re
7
- import struct
8
- import threading
9
- import typing
10
- from typing import Any, Dict, List, Optional, Set, Tuple, Union, get_type_hints
11
- from relationalai.clients.util import IdentityParser, ParseError
12
- from typing_extensions import TypeGuard
13
- import numbers
14
- import os
15
- import datetime
16
- import hashlib
17
- import traceback
18
- import rich
19
- import json
20
- import sys
21
-
22
- from pandas import DataFrame
23
-
24
- from relationalai.environments import runtime_env, SnowbookEnvironment
25
- from relationalai.tools.constants import QUERY_ATTRIBUTES_HEADER
26
-
27
- from .clients.client import Client
28
-
29
- from .metamodel import Behavior, Builtins, ActionType, Var, Task, Action, Builder, Type as mType, Property as mProperty
30
- from . import debugging, errors
31
- from .errors import FilterAsValue, Errors, InvalidPropertySetException, MultipleIdentities, NonCallablePropertyException, OutOfContextException, RAIException, ReservedPropertyException, VariableOutOfContextException, handle_missing_integration
32
-
33
- #--------------------------------------------------
34
- # Constants
35
- #--------------------------------------------------
36
-
37
- RESERVED_PROPS = ["add", "set", "persist", "unpersist"]
38
- MAX_QUERY_ATTRIBUTE_LENGTH = 255
39
-
40
- Value = Union[
41
- "Expression",
42
- "ContextSelect", # because of union/match
43
- int,
44
- float,
45
- str,
46
- bool,
47
- datetime.datetime,
48
- datetime.date,
49
- ]
50
-
51
- #--------------------------------------------------
52
- # Helpers
53
- #--------------------------------------------------
54
-
55
- # @FIXME: This should only return a Var or None but that's gonna take some doing.
56
- def to_var(x:Any) -> Any:
57
- if isinstance(x, Var):
58
- return x
59
- if getattr(x, "_to_var", None):
60
- return to_var(x._to_var())
61
- if isinstance(x, ContextSelect):
62
- return x._vars[0]
63
- if isinstance(x, mProperty):
64
- return Var(value=x)
65
- if isinstance(x, mType):
66
- return Var(value=x)
67
- if isinstance(x, Producer):
68
- x._use_var()
69
- return x._var
70
- if isinstance(x, list) or isinstance(x, tuple):
71
- return Var(Builtins.Any, value=[v for i in x if (v := to_var(i))])
72
- if isinstance(x, str):
73
- return Var(Builtins.String, None, x)
74
- if isinstance(x, numbers.Number):
75
- return Var(Builtins.Number, None, x)
76
- if isinstance(x, datetime.datetime) or isinstance(x, datetime.date):
77
- return Var(value=x)
78
- raise Exception(f"Unknown type: {type(x)}\n{x}")
79
-
80
- build = Builder(to_var)
81
-
82
- def to_list(x:Any):
83
- if isinstance(x, list):
84
- return x
85
- if isinstance(x, tuple):
86
- return list(x)
87
- return [x]
88
-
89
- def is_static(x:Any):
90
- if isinstance(x, Var):
91
- return x.value is not None
92
- if isinstance(x, Type):
93
- return True
94
- if isinstance(x, str):
95
- return True
96
- if isinstance(x, Producer):
97
- return is_static(to_var(x))
98
- if isinstance(x, numbers.Number):
99
- return True
100
- if isinstance(x, list):
101
- return all(is_static(i) for i in x)
102
- if isinstance(x, tuple):
103
- return all(is_static(i) for i in x)
104
- if isinstance(x, dict):
105
- return all(is_static(i) for i in x.values())
106
- return False
107
-
108
- def is_collection(x:Any) -> TypeGuard[Union[List, Tuple, Set]]:
109
- return isinstance(x, list) or isinstance(x, tuple) or isinstance(x, set)
110
-
111
- def rel_dict(**kwargs):
112
- return InlineRelation(get_graph(), [
113
- (Symbol(k), v) for k, v in kwargs.items()
114
- ])
115
-
116
- #--------------------------------------------------
117
- # Base
118
- #--------------------------------------------------
119
-
120
- id = 0
121
- def next_id():
122
- global id
123
- id += 1
124
- return id
125
-
126
- #--------------------------------------------------
127
- # Producer
128
- #--------------------------------------------------
129
-
130
- attributes_to_skip = {
131
- "_to_var",
132
- "__name__",
133
- "__qualname__",
134
- "_repr_html_",
135
- "_supports_binary_op",
136
- }
137
-
138
- def is_streamlit_running():
139
- # First check: Is streamlit imported?
140
- if 'streamlit' not in sys.modules:
141
- return False
142
-
143
- # Second check: Try to access session_state
144
- try:
145
- import streamlit as st #type: ignore
146
- _ = st.session_state
147
- return True
148
- except RuntimeError:
149
- return False
150
-
151
- def is_called_by_streamlit_write():
152
- if not is_streamlit_running():
153
- return False
154
-
155
- stack_frames = inspect.stack()
156
-
157
- for frame in stack_frames[1:]:
158
- if ("streamlit" in frame.filename and "write" in frame.function):
159
- return True
160
-
161
- return False
162
-
163
- class Producer():
164
- def __init__(self, graph:'Graph'):
165
- self._id = next_id()
166
- self._graph = graph
167
- self._subs = {}
168
- self._var = None
169
-
170
- def __iter__(self):
171
- if is_called_by_streamlit_write():
172
- return iter([])
173
- raise Exception("Can't iterate over a producer")
174
-
175
- def __repr__(self):
176
- if isinstance(runtime_env, SnowbookEnvironment):
177
- # suppress spurious output in Snowflake notebooks
178
- # for expressions like p.age > 18
179
- return ""
180
- else:
181
- return super().__repr__()
182
-
183
- def __getattr__(self, name: str) -> Any:
184
- if is_called_by_streamlit_write():
185
- return None
186
- if name in attributes_to_skip:
187
- return None
188
- self._subs[name] = self._make_sub(name, self._subs.get(name))
189
- return self._subs[name]
190
-
191
- def _make_sub(self, name:str, existing:Optional['Producer']=None) -> Any:
192
- raise Exception("Implement Producer._make_sub")
193
-
194
- def _use_var(self):
195
- pass
196
-
197
- #--------------------------------------------------
198
- # Boolean overloads
199
- #--------------------------------------------------
200
-
201
- def __bool__(self):
202
- # This doesn't seem to be safe as Python can call bool on Producers in lots of random cases
203
- # InvalidBoolWarning(Errors.call_source())
204
- # class_name = self.__class__.__name__
205
- # TODO: Refactor this to be Exception instead of warning, so we could directly raise it if we bring back this
206
- # raise TypeError(f"Can't convert an {class_name} to a boolean.")
207
- return True
208
-
209
- #--------------------------------------------------
210
- # Math overloads
211
- #--------------------------------------------------
212
-
213
- def _wrapped_op(self, op, left, right):
214
- # Check if an active context redefines this binary operator (e.g. for the solvers library).
215
- for s in self._graph._stack.stack:
216
- f = getattr(s, "_supports_binary_op", None)
217
- if f and f(op):
218
- return s._make_binary_op(op, left, right)
219
- return Expression(self._graph, op, [left, right])
220
-
221
- def __add__(self, other):
222
- return self._wrapped_op(Builtins.plus, self, other)
223
- def __radd__(self, other):
224
- return self._wrapped_op(Builtins.plus, other, self)
225
-
226
- def __mul__(self, other):
227
- return self._wrapped_op(Builtins.mult, self, other)
228
- def __rmul__(self, other):
229
- return self._wrapped_op(Builtins.mult, other, self)
230
-
231
- def __sub__(self, other):
232
- return self._wrapped_op(Builtins.minus, self, other)
233
- def __rsub__(self, other):
234
- return self._wrapped_op(Builtins.minus, other, self)
235
-
236
- def __truediv__(self, other):
237
- return self._wrapped_op(Builtins.div, self, other)
238
- def __rtruediv__(self, other):
239
- return self._wrapped_op(Builtins.div, other, self)
240
-
241
- def __floordiv__(self, other):
242
- return self._wrapped_op(Builtins.floor_div, self, other)
243
- def __rfloordiv__(self, other):
244
- return self._wrapped_op(Builtins.floor_div, other, self)
245
-
246
- def __pow__(self, other):
247
- return self._wrapped_op(Builtins.pow, self, other)
248
- def __rpow__(self, other):
249
- return self._wrapped_op(Builtins.pow, other, self)
250
-
251
- def __mod__(self, other):
252
- return self._wrapped_op(Builtins.mod, self, other)
253
- def __rmod__(self, other):
254
- return self._wrapped_op(Builtins.mod, other, self)
255
-
256
- def __neg__(self):
257
- return self._wrapped_op(Builtins.mult, self, -1)
258
-
259
- #--------------------------------------------------
260
- # Filter overloads
261
- #--------------------------------------------------
262
-
263
- def __gt__(self, other):
264
- return self._wrapped_op(Builtins.gt, self, other)
265
- def __ge__(self, other):
266
- return self._wrapped_op(Builtins.gte, self, other)
267
- def __lt__(self, other):
268
- return self._wrapped_op(Builtins.lt, self, other)
269
- def __le__(self, other):
270
- return self._wrapped_op(Builtins.lte, self, other)
271
- def __eq__(self, other) -> Any:
272
- return self._wrapped_op(Builtins.approx_eq, self, other)
273
- def __ne__(self, other) -> Any:
274
- return self._wrapped_op(Builtins.neq, self, other)
275
-
276
- #--------------------------------------------------
277
- # Context management
278
- #--------------------------------------------------
279
-
280
- def __enter__(self):
281
- self._graph._push(self)
282
-
283
- def __exit__(self, *args):
284
- self._graph._pop(self)
285
-
286
- #--------------------------------------------------
287
- # Context
288
- #--------------------------------------------------
289
-
290
- class TaskExecType(Enum):
291
- Query = 1
292
- Rule = 2
293
- Procedure = 3
294
- Export = 4
295
-
296
- class ContextSelect(Producer):
297
- def __init__(self, context:'Context'):
298
- super().__init__(context.graph)
299
- self._context = context
300
- self._select_len = None
301
- self._insts = []
302
- self._vars = []
303
- self._props = {}
304
-
305
- def _assign_vars(self):
306
- task = self._context._task
307
- if not len(self._vars) and self._select_len:
308
- self._insts = to_list(Vars(self._select_len))
309
- self._vars = [to_var(v) for v in self._insts]
310
- task.properties = [Builtins.Relation.properties[i] for i in range(self._select_len)]
311
- task.bindings.update({Builtins.Relation.properties[i]: v for i, v in enumerate(self._vars)})
312
-
313
- def __getattr__(self, name: str) -> Any:
314
- if name.startswith("_"):
315
- return None
316
- if name in self._props:
317
- return Instance(self._context.graph, ActionType.Get, [], {}, var=to_var(self._props[name]))
318
- else:
319
- return getattr(Instance(self._context.graph, ActionType.Get, [], {}, var=to_var(self._vars[0])), name)
320
-
321
- #--------------------------------------------------
322
- # Return handling
323
- #--------------------------------------------------
324
-
325
- def _do_return(self, args, distinct=False):
326
- graph = self._context.graph
327
- task = self._context._task
328
- if task.behavior == Behavior.Query \
329
- and self._context._exec_type in [TaskExecType.Query, TaskExecType.Procedure]:
330
- if isinstance(args[0], tuple):
331
- args = args[0]
332
- export = self._context._format == "snowpark"
333
- graph._action(build.return_(list(args), export=export, distinct=distinct))
334
- else:
335
- #TODO: good error message depending on the type of task we're dealing with
336
- raise Exception("Can't select in a non-query")
337
- return self._context
338
-
339
- def __call__(self, *args: Any) -> Any:
340
- if self._context._done:
341
- raise errors.SelectOutOfContext()
342
- return self._do_return(args)
343
-
344
- def distinct(self, *args:Any) -> Any:
345
- if self._context._done:
346
- raise errors.SelectOutOfContext()
347
- return self._do_return(args, distinct=True)
348
-
349
- #--------------------------------------------------
350
- # Add for `model.match() as m`
351
- #--------------------------------------------------
352
-
353
- def add(self, item, **kwargs):
354
- arg_len = len(kwargs) + 1
355
- if self._select_len is not None and arg_len != self._select_len:
356
- raise Exception("Add must be provided the same arguments in each branch")
357
- self._select_len = arg_len
358
- self._assign_vars()
359
- if len(self._props) and set(self._props.keys()) != set(kwargs.keys()):
360
- raise Exception("Add must be provided the same properties in each branch")
361
- elif len(self._props) == 0:
362
- for k, v in zip(kwargs.keys(), self._vars[1:]):
363
- v.name = k
364
- self._props[k] = v
365
-
366
- graph = self._context.graph
367
- graph._action(build.relation_action(ActionType.Bind, self._context._task, [item, *[kwargs[k] for k in self._props.keys()]]))
368
-
369
- class Context():
370
- def __init__(self, graph:'Graph', *args, behavior=Behavior.Query, op=None,
371
- exec_type=TaskExecType.Rule, dynamic=False, format="default",
372
- props=None, engine=None, tag=None, globalize=False, source=None,
373
- attributes=None, read_only=False, skip_invalid_data=False):
374
- self._id = next_id()
375
- self.results = DataFrame()
376
- self.graph = graph
377
- self._task = Task(behavior=behavior)
378
- self._globalize = globalize
379
- self._op = op
380
- self._args = list(args)
381
- self._exec_type = exec_type
382
- self._select_len = None
383
- self._dynamic = dynamic or any([item._dynamic for item in self.graph._stack.stack if isinstance(item, Context)])
384
- self._props = props or {}
385
- self._engine= engine
386
- self._tag = tag # for benchmark reporting
387
- self._format = self._resolve_format(format)
388
- self._done = False
389
- self._source = source
390
- self._read_only:bool = read_only
391
- self._skip_invalid_data:bool = skip_invalid_data
392
-
393
- self._validate_attributes(attributes)
394
- self._attributes = attributes
395
-
396
- def _validate_attributes(self, attributes):
397
- if attributes is None:
398
- return True
399
-
400
- for key, value in attributes.items():
401
- self._validate_attribute_item(key)
402
- self._validate_attribute_item(value)
403
-
404
- def _validate_attribute_item(self, item):
405
- assert isinstance(item, str), f"'{item}' must be a string"
406
- assert len(item) <= MAX_QUERY_ATTRIBUTE_LENGTH, f"'{item}' exceeds the maximum length of {MAX_QUERY_ATTRIBUTE_LENGTH} characters."
407
- assert re.match(r'^[a-zA-Z0-9_-]+$', item), f"'{item}' must contain only alphanumeric characters, underscores, or hyphens."
408
-
409
- def _resolve_format(self, format):
410
- if format == "default":
411
- if self.graph._format != "default":
412
- return self.graph._format
413
- if self.graph._config.get("platform") == "snowflake":
414
- # In the future we may want to default to snowpark
415
- return "pandas"
416
- return "pandas"
417
- return format
418
-
419
- def __enter__(self):
420
- debugging.set_source(self._task, self._source)
421
- self.graph._push(self)
422
- return ContextSelect(self)
423
-
424
- def __exit__(self, *args):
425
- self._done = True
426
- # If no exception info has been passed to args,
427
- # then proceed with the normal exit process.
428
- # Otherwise, return False to propagate the exception.
429
- if args[0] is None:
430
- if not self._dynamic:
431
- debugging.check_errors(self._task)
432
- try:
433
- self.graph._pop(self, globalize=self._globalize)
434
- except KeyboardInterrupt as e:
435
- print("Canceling transactions...")
436
- self.graph.resources.cancel_pending_transactions()
437
- raise e
438
- except RAIException as e:
439
- handle_missing_integration(e)
440
- raise e.clone(self.graph._config) from None
441
- else:
442
- self.graph._pop(self, exec=False)
443
- if isinstance(args[1], RAIException):
444
- raise args[1].clone(self.graph._config) from None
445
- return False
446
-
447
- def __iter__(self):
448
- if self._exec_type != TaskExecType.Query:
449
- raise Exception("Can't iterate over a non-query task")
450
- else:
451
- return self.results.itertuples(index=False)
452
-
453
- def _repr_html_(self):
454
- if self._exec_type == TaskExecType.Query:
455
- if isinstance(self.results, DataFrame):
456
- return self.results.to_html(index=False)
457
- elif getattr(self.results, "_repr_html_", None):
458
- return self.results._repr_html_()
459
- elif getattr(self.results, "show"):
460
- self.results.show()
461
- return ""
462
- else:
463
- return str(self.results)
464
-
465
- def __str__(self):
466
- if self._exec_type == TaskExecType.Query:
467
- if isinstance(self.results, DataFrame):
468
- return self.results.to_string(index=False)
469
- else:
470
- return str(self.results)
471
- return super().__str__()
472
-
473
- #--------------------------------------------------
474
- # Type
475
- #--------------------------------------------------
476
-
477
- def hash_values_sha256_truncated(args):
478
- combined = ''.join(map(str, args))
479
- combined_bytes = combined.encode('utf-8')
480
- hasher = hashlib.sha256()
481
- hasher.update(combined_bytes)
482
- hash_128_bit = hasher.digest()[:16]
483
- return hash_128_bit
484
-
485
- # @NOTE: `omit_intrinsic_type_in_hash` exists to keep node hashes (which are namespaced by their graph) stable
486
- # when new nodes are directly created via `Node.add(x = ..)` instead of marking existing entities as
487
- # nodes. Possible hash collisions between types happen to be okay in this case because of the access
488
- # paths, but it's _not_ generally safe to use it otherwise.
489
- class Type(Producer):
490
- def __init__(self, graph:'Graph', name:str, builtins:List[str] = [], scope:str="", omit_intrinsic_type_in_hash = False):
491
- super().__init__(graph)
492
- self._type = mType(scope+name)
493
- self._scope = scope
494
- self._omit_intrinsic_type_in_hash = omit_intrinsic_type_in_hash
495
- if graph._config.get("compiler.use_value_types", False):
496
- self._type.parents.append(Builtins.ValueType)
497
- install = build.install(self._type)
498
- self._graph._action(install)
499
- debugging.set_source(install)
500
-
501
- def __call__(self, *args, **kwargs):
502
- return Instance(self._graph, ActionType.Get, [self, *args], kwargs, name=self._type.name.lower(), scope=self._scope)
503
-
504
- def add(self, *args, **kwargs):
505
- inst = Instance(self._graph, ActionType.Bind, [self, *args], kwargs, name=self._type.name.lower(), is_add=True, scope=self._scope)
506
- if inst._action.entity.value is not None:
507
- pass
508
- elif is_static(args) and is_static(kwargs):
509
- params = [Var(value=t.name) for t in inst._action.types]
510
- if self._omit_intrinsic_type_in_hash:
511
- params.pop(0)
512
- params.extend(inst._action.bindings.values())
513
- inst._action.entity.value = hash_values_sha256_truncated(params)
514
- elif all([isinstance(a, Type) for a in args]):
515
- self._graph._action(build.ident(inst._action, self._omit_intrinsic_type_in_hash))
516
- inst._add_to_graph()
517
- return inst
518
-
519
- def persist(self, *args, **kwargs):
520
- inst = Instance(self._graph, ActionType.Persist, [self, *args], kwargs, name=self._type.name.lower(), is_add=True, scope=self._scope)
521
- if inst._action.entity.value is not None:
522
- pass
523
- elif is_static(args) and is_static(kwargs):
524
- params = [Var(value=t.name) for t in inst._action.types]
525
- params.extend(inst._action.bindings.values())
526
- inst._action.entity.value = hash_values_sha256_truncated(params)
527
- elif all([isinstance(a, Type) for a in args]):
528
- self._graph._action(build.ident(inst._action, self._omit_intrinsic_type_in_hash))
529
- inst._add_to_graph()
530
- return inst
531
-
532
- def extend(self, *args, **kwargs):
533
- for arg in args:
534
- if not isinstance(arg, Type):
535
- raise Exception("Can only extend a type with another type")
536
- with self._graph.rule(dynamic=True):
537
- a = arg()
538
- a.set(self)
539
- with self._graph.rule(dynamic=True):
540
- a = arg()
541
- neue = self(a)
542
- for k, v in kwargs.items():
543
- if isinstance(v, Property):
544
- v = getattr(a, v._prop.name)
545
- neue.set(**{k:v})
546
-
547
- def define(self, **kwargs):
548
- for k, v in kwargs.items():
549
- if isinstance(v, tuple):
550
- (other_type, left, right) = v
551
- with self._graph.rule():
552
- inst = other_type()
553
- me = self()
554
- getattr(inst, right) == getattr(me, left) # type: ignore
555
- if getattr(self, k).is_multi_valued:
556
- getattr(me, k).add(inst)
557
- else:
558
- me.set(**{k: inst})
559
- else:
560
- raise Exception("Define requires a tuple of (Type, left, right)")
561
- return self
562
-
563
- def keyed(self, **kwargs):
564
- return KeyedType(self, kwargs)
565
-
566
- def __or__(self, __value: Any) -> TypeUnion:
567
- if isinstance(__value, Type) or isinstance(__value, TypeIntersection):
568
- return TypeUnion(self._graph, [self, __value])
569
- if isinstance(__value, TypeUnion):
570
- return TypeUnion(self._graph, [self, *__value._types])
571
- raise Exception("Can't or a type with a non-type")
572
-
573
- def __and__(self, __value: Any) -> TypeIntersection:
574
- if isinstance(__value, Type) or isinstance(__value, TypeUnion):
575
- return TypeIntersection(self._graph, [self, __value])
576
- if isinstance(__value, TypeIntersection):
577
- return TypeIntersection(self._graph, [self, *__value._types])
578
- raise Exception("Can't & a type with a non-type")
579
-
580
- def _make_sub(self, name: str, existing=None):
581
- if existing is not None:
582
- return existing
583
- return Property(self._graph, name, [self._type], self, scope=self._scope)
584
-
585
- def known_properties(self):
586
- return [p.name.removeprefix(self._scope) for p in self._type.properties]
587
-
588
- #--------------------------------------------------
589
- # KeyedType
590
- #--------------------------------------------------
591
-
592
- class KeyedType(Producer):
593
- def __init__(self, type:Type, keys:Dict[str,Type]):
594
- super().__init__(type._graph)
595
- self._type = type
596
- self._relation = RawRelation(self._graph, type._type.name, len(keys))
597
- self._key_info = keys
598
- self._key_order = list(keys.keys())
599
- self._props = {}
600
-
601
- # declare the relation
602
- install = build.install(self._relation._type)
603
- self._graph._action(install)
604
- debugging.set_source(install)
605
-
606
- def _prop(self, name:str):
607
- if name not in self._props:
608
- self._props[name] = RawRelation(self._graph, f"{self._relation._name}_{name}", len(self._key_info)+1)
609
- return self._props[name]
610
-
611
- def extend(self, *args, **kwargs):
612
- raise errors.KeyedCantBeExtended()
613
-
614
- def _collect_keys(self, args:List[Any], kwargs:Dict[str,Any]):
615
- ks = self._key_info.keys()
616
- all_args = dict(zip(ks, args))
617
- all_args.update(kwargs)
618
- props = set(all_args.keys()) - set(ks)
619
- return all_args, {k: all_args.get(k) for k in ks if k in all_args}, {k: all_args[k] for k in props}
620
-
621
- def add(self, *args:Any, **kwargs):
622
- all_args, keys, props = self._collect_keys(list(args), kwargs)
623
- if len(keys) != len(self._key_info):
624
- raise errors.KeyedWrongArity(self._type._type.name, list(self._key_info.keys()), len(keys))
625
- self._relation.add(*keys.values())
626
- for k, v in props.items():
627
- self._prop(k).add(*keys, v)
628
- return KeyedInstance(self, list(keys), {})
629
-
630
- def __call__(self, *args, **kwargs):
631
- all_args, keys, props = self._collect_keys(list(args), kwargs)
632
- ks = self._key_info.keys()
633
- keys = [all_args.get(k, Vars(1)) for k in ks]
634
- self._relation(*keys)
635
- return KeyedInstance(self, keys, props)
636
-
637
- def __getattr__(self, name: str) -> Any:
638
- return self._props[name]
639
-
640
- class KeyedInstance(Producer):
641
- def __init__(self, keyed_type:KeyedType, keys:List[Any], kwargs:dict={}):
642
- self._keys = keys
643
- self._type = keyed_type
644
- for k, v in kwargs.items():
645
- self._type._prop(k)(*keys, v)
646
-
647
- def __getattr__(self, name:str):
648
- if name in self._type._key_order:
649
- return self._keys[self._type._key_order.index(name)]
650
- v = Vars(1)
651
- self._type._prop(name)(*self._keys, v)
652
- return v
653
-
654
- def set(self, **kwargs):
655
- for k, v in kwargs.items():
656
- self._type._prop(k).add(*self._keys, v)
657
- return self
658
-
659
- def __iter__(self):
660
- return iter(self._keys)
661
-
662
- def _to_var(self):
663
- raise Exception("KeyedTypes can't be returned directly, you can only reference properties")
664
-
665
- #--------------------------------------------------
666
- # TypeUnion
667
- #--------------------------------------------------
668
-
669
- class TypeUnion(Producer):
670
- def __init__(self, graph:'Graph', types:List[Type|TypeIntersection]):
671
- super().__init__(graph)
672
- self._types = types
673
-
674
- def __call__(self, *args, **kwargs) -> 'ContextSelect':
675
- if not len(self._graph._stack.stack):
676
- raise Exception("Can't create an instance outside of a context")
677
- graph = self._graph
678
- with graph.union(dynamic=True) as union:
679
- for t in self._types:
680
- with graph.scope():
681
- union.add(t(*args, **kwargs))
682
- return union
683
-
684
- def known_properties(self):
685
- props = []
686
- for t in self._types:
687
- for prop in t.known_properties():
688
- if prop not in props:
689
- props.append(prop)
690
- return props
691
-
692
- def __or__(self, __value: Any) -> 'TypeUnion':
693
- if isinstance(__value, Type):
694
- return TypeUnion(self._graph, [*self._types, __value])
695
- if isinstance(__value, TypeUnion):
696
- return TypeUnion(self._graph, [*self._types, *__value._types])
697
- raise Exception("Can't or a type with a non-type")
698
-
699
- def _make_sub(self, name: str, existing=None):
700
- if existing is not None:
701
- return existing
702
- return Property(self._graph, name, [t._type for t in self._types], self)
703
-
704
- #--------------------------------------------------
705
- # TypeIntersection
706
- #--------------------------------------------------
707
-
708
- class TypeIntersection(Producer):
709
- def __init__(self, graph:'Graph', types:List[Type|TypeUnion]):
710
- super().__init__(graph)
711
- self._types = types
712
-
713
- def __call__(self, *args, **kwargs) -> Producer:
714
- if not len(self._graph._stack.stack):
715
- raise Exception("Can't create an instance outside of a context")
716
- return self._types[0](*self._types[1:], *args, **kwargs)
717
-
718
- def known_properties(self):
719
- props = []
720
- for t in self._types:
721
- for prop in t.known_properties():
722
- if prop not in props:
723
- props.append(prop)
724
- return props
725
-
726
- def __and__(self, __value: Any) -> TypeIntersection:
727
- if isinstance(__value, Type):
728
- return TypeIntersection(self._graph, [*self._types, __value])
729
- if isinstance(__value, TypeIntersection):
730
- return TypeIntersection(self._graph, [*self._types, *__value._types])
731
- raise Exception("Can't & a type with a non-type")
732
-
733
- def _make_sub(self, name: str, existing=None):
734
- if existing is not None:
735
- return existing
736
- return Property(self._graph, name, [t._type for t in self._types], self)
737
-
738
- #--------------------------------------------------
739
- # Property
740
- #--------------------------------------------------
741
-
742
- class Property(Producer):
743
- def __init__(self, graph:'Graph', name:str, types:List[mType], provider:Type|TypeUnion|TypeIntersection, scope:str=""):
744
- super().__init__(graph)
745
- self._name = name
746
- self._type = types[0]
747
- self._scope = scope
748
- self._provider = provider
749
- self._prop = build.property_named(scope+name, types)
750
-
751
- def __call__(self, key:Any, value:Any):
752
- action = build.relation_action(ActionType.Get, self._prop, [key, value])
753
- self._graph._action(action)
754
-
755
- def _use_var(self):
756
- raise Exception("Support properties being used as vars")
757
-
758
- def _make_sub(self, name: str, existing=None):
759
- raise Exception("Support properties on properties?")
760
-
761
- def to_property(self):
762
- return self._prop
763
-
764
- def declare(self):
765
- self._graph._action(build.install(self._prop))
766
-
767
- def has_many(self):
768
- self.declare()
769
- self._graph._check_property(self._prop, multi_valued=True)
770
-
771
- @property
772
- def is_multi_valued(self):
773
- return self._graph._prop_is_multi.get(self._name)
774
-
775
- #--------------------------------------------------
776
- # Instance
777
- #--------------------------------------------------
778
-
779
- class Instance(Producer):
780
- def __init__(self, graph:'Graph', action_type:ActionType, positionals:List[Any], named:Dict[str,Any], var:Var|None=None, name=None, is_add=False, scope:str=""):
781
- super().__init__(graph)
782
- self._action = Action(action_type, to_var(var) if var else Var(name=name))
783
- self._actions = [self._action]
784
- self._sets = {}
785
- self._context = graph._stack.active()
786
- self._scope = scope
787
- available_types = []
788
- last_pos_var = None
789
-
790
- #--------------------------------------------------
791
- # Positionals
792
- #--------------------------------------------------
793
- has_ident = False
794
- for pos in positionals:
795
- if isinstance(pos, Type):
796
- self._action.append(pos._type)
797
- elif isinstance(pos, Instance):
798
- if has_ident:
799
- raise MultipleIdentities()
800
- has_ident = True
801
- self._action.append(to_var(pos))
802
- available_types.extend(pos._action.types)
803
- if last_pos_var:
804
- self._graph._action(build.eq(last_pos_var, self._action.entity))
805
- last_pos_var = self._action.entity
806
- elif isinstance(pos, TypeUnion) or isinstance(pos, TypeIntersection):
807
- self._action.append(to_var(pos()))
808
- available_types.extend([t._type for t in pos._types])
809
- if last_pos_var:
810
- self._graph._action(build.eq(last_pos_var, self._action.entity))
811
- last_pos_var = self._action.entity
812
- elif isinstance(pos, Producer):
813
- if has_ident:
814
- raise MultipleIdentities()
815
- has_ident = True
816
- self._action.append(to_var(pos))
817
- if last_pos_var:
818
- self._graph._action(build.eq(last_pos_var, self._action.entity))
819
- last_pos_var = self._action.entity
820
- elif isinstance(pos, (str, int)):
821
- if has_ident:
822
- raise MultipleIdentities()
823
- has_ident = True
824
- if isinstance(pos, str):
825
- try:
826
- decoded = base64.b64decode(pos + "==")
827
- if len(decoded) == 16:
828
- first_int = decoded[:8]
829
- second_int = decoded[8:]
830
- pos = struct.pack('<Q', struct.unpack('>Q', second_int)[0]) + \
831
- struct.pack('<Q', struct.unpack('>Q', first_int)[0])
832
- except Exception:
833
- pass
834
- self._action.append(Var(value=pos))
835
- last_pos_var = self._action.entity
836
- else:
837
- raise Exception(f"Unknown input type: {pos}")
838
- available_types.extend(self._action.types)
839
- if scope:
840
- available_types = [t for t in available_types if t.name.startswith(scope)]
841
-
842
- #--------------------------------------------------
843
- # Handle properties
844
- #--------------------------------------------------
845
- for name, val in named.items():
846
- prop = build.property_named(scope+name, available_types)
847
-
848
- if val is None:
849
- raise Exception(f"{prop}'s value is None, please provide a value for the property")
850
-
851
- if isinstance(val, int) and action_type == ActionType.Get:
852
- orig = val
853
- val = Vars(1)
854
- self._actions.append(build.eq(val, orig, approx=True))
855
-
856
- prop_var = to_var(val)
857
-
858
- if prop_var.isa(Builtins.ExternalInput):
859
- orig = prop_var
860
- prop_var = to_var(Vars(1))
861
- self._actions.append(build.eq(prop_var, orig, approx=True))
862
-
863
- if is_collection(prop_var.value):
864
- raise Exception("Can't set a property to a collection")
865
-
866
- if not prop_var.name:
867
- prop_var.name = prop.name
868
- if action_type.is_effect():
869
- self._graph._check_property(prop)
870
- else:
871
- self._graph._check_property(prop, unknown_cardinality=True)
872
- self._action.append(prop, prop_var)
873
-
874
- #--------------------------------------------------
875
- # Entities
876
- #--------------------------------------------------
877
- self._var = self._action.entity
878
- if self._var.type == Builtins.Unknown and len(self._action.types):
879
- self._var.type = self._action.types[0]
880
- if not is_add and (self._action.types or self._action.bindings):
881
- self._add_to_graph()
882
-
883
- def _to_var(self):
884
- if not self._graph._stack.contains(self._context):
885
- exception = VariableOutOfContextException(Errors.call_source(), self._var.name)
886
- raise exception from None
887
- return self._var
888
-
889
- def _add_to_graph(self):
890
- for action in self._actions:
891
- self._graph._action(action)
892
-
893
- def __call__(self, *args, **kwargs):
894
- pass
895
-
896
- def __setattr__(self, name: str, value: Any) -> None:
897
- if name.startswith("_"):
898
- return super().__setattr__(name, value)
899
- exception = InvalidPropertySetException(Errors.call_source(3))
900
- raise exception from None
901
-
902
- def _make_sub(self, name: str, existing=None):
903
- if self._sets.get(name) is not None:
904
- return self._sets[name]
905
- if existing is not None:
906
- inst = InstanceProperty(self._graph, self, name, var=existing._var, scope=self._scope)
907
- inst._subs = existing._subs
908
- return inst
909
- prop = build.property_named(self._scope+name, self._action.types)
910
- if self._action.bindings.get(prop):
911
- return InstanceProperty(self._graph, self, name, var=self._action.bindings[prop], scope=self._scope)
912
- return InstanceProperty(self._graph, self, name, scope=self._scope)
913
-
914
- def set(self, *args, **kwargs):
915
- if self._graph._stack.active() is self._context:
916
- self._sets.update(kwargs)
917
- Instance(self._graph, ActionType.Bind, [self, *args], kwargs, var=self._var, scope=self._scope)
918
- return self
919
-
920
- def persist(self, *args, **kwargs):
921
- Instance(self._graph, ActionType.Persist, [self, *args], kwargs, var=self._var, scope=self._scope)
922
- return self
923
-
924
- def unpersist(self, *args, **kwargs):
925
- Instance(self._graph, ActionType.Unpersist, [self, *args], kwargs, var=self._var, scope=self._scope)
926
- return self
927
-
928
- def has_value(self):
929
- return self != rel.Missing # type:ignore
930
-
931
- #--------------------------------------------------
932
- # InstanceProperty
933
- #--------------------------------------------------
934
-
935
- class InstanceProperty(Producer):
936
- def __init__(self, graph:'Graph', instance:Instance, name:str, var=None, scope:str=""):
937
- super().__init__(graph)
938
- self._instance = instance
939
-
940
- self._prop = build.property_named(scope+name, instance._action.types)
941
- self._var = var or Var(self._prop.type, name=name)
942
- self._check_context()
943
- self._scope = scope
944
- new = Instance(self._graph, ActionType.Get, [instance], {name: self._var}, scope=self._scope)
945
- self._action = new._action
946
-
947
- def _check_context(self):
948
- if not self._graph._stack.contains(self._instance._context):
949
- name = f"{self._instance._var.name}.{self._var.name}"
950
- exception = VariableOutOfContextException(Errors.call_source(), name, is_property=True)
951
- raise exception from None
952
-
953
- def __call__(self, *args, **kwargs):
954
- name = f"{self._instance._var.name}.{self._var.name}"
955
- exception = NonCallablePropertyException(Errors.call_source(), name)
956
- raise exception from None
957
-
958
- def _make_sub(self, name: str, existing=None):
959
- if existing is not None and self._graph._stack.is_active(existing._instance._context):
960
- return existing
961
- return getattr(Instance(self._graph, ActionType.Get, [self], {}), name)
962
-
963
- def _to_var(self):
964
- self._check_context()
965
- return self._var
966
-
967
- def or_(self, other):
968
- self._graph._remove_action(self._action)
969
- default = build.call(Builtins.Default, [self._prop, other, self._instance, self])
970
- self._graph._action(default)
971
- return self
972
-
973
- def in_(self, others):
974
- other_rel = InlineRelation(self._graph, [(x,) for x in others])
975
- return self == other_rel
976
-
977
- def has_value(self):
978
- return self != rel.Missing # type:ignore
979
-
980
- def _remove_if_unused(self):
981
- # When calling append/extend we aren't necessarily doing a get on the property,
982
- # but we will already have added one. If we're the only thing using this get,
983
- # we remove it so that it doesn't unnecessarily constrain the query.
984
- remove = False
985
- for item in reversed(self._graph._stack.items):
986
- if item is self._action:
987
- remove = True
988
- break
989
- elif isinstance(item, Action):
990
- if self._var in item.vars():
991
- remove = False
992
- break
993
- if remove:
994
- self._graph._remove_action(self._action)
995
-
996
- def set(self, *args, **kwargs):
997
- return Instance(self._graph, ActionType.Get, [self], {}).set(*args, **kwargs)
998
-
999
- def add(self, other):
1000
- self._remove_if_unused()
1001
- self._graph._check_property(self._prop, multi_valued=True)
1002
- rel = Action(ActionType.Bind, to_var(self._instance), [], {self._prop: to_var(other)})
1003
- self._graph._action(rel)
1004
-
1005
- def extend(self, others):
1006
- self._remove_if_unused()
1007
- self._graph._check_property(self._prop, True)
1008
- for other in others:
1009
- rel = Action(ActionType.Bind, to_var(self._instance), [], {self._prop: to_var(other)})
1010
- self._graph._action(rel)
1011
-
1012
- def choose(self, num, unique=True):
1013
- if num < 1:
1014
- raise ValueError("Must choose a positive number of items")
1015
- self._remove_if_unused()
1016
- items = [getattr(Instance(self._graph, ActionType.Get, [self._instance], {}), self._prop.name) for ix in range(num)]
1017
- if unique:
1018
- for ix in range(num-1):
1019
- items[ix] < items[ix+1]
1020
- return items
1021
-
1022
- #--------------------------------------------------
1023
- # Expression
1024
- #--------------------------------------------------
1025
-
1026
- class Expression(Producer):
1027
- def __init__(self, graph:'Graph', op:mType|Task, args:List[Any]):
1028
-
1029
- super().__init__(graph)
1030
- self._var = None
1031
- self._context = graph._stack.active()
1032
-
1033
- # For calls to tasks with known signatures, normalize their arguments by
1034
- # throwing on missing inputs or constructing vars for missing outputs
1035
- if op.properties and not op.isa(Builtins.Anonymous):
1036
- for prop, arg in zip_longest(op.properties, args):
1037
- if arg is None:
1038
- if prop.is_input:
1039
- raise TypeError(f"{op.name} is missing a required argument: '{prop.name}'")
1040
- else:
1041
- args.append(Var(prop.type, name=prop.name))
1042
-
1043
- # Expose the last output as the result, to ensure we don't double-create it in _use_var.
1044
- # @NOTE: Literal values like 1 show up here from calls like `rel.range(0, len(df), 1)`
1045
- if not op.properties[-1].is_input and isinstance(args[-1], Var):
1046
- self._var = args[-1]
1047
-
1048
- self._expr = build.call(op, args)
1049
- self._graph._action(self._expr)
1050
-
1051
- def __call__(self, *args, **kwargs):
1052
- raise Exception("Expressions can't be called")
1053
-
1054
- def _use_var(self):
1055
- if self._expr.entity.isa(Builtins.Filter):
1056
- if isinstance(runtime_env, SnowbookEnvironment):
1057
- return
1058
- raise FilterAsValue(Errors.call_source())
1059
- elif not self._var:
1060
- self._var = Var(Builtins.Unknown)
1061
- prop = build.property_named("result", self._expr.types)
1062
- self._expr.append(prop, self._var)
1063
-
1064
- if not self._graph._stack.contains(self._context):
1065
- exception = VariableOutOfContextException(Errors.call_source(), self._var.name or "a result")
1066
- raise exception from None
1067
-
1068
- def _make_sub(self, name: str, existing=None):
1069
- if existing is not None and existing._instance._context is self._graph._stack.active():
1070
- return existing
1071
- return getattr(Instance(self._graph, ActionType.Get, [self], {}), name)
1072
-
1073
- def has_value(self):
1074
- return self != rel.Missing # type:ignore
1075
-
1076
- #--------------------------------------------------
1077
- # RelationNS
1078
- #--------------------------------------------------
1079
-
1080
- unsafe_symbol_pattern = re.compile(r"[^a-zA-Z0-9_]", re.UNICODE)
1081
- def safe_symbol(name: str):
1082
- return f':"{name}"' if unsafe_symbol_pattern.search(name) else f":{name}"
1083
-
1084
- class RelationNS():
1085
- def __init__(self, ns:List[str], name:str, use_rel_namespaces=False, tags:List[mType]=[]):
1086
- if name == "getdoc":
1087
- rich.print("[red bold]GETDOC CALLED")
1088
- traceback.print_stack()
1089
- return
1090
- self._name = name
1091
- self._ns = ns
1092
- self._subs = {}
1093
- self._use_rel_namespaces = use_rel_namespaces
1094
- self._rel = self._build_rel()
1095
- self._tags = tags
1096
-
1097
- def __call__(self, *args: Any, **kwds: Any) -> Any:
1098
- op = self._rel
1099
- for t in self._tags:
1100
- tag(self, t)
1101
- self._ensure_args(len(args))
1102
- return Expression(get_graph(), op, list(args))
1103
-
1104
- def __getattr__(self, name: str) -> RelationNS:
1105
- self._subs[name] = self._make_sub(name, self._subs.get(name))
1106
- return self._subs[name]
1107
-
1108
- def _make_sub(self, name: str, existing=None):
1109
- if existing is not None:
1110
- return existing
1111
- ns = self._ns[:]
1112
- if self._name:
1113
- ns.append(self._name)
1114
- return self.__class__(ns, name, use_rel_namespaces=self._use_rel_namespaces, tags=self._tags)
1115
-
1116
- def _build_rel(self, arg_count = 0):
1117
- fqn_parts = self._ns + [self._name]
1118
- if self._use_rel_namespaces:
1119
- return build.relation('::'+'::'.join(fqn_parts), arg_count)
1120
- if len(fqn_parts) == 1:
1121
- return build.relation(fqn_parts[0], arg_count)
1122
- else:
1123
- return build.relation(f"{fqn_parts[0]}[{', '.join(safe_symbol(part) for part in fqn_parts[1:])}]", arg_count)
1124
-
1125
- def _ensure_args(self, arg_count):
1126
- if len(self._rel.properties) <= arg_count:
1127
- self._rel.properties = [Builtins.Relation.properties[i] for i in range(arg_count)]
1128
-
1129
- def add(self, *args):
1130
- op = self._rel
1131
- self._ensure_args(len(args))
1132
- get_graph()._action(build.relation_action(ActionType.Bind, op, list(args)))
1133
-
1134
- def _to_var(self):
1135
- return Var(Builtins.Relation, value=self._build_rel())
1136
-
1137
- def _tagged(self, *tags: mType):
1138
- return self.__class__(self._ns, self._name, use_rel_namespaces=self._use_rel_namespaces, tags=list(tags))
1139
-
1140
- #--------------------------------------------------
1141
- # RawRelation
1142
- #--------------------------------------------------
1143
-
1144
- class RawRelation(Producer):
1145
- def __init__(self, graph:'Graph', name:str, arity:int):
1146
- super().__init__(graph)
1147
- self._name = name
1148
- self._arity = arity
1149
- self._type = build.relation(self._name, self._arity)
1150
-
1151
- def __call__(self, *args: Any, **kwds: Any) -> Any:
1152
- return Expression(self._graph, self._type, list(args))
1153
-
1154
- def add(self, *args):
1155
- self._graph._action(build.relation_action(ActionType.Bind, self._type, list(args)))
1156
-
1157
- def _make_sub(self, name: str, existing=None):
1158
- return existing
1159
-
1160
- def _to_var(self):
1161
- return Var(Builtins.Relation, value=self._type)
1162
-
1163
- #--------------------------------------------------
1164
- # InlineRelation
1165
- #--------------------------------------------------
1166
-
1167
- class InlineRelation():
1168
- def __init__(self, graph:'Graph', data:List[Tuple]):
1169
- self._var = Var(type=Builtins.InlineRawData)
1170
- self._graph = graph
1171
- cols = [[] for _ in range(len(data[0]))]
1172
- for row in data:
1173
- for i, val in enumerate(row):
1174
- cols[i].append(to_var(val))
1175
-
1176
- params = [Var(value=col) for col in cols]
1177
- params.append(self._var)
1178
- q = build.relation_action(ActionType.Get, Builtins.InlineRawData, params)
1179
- self._graph._action(q)
1180
-
1181
- def _to_var(self):
1182
- return self._var
1183
-
1184
- #--------------------------------------------------
1185
- # Rows
1186
- #--------------------------------------------------
1187
-
1188
- class Rows():
1189
- def __init__(self, graph:'Graph', data:List[Any]):
1190
- self._graph = graph
1191
-
1192
- col_names = []
1193
- data_cols = []
1194
-
1195
- size = len(data)
1196
- warning_size = 1000
1197
- error_size = 10000
1198
- if size > error_size:
1199
- raise errors.RowLiteralTooLarge(size, max_size=error_size)
1200
- elif size > warning_size:
1201
- errors.RowLiteralTooLargeWarning(size, max_size=warning_size)
1202
-
1203
- first = data[0]
1204
- if isinstance(first, dict):
1205
- col_names = list(first.keys())
1206
- data_cols = [[] for _ in range(len(col_names))]
1207
- for row in data:
1208
- for ix, col in enumerate(col_names):
1209
- if col not in row:
1210
- raise errors.RowLiteralMismatch("keys")
1211
- data_cols[ix].append(row[col])
1212
- elif isinstance(first, tuple):
1213
- data_cols = [[] for _ in range(len(first))]
1214
- for row in data:
1215
- if len(row) != len(first):
1216
- raise errors.RowLiteralMismatch("length")
1217
- for ix, col in enumerate(row):
1218
- data_cols[ix].append(col)
1219
- elif isinstance(first, list):
1220
- data_cols = [data]
1221
- else:
1222
- raise Exception("Unsupported data type: must be a list")
1223
-
1224
- data_vars = [Var(value=col) for col in data_cols]
1225
- if col_names:
1226
- vars = [Var(name=name) for name in col_names]
1227
- else:
1228
- vars = [Var() for _ in range(len(data_vars))]
1229
-
1230
- self._fetch = build.relation_action(ActionType.Get, Builtins.RawData, [*data_vars, *vars])
1231
- self._var = vars[-1]
1232
- self._vars = vars
1233
- self._columns = col_names
1234
-
1235
- def _add_to_graph(self):
1236
- if not self._graph._in_rule():
1237
- raise errors.OutOfContextException()
1238
- self._graph._action(self._fetch, dedupe=True)
1239
-
1240
- def _to_var(self):
1241
- self._add_to_graph()
1242
- return self._var
1243
-
1244
- def __getitem__(self, index):
1245
- self._add_to_graph()
1246
- if isinstance(index, str):
1247
- return getattr(self, index)
1248
- return self._vars[index]
1249
-
1250
- def __getattr__(self, name):
1251
- if name in self._columns:
1252
- self._add_to_graph()
1253
- return self._vars[self._columns.index(name)]
1254
- raise AttributeError(f"Set has no attribute '{name}'")
1255
-
1256
- #--------------------------------------------------
1257
- # Symbol
1258
- #--------------------------------------------------
1259
-
1260
- class Symbol():
1261
- def __init__(self, name:str):
1262
- self._var = Var(Builtins.Symbol, value=name)
1263
-
1264
- def _to_var(self):
1265
- return self._var
1266
-
1267
- #--------------------------------------------------
1268
- # RelationRef
1269
- #--------------------------------------------------
1270
-
1271
- class RelationRef(Producer):
1272
- def __init__(self, graph:'Graph', rel:Task|mType, args:List[Var]):
1273
- super().__init__(graph)
1274
- self._rel = rel
1275
- self._args = args
1276
- self._var = args[-1]
1277
- self._action = build.relation_action(ActionType.Get, self._rel, self._args)
1278
-
1279
- def _use_var(self):
1280
- self._graph._action(self._action)
1281
-
1282
- def _make_sub(self, name: str, existing=None):
1283
- return getattr(Instance(self._graph, ActionType.Get, [self], {}), name)
1284
-
1285
- def __enter__(self):
1286
- super().__enter__()
1287
- self._use_var()
1288
- Instance(self._graph, ActionType.Get, [self], {}).has_value()
1289
-
1290
- #--------------------------------------------------
1291
- # Export
1292
- #--------------------------------------------------
1293
-
1294
- allowed_export_types = [Type, str, numbers.Number, datetime.datetime, datetime.date, bool]
1295
-
1296
- def check_type(name, type):
1297
- if not any(isinstance(type, t) or (inspect.isclass(type) and issubclass(type, t))
1298
- for t in allowed_export_types):
1299
- raise TypeError(f"Argument '{name}' is an unsupported type: {type}")
1300
-
1301
- def export(model, schema, kwargs):
1302
- try:
1303
- parser = IdentityParser(schema)
1304
- except ParseError as e:
1305
- raise Exception(f"Not able to parse provided schema '{schema}'. {e}")
1306
-
1307
- def decorator(func):
1308
- # Get type hints of the function
1309
- hints = get_type_hints(func)
1310
- input_types = [hints[name] for name in hints if name != 'return']
1311
- arg_names = func.__code__.co_varnames[:func.__code__.co_argcount]
1312
- for name in arg_names:
1313
- if name not in hints:
1314
- raise TypeError(f"Argument '{name}' must have a type hint")
1315
- check_type(name, hints[name])
1316
-
1317
- output_types = []
1318
- has_return_hint = 'return' in hints
1319
- if has_return_hint:
1320
- ret = hints.get('return')
1321
- if typing.get_origin(ret) is tuple:
1322
- for t in typing.get_args(ret):
1323
- check_type("return", t)
1324
- output_types.append(t)
1325
- else:
1326
- check_type("return", ret)
1327
- output_types.append(ret)
1328
- name = f"{schema}.{func.__name__}" if schema else func.__name__
1329
- props = {
1330
- "name": name if parser.entity is None else parser.identity,
1331
- "outputs": output_types if has_return_hint else None,
1332
- }
1333
-
1334
- ctx = Context(model, exec_type=TaskExecType.Procedure, props=props, format="snowpark", **kwargs)
1335
- with ctx as ret:
1336
- inputs = to_list(Vars(len(arg_names)))
1337
- for i in inputs:
1338
- i._var.type = Builtins.ExternalInput
1339
- props["inputs"] = list(zip(arg_names, [to_var(i) for i in inputs], input_types))
1340
- outs = to_list(func(*inputs))
1341
- if has_return_hint and len(outs) != len(output_types):
1342
- raise TypeError(f"Function '{func.__name__}' must return {len(output_types)} values according to the type hints")
1343
- ret(*outs)
1344
-
1345
- def wrapper():
1346
- raise Exception("Exports can't be called directly. They are exported to the underlying platform")
1347
-
1348
- return wrapper
1349
- return decorator
1350
-
1351
- #--------------------------------------------------
1352
- # RuleStack
1353
- #--------------------------------------------------
1354
-
1355
- class RuleStack():
1356
- def __init__(self, graph:'Graph'):
1357
- self.items = []
1358
- self.stack = []
1359
- self._graph = graph
1360
-
1361
- def push(self, item):
1362
- self.stack.append(item)
1363
- self.items.append(("push", item))
1364
-
1365
- def pop(self, item, globalize=False):
1366
- self.stack.pop()
1367
- self.items.append(("pop", item))
1368
- if len(self.stack) == 0:
1369
- compacted = self.compact()
1370
- self.items.clear()
1371
- if len(compacted.items):
1372
- return compacted
1373
- elif globalize:
1374
- ix = self.items.index(("push", item))
1375
- temp_items = self.items[0:ix]
1376
- self.items = self.items[ix:]
1377
- compacted = self.compact()
1378
- self.items = temp_items
1379
- if len(compacted.items):
1380
- return compacted
1381
-
1382
- def push_item(self, item):
1383
- if not len(self.stack):
1384
- raise Exception("Can't push a non-context item onto an empty stack")
1385
- self.items.append(item)
1386
-
1387
- def contains(self, item):
1388
- for i in self.stack:
1389
- if i is item:
1390
- return True
1391
-
1392
- def is_active(self, item):
1393
- if isinstance(item, Context) and item._task.behavior != Behavior.Query:
1394
- return False
1395
- return item is self.active()
1396
-
1397
- def in_context(self, item):
1398
- if isinstance(item, Context) and item._task.behavior != Behavior.Query:
1399
- return False
1400
- return self.contains(item)
1401
-
1402
- def active(self):
1403
- try:
1404
- cur = self.stack[-1]
1405
- if cur is self._graph._temp_rule:
1406
- exception = OutOfContextException(Errors.call_source())
1407
- raise exception from None
1408
- return cur
1409
- except IndexError:
1410
- exception = OutOfContextException(Errors.call_source())
1411
- raise exception from None
1412
-
1413
- def _expression_start(self, buffer, single_use_vars):
1414
- consume_from = -1
1415
- if not len(buffer):
1416
- return consume_from
1417
- # we can only pull vars if their only use is for this condition
1418
- used_vars = set(buffer[-1].requires_provides()[0] & single_use_vars)
1419
- # walk buffer in reverse collecting vars in the action until we get one
1420
- # that doesn't provide a var we care about
1421
- for action in reversed(buffer[:-1]):
1422
- if not isinstance(action, Action):
1423
- break
1424
- req, provs, _ = action.requires_provides()
1425
- # don't pull in vars the represent root entities even though they're provided
1426
- # by gets. This prevents scenarios where p = Person() would get pulled in if you
1427
- # did with p.age > 10:
1428
- provs = provs - {action.entity}
1429
- if len(used_vars.intersection(provs)):
1430
- used_vars.update(req & single_use_vars)
1431
- consume_from -= 1
1432
- else:
1433
- break
1434
- return consume_from
1435
-
1436
- def compact(self) -> Task:
1437
- stack:List[Task] = []
1438
- buffer = []
1439
-
1440
- var_uses = {}
1441
- for item in self.items:
1442
- if isinstance(item, Action):
1443
- if item.action == ActionType.Get:
1444
- for var in item.vars():
1445
- var_uses[var] = var_uses.get(var, 0) + 1
1446
- else:
1447
- for var in item.vars():
1448
- var_uses[var] = var_uses.get(var, 0) - 1
1449
-
1450
- # check for 2 refs - one create and one use
1451
- single_use_vars = set([var for var, uses in var_uses.items() if uses >= 0])
1452
-
1453
- for item in self.items:
1454
- if not isinstance(item, tuple):
1455
- buffer.append(item)
1456
- continue
1457
-
1458
- op, value = item
1459
- if op == "push":
1460
- if isinstance(value, Context):
1461
- if len(buffer):
1462
- stack[-1].items.extend(buffer)
1463
- buffer.clear()
1464
- task = value._task
1465
- elif isinstance(value, RelationRef):
1466
- if len(buffer):
1467
- stack[-1].items.extend(buffer)
1468
- buffer.clear()
1469
- task = Task()
1470
-
1471
- elif isinstance(value, Producer):
1472
- consume_from = self._expression_start(buffer, single_use_vars)
1473
- stack[-1].items.extend(buffer[:consume_from])
1474
- buffer = buffer[consume_from:]
1475
- task = Task()
1476
- else:
1477
- raise Exception(f"Unknown push type: {type(value)}")
1478
-
1479
- stack.append(task)
1480
-
1481
- elif op == "pop":
1482
- cur = stack.pop()
1483
- cur.items.extend(buffer)
1484
- buffer.clear()
1485
- if not len(stack):
1486
- return cur
1487
- if isinstance(value, Context) and value._op:
1488
- stack[-1].items.append(build.call(value._op, [Var(value=value._args), Var(Builtins.Task, value=cur)]))
1489
- else:
1490
- stack[-1].items.append(build.call(cur, list(cur.bindings.values())))
1491
-
1492
- raise Exception("No task found")
1493
-
1494
- #--------------------------------------------------
1495
- # Graph
1496
- #--------------------------------------------------
1497
-
1498
- locals = threading.local()
1499
- locals.graph_stack = []
1500
-
1501
- def get_graph() -> 'Graph':
1502
- _ensure_stack()
1503
- if not len(locals.graph_stack):
1504
- raise Exception("Outside of a model context")
1505
- return locals.graph_stack[-1]
1506
-
1507
- def _ensure_stack():
1508
- if not hasattr(locals, "graph_stack"):
1509
- locals.graph_stack = []
1510
- return locals.graph_stack
1511
-
1512
- rel = RelationNS([], "")
1513
- global_ns = RelationNS([], "", use_rel_namespaces=True)
1514
-
1515
- def alias(ref:Any, name:str):
1516
- var = to_var(ref)
1517
- var.name = name
1518
- return var
1519
-
1520
- def tag(ref:Any, tag:mType):
1521
- if isinstance(ref, RelationNS):
1522
- parents = ref._rel.parents
1523
- elif isinstance(ref, Type):
1524
- parents = ref._type.parents
1525
- elif isinstance(ref, Property):
1526
- parents = ref._type.parents
1527
- else:
1528
- return
1529
- if tag not in parents:
1530
- parents.append(tag)
1531
-
1532
- def create_var() -> Instance:
1533
- return Instance(get_graph(), ActionType.Get, [], {}, Var(Builtins.Unknown))
1534
-
1535
- def create_vars(count: int) -> List[Instance]:
1536
- return [create_var() for _ in range(count)]
1537
-
1538
- def Vars(count: int):
1539
- if count == 1:
1540
- return create_var()
1541
- return create_vars(count)
1542
-
1543
- class Graph:
1544
- def __init__(self, client:Client, name:str, format:str="default"):
1545
- self.name = name
1546
- self._executed = []
1547
- self._client = client
1548
- self._config = client.resources.config
1549
- self.resources = client.resources
1550
- self._prop_is_multi:Dict[str, bool] = {}
1551
- self._format = format
1552
- self._stack = RuleStack(self)
1553
- self._restore_temp()
1554
-
1555
- self._Error = Type(self, "Error", scope="pyrel_error_")
1556
- self._error_props = set()
1557
-
1558
-
1559
- #--------------------------------------------------
1560
- # Rule stack
1561
- #--------------------------------------------------
1562
-
1563
- def _flush_temp(self):
1564
- if self._temp_rule:
1565
- self._pop(self._temp_rule, is_temp=True)
1566
- if not len(_ensure_stack()):
1567
- _ensure_stack().append(self)
1568
- self._temp_rule = None
1569
-
1570
- def _restore_temp(self):
1571
- self._temp_rule = Context(self)
1572
- _ensure_stack().append(self)
1573
- self._stack.push(self._temp_rule)
1574
-
1575
- def _temp_is_active(self):
1576
- return self._temp_rule and len(self._stack.items) > 1
1577
-
1578
- def _in_rule(self):
1579
- return not self._temp_rule
1580
-
1581
- def _push(self, item):
1582
- _ensure_stack().append(self)
1583
- self._flush_temp()
1584
- self._stack.push(item)
1585
-
1586
- def _pop(self, item, exec=True, is_temp=False, globalize=False):
1587
- _ensure_stack().pop()
1588
- task = self._stack.pop(item, globalize=globalize)
1589
- try:
1590
- if exec and task:
1591
- self._exec(item, task)
1592
- finally:
1593
- if not is_temp and not len(self._stack.stack):
1594
- self._restore_temp()
1595
-
1596
- def _action(self, action:Action|List[Action], dedupe=False):
1597
- if isinstance(action, list):
1598
- for a in action:
1599
- self._action(a, dedupe=dedupe)
1600
- return
1601
- if dedupe and self._stack.contains(action):
1602
- return
1603
- self._stack.push_item(action)
1604
-
1605
- def _remove_action(self, action):
1606
- self._stack.items.remove(action)
1607
-
1608
- def _exec(self, context:Context, task):
1609
- props = context._props
1610
- if context._exec_type == TaskExecType.Rule:
1611
- self._client.install(f"rule{len(self._executed)}", context._task)
1612
- elif context._exec_type == TaskExecType.Query:
1613
- headers = {QUERY_ATTRIBUTES_HEADER: json.dumps(context._attributes)} if context._attributes else {}
1614
- context.results = self._client.query(context._task, tag=context._tag, format=context._format, headers=headers, read_only=context._read_only, skip_invalid_data=context._skip_invalid_data)
1615
- elif context._exec_type == TaskExecType.Procedure:
1616
- self._client.export_udf(props["name"], props["inputs"], props["outputs"], context._task, props.get("engine"), skip_invalid_data=context._skip_invalid_data)
1617
- elif context._exec_type == TaskExecType.Export:
1618
- self._client.export_table(props["name"], props["rel"], props["columns"], context._task, engine=props.get("engine"), refresh=props.get("refresh"))
1619
- self._executed.append(context)
1620
-
1621
- #--------------------------------------------------
1622
- # Property handling
1623
- #--------------------------------------------------
1624
-
1625
- def _check_property(self, prop:mProperty, multi_valued=False, unknown_cardinality=False):
1626
- name = prop.name
1627
- if name in RESERVED_PROPS:
1628
- exception = ReservedPropertyException(Errors.call_source(), name)
1629
- raise exception from None
1630
-
1631
- if unknown_cardinality:
1632
- if name in self._prop_is_multi and self._prop_is_multi[name] and Builtins.MultiValued not in prop.parents:
1633
- prop.parents.append(Builtins.MultiValued)
1634
- return
1635
-
1636
- if name in self._prop_is_multi:
1637
- if self._prop_is_multi[name] != multi_valued:
1638
- raise Exception(
1639
- f"Trying to use a property `{name}` as both singular and multi-valued. "
1640
- "This often happens when multiple types have a property with the same name, but one is single-valued and the other is multi-valued. "
1641
- "Consider using a plural name for the multi-valued property. "
1642
- "See https://relational.ai/docs/develop/core-concepts#setting-object-properties for more information."
1643
- )
1644
- elif self._prop_is_multi[name] and Builtins.MultiValued not in prop.parents:
1645
- prop.parents.append(Builtins.MultiValued)
1646
- else:
1647
- self._prop_is_multi[name] = multi_valued
1648
-
1649
- if not multi_valued and Builtins.FunctionAnnotation not in prop.parents:
1650
- prop.parents.append(Builtins.FunctionAnnotation)
1651
- elif multi_valued and Builtins.MultiValued not in prop.parents:
1652
- prop.parents.append(Builtins.MultiValued)
1653
-
1654
- #--------------------------------------------------
1655
- # Public API
1656
- #--------------------------------------------------
1657
-
1658
- def Type(self, name:str, source=None):
1659
- if source:
1660
- return self.resources.to_model_type(self, name, source)
1661
- return Type(self, name)
1662
-
1663
- def _error_like(self, message:str, kwargs:Dict[str, Any], is_error:bool):
1664
- kwargs["message"] = message
1665
- kwargs["severity"] = "error" if is_error else "warning"
1666
- source = Errors.call_source()
1667
- id = 0
1668
- if source:
1669
- id = len(errors.ModelError.error_locations)
1670
- errors.ModelError.error_locations[id] = source
1671
- kwargs["pyrel_id"] = id
1672
- for k, v in kwargs.items():
1673
- if k not in self._error_props:
1674
- self._error_props.add(k)
1675
- with self.rule():
1676
- e = self._Error()
1677
- rel.output.pyrel_error.add(e, k, getattr(e, k))
1678
- if is_error:
1679
- with self.case():
1680
- self._Error(pyrel_id=id)
1681
- rel.abort.add()
1682
- return self._Error.add(**kwargs)
1683
-
1684
- def error(self, message:str, **kwargs):
1685
- return self._error_like(message, kwargs, is_error=True)
1686
-
1687
- def warn(self, message:str, **kwargs):
1688
- return self._error_like(message, kwargs, is_error=False)
1689
-
1690
- def rule(self, **kwargs):
1691
- return Context(self, **kwargs)
1692
-
1693
- def scope(self, **kwargs):
1694
- return Context(self, **kwargs)
1695
-
1696
- def case(self, **kwargs):
1697
- return Context(self, **kwargs)
1698
-
1699
- def match(self, multiple=False, **kwargs):
1700
- if not multiple:
1701
- return Context(self, behavior=Behavior.OrderedChoice, **kwargs)
1702
- else:
1703
- return Context(self, behavior=Behavior.Union, **kwargs)
1704
-
1705
- def query(self, **kwargs):
1706
- return Context(self, exec_type=TaskExecType.Query, **kwargs)
1707
-
1708
- def export(self, object:str = "", **kwargs):
1709
- return export(self, object, kwargs)
1710
-
1711
- def found(self, **kwargs):
1712
- return Context(self, op=Builtins.Exists, **kwargs)
1713
-
1714
- def not_found(self, **kwargs):
1715
- return Context(self, op=Builtins.Not, **kwargs)
1716
-
1717
- def union(self, **kwargs):
1718
- return Context(self, behavior=Behavior.Union, **kwargs)
1719
-
1720
- def ordered_choice(self, **kwargs):
1721
- return Context(self, behavior=Behavior.OrderedChoice, **kwargs)
1722
-
1723
- def read(self, name:str, **kwargs):
1724
- from relationalai.loaders.loader import read_resource_context # We do the late import to break an dependency cycle
1725
- return read_resource_context(self, name, **kwargs)
1726
-
1727
- def load_raw(self, path:str):
1728
- if os.path.isfile(path):
1729
- if path.endswith('.rel'):
1730
- self._client.load_raw_file(path)
1731
- elif os.path.isdir(path):
1732
- for root, _, files in os.walk(path):
1733
- for file in files:
1734
- if file.endswith('.rel'):
1735
- file_path = os.path.join(root, file)
1736
- self._client.load_raw_file(file_path)
1737
-
1738
- def exec_raw(self, code:str, readonly=False, raw_results=True, abort_on_error=True, inputs={}, query_timeout_mins: Optional[int]=None):
1739
- try:
1740
- return self._client.exec_raw(code, readonly=readonly, raw_results=raw_results, inputs=inputs, abort_on_error=abort_on_error, query_timeout_mins=query_timeout_mins)
1741
- except KeyboardInterrupt as e:
1742
- print("Canceling transactions...")
1743
- self.resources.cancel_pending_transactions()
1744
- raise e
1745
- except RAIException as e:
1746
- raise e.clone(self._config) from None
1747
-
1748
- def install_raw(self, code:str, name:str|None = None, overwrite=False):
1749
- self._client.install_raw(code, name, overwrite)