relationalai 1.0.0a1__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.
- relationalai/semantics/frontend/base.py +3 -0
- relationalai/semantics/frontend/front_compiler.py +5 -2
- relationalai/semantics/metamodel/builtins.py +2 -1
- relationalai/semantics/metamodel/metamodel.py +32 -4
- relationalai/semantics/metamodel/pprint.py +5 -3
- relationalai/semantics/metamodel/typer.py +324 -297
- relationalai/semantics/std/aggregates.py +0 -1
- relationalai/semantics/std/datetime.py +4 -1
- relationalai/shims/executor.py +22 -4
- relationalai/shims/mm2v0.py +108 -38
- {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a2.dist-info}/METADATA +1 -1
- {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a2.dist-info}/RECORD +27 -27
- v0/relationalai/errors.py +23 -0
- v0/relationalai/semantics/internal/internal.py +4 -4
- v0/relationalai/semantics/internal/snowflake.py +2 -1
- v0/relationalai/semantics/lqp/executor.py +16 -11
- v0/relationalai/semantics/lqp/model2lqp.py +42 -4
- v0/relationalai/semantics/lqp/passes.py +1 -1
- v0/relationalai/semantics/lqp/rewrite/cdc.py +1 -1
- v0/relationalai/semantics/lqp/rewrite/extract_keys.py +53 -12
- v0/relationalai/semantics/metamodel/builtins.py +8 -6
- v0/relationalai/semantics/metamodel/rewrite/flatten.py +9 -4
- v0/relationalai/semantics/reasoners/graph/core.py +8 -9
- v0/relationalai/semantics/sql/compiler.py +2 -2
- {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a2.dist-info}/WHEEL +0 -0
- {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a2.dist-info}/entry_points.txt +0 -0
- {relationalai-1.0.0a1.dist-info → relationalai-1.0.0a2.dist-info}/top_level.txt +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
|
-
|
|
229
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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,
|
|
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,
|
|
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
|
|
404
|
+
return object.__repr__(node)
|
|
403
405
|
|
|
404
406
|
|
|
405
407
|
def format(node: Node|list|tuple, indent: Optional[int] = None) -> str:
|