relationalai 1.0.0a1__py3-none-any.whl → 1.0.0a3__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 (57) hide show
  1. relationalai/semantics/frontend/base.py +3 -0
  2. relationalai/semantics/frontend/front_compiler.py +5 -2
  3. relationalai/semantics/metamodel/builtins.py +2 -1
  4. relationalai/semantics/metamodel/metamodel.py +32 -4
  5. relationalai/semantics/metamodel/pprint.py +5 -3
  6. relationalai/semantics/metamodel/typer.py +324 -297
  7. relationalai/semantics/std/aggregates.py +0 -1
  8. relationalai/semantics/std/datetime.py +4 -1
  9. relationalai/shims/executor.py +26 -5
  10. relationalai/shims/mm2v0.py +119 -44
  11. {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a3.dist-info}/METADATA +1 -1
  12. {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a3.dist-info}/RECORD +57 -48
  13. v0/relationalai/__init__.py +69 -22
  14. v0/relationalai/clients/__init__.py +15 -2
  15. v0/relationalai/clients/client.py +4 -4
  16. v0/relationalai/clients/local.py +5 -5
  17. v0/relationalai/clients/resources/__init__.py +8 -0
  18. v0/relationalai/clients/{azure.py → resources/azure/azure.py} +12 -12
  19. v0/relationalai/clients/resources/snowflake/__init__.py +20 -0
  20. v0/relationalai/clients/resources/snowflake/cli_resources.py +87 -0
  21. v0/relationalai/clients/resources/snowflake/direct_access_resources.py +711 -0
  22. v0/relationalai/clients/resources/snowflake/engine_state_handlers.py +309 -0
  23. v0/relationalai/clients/resources/snowflake/error_handlers.py +199 -0
  24. v0/relationalai/clients/resources/snowflake/resources_factory.py +99 -0
  25. v0/relationalai/clients/{snowflake.py → resources/snowflake/snowflake.py} +606 -1392
  26. v0/relationalai/clients/{use_index_poller.py → resources/snowflake/use_index_poller.py} +43 -12
  27. v0/relationalai/clients/resources/snowflake/use_index_resources.py +188 -0
  28. v0/relationalai/clients/resources/snowflake/util.py +387 -0
  29. v0/relationalai/early_access/dsl/ir/executor.py +4 -4
  30. v0/relationalai/early_access/dsl/snow/api.py +2 -1
  31. v0/relationalai/errors.py +23 -0
  32. v0/relationalai/experimental/solvers.py +7 -7
  33. v0/relationalai/semantics/devtools/benchmark_lqp.py +4 -5
  34. v0/relationalai/semantics/devtools/extract_lqp.py +1 -1
  35. v0/relationalai/semantics/internal/internal.py +4 -4
  36. v0/relationalai/semantics/internal/snowflake.py +3 -2
  37. v0/relationalai/semantics/lqp/executor.py +20 -22
  38. v0/relationalai/semantics/lqp/model2lqp.py +42 -4
  39. v0/relationalai/semantics/lqp/passes.py +1 -1
  40. v0/relationalai/semantics/lqp/rewrite/cdc.py +1 -1
  41. v0/relationalai/semantics/lqp/rewrite/extract_keys.py +53 -12
  42. v0/relationalai/semantics/metamodel/builtins.py +8 -6
  43. v0/relationalai/semantics/metamodel/rewrite/flatten.py +9 -4
  44. v0/relationalai/semantics/metamodel/util.py +6 -5
  45. v0/relationalai/semantics/reasoners/graph/core.py +8 -9
  46. v0/relationalai/semantics/rel/executor.py +14 -11
  47. v0/relationalai/semantics/sql/compiler.py +2 -2
  48. v0/relationalai/semantics/sql/executor/snowflake.py +9 -5
  49. v0/relationalai/semantics/tests/test_snapshot_abstract.py +1 -1
  50. v0/relationalai/tools/cli.py +26 -30
  51. v0/relationalai/tools/cli_helpers.py +10 -2
  52. v0/relationalai/util/otel_configuration.py +2 -1
  53. v0/relationalai/util/otel_handler.py +1 -1
  54. {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a3.dist-info}/WHEEL +0 -0
  55. {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a3.dist-info}/entry_points.txt +0 -0
  56. {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a3.dist-info}/top_level.txt +0 -0
  57. /v0/relationalai/clients/{cache_store.py → resources/snowflake/cache_store.py} +0 -0
@@ -432,6 +432,9 @@ class Table(Concept):
432
432
  for col_name, col_type_name in schema.items():
433
433
  col_type = _find_concept(self._model, col_type_name, default=CoreConcepts["Any"])
434
434
  col_rel = self._dot(col_name, with_type=col_type)
435
+ col_rel._short_name = col_name
436
+ if col_type is not None:
437
+ col_rel._fields[1].type = col_type
435
438
  self._known_columns.append(col_rel)
436
439
  return self._known_columns
437
440
 
@@ -225,8 +225,11 @@ def handle_concept_expression(compiler:FrontCompiler, ctx:Context, expr:Expressi
225
225
 
226
226
  # Update identity and non-identity attributes
227
227
  for k, v in kwargs.items():
228
- rel = passed_concept._dot(k)
229
- ctx.add_update(rel, [root_id, compiler.lookup(ctx, v)], source=source)
228
+ with ctx.subcontext():
229
+ rel = passed_concept._dot(k)
230
+ ctx.add_update(rel, [root_id, compiler.lookup(ctx, v)], source=source)
231
+ nodes = tuple(ctx.nodes)
232
+ ctx.add(Logical(nodes, source=source, optional=True))
230
233
 
231
234
  ctx.construct_handled.add(expr)
232
235
 
@@ -35,6 +35,7 @@ class CoreLibrary:
35
35
  Date: mm.ScalarType
36
36
  DateTime: mm.ScalarType
37
37
  Float: mm.ScalarType
38
+ Hash: mm.ScalarType
38
39
  # type aliases
39
40
  Integer: mm.NumberType
40
41
  DefaultNumber: mm.NumberType
@@ -155,7 +156,7 @@ def is_number(t: mm.Type) -> bool:
155
156
  """ True if the type is a number type. """
156
157
  # note that builtins.core.Number is a ScalarType that represents "any number type",
157
158
  # whereas concrete numbers are represented by NumberType instances.
158
- return isinstance(t, mm.NumberType) or t == builtins.core.Number
159
+ return isinstance(t, mm.NumberType) or t == builtins.core.Number or t == builtins.core.ScaledNumber
159
160
 
160
161
  def is_numeric(t: mm.Type) -> bool:
161
162
  """ True if the type is numeric (Number or Float). """
@@ -56,6 +56,11 @@ class Node():
56
56
  changes["id"] = self.id
57
57
  return replace(self, **changes)
58
58
 
59
+ def replace(self: Self, **changes) -> Self:
60
+ """Convenience to return a modified copy, with a new id."""
61
+ changes["id"] = _next_id()
62
+ return replace(self, **changes)
63
+
59
64
  #-----------------------------------------------------------------------------
60
65
  # Capabilities, Reasoners
61
66
  #-----------------------------------------------------------------------------
@@ -172,28 +177,51 @@ class NumberType(ScalarType):
172
177
  scale: int = 14
173
178
 
174
179
  def __hash__(self) -> int:
175
- return hash(self.id)
180
+ return hash((self.precision, self.scale))
181
+
182
+ def __eq__(self, other: Any) -> bool:
183
+ if not isinstance(other, NumberType):
184
+ return False
185
+ return self.precision == other.precision and self.scale == other.scale
176
186
 
177
187
  @dataclass(repr=False, frozen=True, slots=True)
178
188
  class UnionType(TypeNode):
179
189
  types: ISeq[TypeNode] = field(default=())
180
190
 
191
+ def __post_init__(self):
192
+ object.__setattr__(self, "types", tuple(sorted(self.types, key=lambda t: hash(t))))
193
+
181
194
  def __hash__(self) -> int:
182
- return hash(self.id)
195
+ return hash(self.types)
196
+
197
+ def __eq__(self, other: Any) -> bool:
198
+ if not isinstance(other, UnionType):
199
+ return False
200
+ return len(self.types) == len(other.types) and all(any(t1 == t2 for t2 in other.types) for t1 in self.types)
183
201
 
184
202
  @dataclass(repr=False, frozen=True, slots=True)
185
203
  class ListType(TypeNode):
186
204
  element_type: TypeNode = field(default_factory=TypeNode)
187
205
 
188
206
  def __hash__(self) -> int:
189
- return hash(self.id)
207
+ return hash((self.element_type))
208
+
209
+ def __eq__(self, other: Any) -> bool:
210
+ if not isinstance(other, ListType):
211
+ return False
212
+ return self.element_type == other.element_type
190
213
 
191
214
  @dataclass(repr=False, frozen=True, slots=True)
192
215
  class TupleType(TypeNode):
193
216
  element_types: ISeq[TypeNode] = field(default=())
194
217
 
195
218
  def __hash__(self) -> int:
196
- return hash(self.id)
219
+ return hash(self.element_types)
220
+
221
+ def __eq__(self, other: Any) -> bool:
222
+ if not isinstance(other, TupleType):
223
+ return False
224
+ return self.element_types == other.element_types
197
225
 
198
226
  # Type alias to mirror the spec's union
199
227
  Type = TypeNode
@@ -340,7 +340,7 @@ class Printer():
340
340
  )
341
341
  return
342
342
 
343
- yield _indent_line(indent, repr(task))
343
+ yield _indent_line(indent, object.__repr__(task))
344
344
 
345
345
  def _render_model(self, model: Model, indent: int = 0) -> Iterable[str]:
346
346
  summary_parts: List[str] = []
@@ -370,7 +370,7 @@ class Printer():
370
370
  if isinstance(model.root, Task):
371
371
  yield from self._render_task(model.root, indent + 2)
372
372
  else:
373
- yield _indent_line(indent + 2, repr(model.root))
373
+ yield _indent_line(indent + 2, object.__repr__(model.root))
374
374
 
375
375
  def format_task(self, task: Task, indent: Optional[int] = None) -> str:
376
376
  start_indent = 0 if indent is None else indent
@@ -398,8 +398,10 @@ class Printer():
398
398
  return "List\n" + "\n".join(self.format(n, start_indent+1) for n in node)
399
399
  elif isinstance(node, Field):
400
400
  return self.value(node)
401
+ elif isinstance(node, Annotation):
402
+ return self.annotation(node)
401
403
  else:
402
- return repr(node)
404
+ return object.__repr__(node)
403
405
 
404
406
 
405
407
  def format(node: Node|list|tuple, indent: Optional[int] = None) -> str: