inputlayer-client-dev 0.1.0__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.
- inputlayer/__init__.py +151 -0
- inputlayer/_ast.py +133 -0
- inputlayer/_naming.py +44 -0
- inputlayer/_protocol.py +225 -0
- inputlayer/_proxy.py +244 -0
- inputlayer/aggregations.py +126 -0
- inputlayer/auth.py +70 -0
- inputlayer/client.py +178 -0
- inputlayer/client_sync.py +231 -0
- inputlayer/compiler.py +672 -0
- inputlayer/connection.py +314 -0
- inputlayer/derived.py +141 -0
- inputlayer/exceptions.py +76 -0
- inputlayer/functions.py +285 -0
- inputlayer/index.py +40 -0
- inputlayer/knowledge_graph.py +589 -0
- inputlayer/migrations/__init__.py +51 -0
- inputlayer/migrations/autodetector.py +120 -0
- inputlayer/migrations/cli.py +254 -0
- inputlayer/migrations/executor.py +95 -0
- inputlayer/migrations/loader.py +91 -0
- inputlayer/migrations/operations.py +298 -0
- inputlayer/migrations/recorder.py +44 -0
- inputlayer/migrations/state.py +107 -0
- inputlayer/migrations/writer.py +183 -0
- inputlayer/notifications.py +83 -0
- inputlayer/py.typed +0 -0
- inputlayer/relation.py +102 -0
- inputlayer/result.py +89 -0
- inputlayer/session.py +75 -0
- inputlayer/types.py +192 -0
- inputlayer_client_dev-0.1.0.dist-info/METADATA +364 -0
- inputlayer_client_dev-0.1.0.dist-info/RECORD +35 -0
- inputlayer_client_dev-0.1.0.dist-info/WHEEL +4 -0
- inputlayer_client_dev-0.1.0.dist-info/entry_points.txt +2 -0
inputlayer/functions.py
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"""Built-in functions that compile to Datalog function calls.
|
|
2
|
+
|
|
3
|
+
Each function returns a FuncCall AST node (an Expr) that the compiler
|
|
4
|
+
serialises as ``func_name(arg1, arg2, ...)``.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from inputlayer._ast import Expr, FuncCall, Literal
|
|
10
|
+
from inputlayer._proxy import ColumnProxy
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _e(v: ColumnProxy | Expr | int | float | str | list) -> Expr:
|
|
14
|
+
"""Coerce a value to an Expr."""
|
|
15
|
+
if isinstance(v, ColumnProxy):
|
|
16
|
+
return v._to_ast()
|
|
17
|
+
if isinstance(v, Expr):
|
|
18
|
+
return v
|
|
19
|
+
return Literal(v)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# ── Distance (4) ──────────────────────────────────────────────────────
|
|
23
|
+
|
|
24
|
+
def euclidean(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr | list) -> FuncCall:
|
|
25
|
+
return FuncCall("euclidean", (_e(v1), _e(v2)))
|
|
26
|
+
|
|
27
|
+
def cosine(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr | list) -> FuncCall:
|
|
28
|
+
return FuncCall("cosine", (_e(v1), _e(v2)))
|
|
29
|
+
|
|
30
|
+
def dot(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr | list) -> FuncCall:
|
|
31
|
+
return FuncCall("dot", (_e(v1), _e(v2)))
|
|
32
|
+
|
|
33
|
+
def manhattan(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr | list) -> FuncCall:
|
|
34
|
+
return FuncCall("manhattan", (_e(v1), _e(v2)))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# ── Vector Operations (4) ────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
def normalize(v: ColumnProxy | Expr) -> FuncCall:
|
|
40
|
+
return FuncCall("normalize", (_e(v),))
|
|
41
|
+
|
|
42
|
+
def vec_dim(v: ColumnProxy | Expr) -> FuncCall:
|
|
43
|
+
return FuncCall("vec_dim", (_e(v),))
|
|
44
|
+
|
|
45
|
+
def vec_add(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr) -> FuncCall:
|
|
46
|
+
return FuncCall("vec_add", (_e(v1), _e(v2)))
|
|
47
|
+
|
|
48
|
+
def vec_scale(v: ColumnProxy | Expr, s: ColumnProxy | Expr | float) -> FuncCall:
|
|
49
|
+
return FuncCall("vec_scale", (_e(v), _e(s)))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# ── LSH (3) ───────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
def lsh_bucket(
|
|
55
|
+
v: ColumnProxy | Expr,
|
|
56
|
+
table_idx: ColumnProxy | Expr | int,
|
|
57
|
+
num_hp: ColumnProxy | Expr | int,
|
|
58
|
+
) -> FuncCall:
|
|
59
|
+
return FuncCall("lsh_bucket", (_e(v), _e(table_idx), _e(num_hp)))
|
|
60
|
+
|
|
61
|
+
def lsh_probes(
|
|
62
|
+
bucket: ColumnProxy | Expr | int,
|
|
63
|
+
num_hp: ColumnProxy | Expr | int,
|
|
64
|
+
num_probes: ColumnProxy | Expr | int,
|
|
65
|
+
) -> FuncCall:
|
|
66
|
+
return FuncCall("lsh_probes", (_e(bucket), _e(num_hp), _e(num_probes)))
|
|
67
|
+
|
|
68
|
+
def lsh_multi_probe(
|
|
69
|
+
v: ColumnProxy | Expr,
|
|
70
|
+
table_idx: ColumnProxy | Expr | int,
|
|
71
|
+
num_hp: ColumnProxy | Expr | int,
|
|
72
|
+
num_probes: ColumnProxy | Expr | int,
|
|
73
|
+
) -> FuncCall:
|
|
74
|
+
return FuncCall("lsh_multi_probe", (_e(v), _e(table_idx), _e(num_hp), _e(num_probes)))
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# ── Quantization (4) ─────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
def quantize_linear(v: ColumnProxy | Expr) -> FuncCall:
|
|
80
|
+
return FuncCall("quantize_linear", (_e(v),))
|
|
81
|
+
|
|
82
|
+
def quantize_symmetric(v: ColumnProxy | Expr) -> FuncCall:
|
|
83
|
+
return FuncCall("quantize_symmetric", (_e(v),))
|
|
84
|
+
|
|
85
|
+
def dequantize(v: ColumnProxy | Expr) -> FuncCall:
|
|
86
|
+
return FuncCall("dequantize", (_e(v),))
|
|
87
|
+
|
|
88
|
+
def dequantize_scaled(v: ColumnProxy | Expr, s: ColumnProxy | Expr | float) -> FuncCall:
|
|
89
|
+
return FuncCall("dequantize_scaled", (_e(v), _e(s)))
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# ── Int8 Distance (4) ────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
def euclidean_int8(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr) -> FuncCall:
|
|
95
|
+
return FuncCall("euclidean_int8", (_e(v1), _e(v2)))
|
|
96
|
+
|
|
97
|
+
def cosine_int8(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr) -> FuncCall:
|
|
98
|
+
return FuncCall("cosine_int8", (_e(v1), _e(v2)))
|
|
99
|
+
|
|
100
|
+
def dot_int8(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr) -> FuncCall:
|
|
101
|
+
return FuncCall("dot_int8", (_e(v1), _e(v2)))
|
|
102
|
+
|
|
103
|
+
def manhattan_int8(v1: ColumnProxy | Expr, v2: ColumnProxy | Expr) -> FuncCall:
|
|
104
|
+
return FuncCall("manhattan_int8", (_e(v1), _e(v2)))
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
# ── Temporal (14) ─────────────────────────────────────────────────────
|
|
108
|
+
|
|
109
|
+
def time_now() -> FuncCall:
|
|
110
|
+
return FuncCall("time_now", ())
|
|
111
|
+
|
|
112
|
+
def time_diff(t1: ColumnProxy | Expr, t2: ColumnProxy | Expr) -> FuncCall:
|
|
113
|
+
return FuncCall("time_diff", (_e(t1), _e(t2)))
|
|
114
|
+
|
|
115
|
+
def time_add(ts: ColumnProxy | Expr, dur: ColumnProxy | Expr | int) -> FuncCall:
|
|
116
|
+
return FuncCall("time_add", (_e(ts), _e(dur)))
|
|
117
|
+
|
|
118
|
+
def time_sub(ts: ColumnProxy | Expr, dur: ColumnProxy | Expr | int) -> FuncCall:
|
|
119
|
+
return FuncCall("time_sub", (_e(ts), _e(dur)))
|
|
120
|
+
|
|
121
|
+
def time_decay(
|
|
122
|
+
ts: ColumnProxy | Expr,
|
|
123
|
+
now: ColumnProxy | Expr,
|
|
124
|
+
half_life: ColumnProxy | Expr | int,
|
|
125
|
+
) -> FuncCall:
|
|
126
|
+
return FuncCall("time_decay", (_e(ts), _e(now), _e(half_life)))
|
|
127
|
+
|
|
128
|
+
def time_decay_linear(
|
|
129
|
+
ts: ColumnProxy | Expr,
|
|
130
|
+
now: ColumnProxy | Expr,
|
|
131
|
+
max_age: ColumnProxy | Expr | int,
|
|
132
|
+
) -> FuncCall:
|
|
133
|
+
return FuncCall("time_decay_linear", (_e(ts), _e(now), _e(max_age)))
|
|
134
|
+
|
|
135
|
+
def time_before(t1: ColumnProxy | Expr, t2: ColumnProxy | Expr) -> FuncCall:
|
|
136
|
+
return FuncCall("time_before", (_e(t1), _e(t2)))
|
|
137
|
+
|
|
138
|
+
def time_after(t1: ColumnProxy | Expr, t2: ColumnProxy | Expr) -> FuncCall:
|
|
139
|
+
return FuncCall("time_after", (_e(t1), _e(t2)))
|
|
140
|
+
|
|
141
|
+
def time_between(
|
|
142
|
+
ts: ColumnProxy | Expr,
|
|
143
|
+
start: ColumnProxy | Expr,
|
|
144
|
+
end: ColumnProxy | Expr,
|
|
145
|
+
) -> FuncCall:
|
|
146
|
+
return FuncCall("time_between", (_e(ts), _e(start), _e(end)))
|
|
147
|
+
|
|
148
|
+
def within_last(
|
|
149
|
+
ts: ColumnProxy | Expr,
|
|
150
|
+
now: ColumnProxy | Expr,
|
|
151
|
+
dur: ColumnProxy | Expr | int,
|
|
152
|
+
) -> FuncCall:
|
|
153
|
+
return FuncCall("within_last", (_e(ts), _e(now), _e(dur)))
|
|
154
|
+
|
|
155
|
+
def intervals_overlap(
|
|
156
|
+
s1: ColumnProxy | Expr, e1: ColumnProxy | Expr,
|
|
157
|
+
s2: ColumnProxy | Expr, e2: ColumnProxy | Expr,
|
|
158
|
+
) -> FuncCall:
|
|
159
|
+
return FuncCall("intervals_overlap", (_e(s1), _e(e1), _e(s2), _e(e2)))
|
|
160
|
+
|
|
161
|
+
def interval_contains(
|
|
162
|
+
s1: ColumnProxy | Expr, e1: ColumnProxy | Expr,
|
|
163
|
+
s2: ColumnProxy | Expr, e2: ColumnProxy | Expr,
|
|
164
|
+
) -> FuncCall:
|
|
165
|
+
return FuncCall("interval_contains", (_e(s1), _e(e1), _e(s2), _e(e2)))
|
|
166
|
+
|
|
167
|
+
def interval_duration(
|
|
168
|
+
s: ColumnProxy | Expr, e: ColumnProxy | Expr,
|
|
169
|
+
) -> FuncCall:
|
|
170
|
+
return FuncCall("interval_duration", (_e(s), _e(e)))
|
|
171
|
+
|
|
172
|
+
def point_in_interval(
|
|
173
|
+
ts: ColumnProxy | Expr,
|
|
174
|
+
s: ColumnProxy | Expr,
|
|
175
|
+
e: ColumnProxy | Expr,
|
|
176
|
+
) -> FuncCall:
|
|
177
|
+
return FuncCall("point_in_interval", (_e(ts), _e(s), _e(e)))
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# ── Math (15) ─────────────────────────────────────────────────────────
|
|
181
|
+
|
|
182
|
+
def abs_(x: ColumnProxy | Expr) -> FuncCall:
|
|
183
|
+
return FuncCall("abs", (_e(x),))
|
|
184
|
+
|
|
185
|
+
def abs_int64(x: ColumnProxy | Expr) -> FuncCall:
|
|
186
|
+
return FuncCall("abs_int64", (_e(x),))
|
|
187
|
+
|
|
188
|
+
def abs_float64(x: ColumnProxy | Expr) -> FuncCall:
|
|
189
|
+
return FuncCall("abs_float64", (_e(x),))
|
|
190
|
+
|
|
191
|
+
def sqrt(x: ColumnProxy | Expr) -> FuncCall:
|
|
192
|
+
return FuncCall("sqrt", (_e(x),))
|
|
193
|
+
|
|
194
|
+
def pow_(base: ColumnProxy | Expr, exp: ColumnProxy | Expr | float) -> FuncCall:
|
|
195
|
+
return FuncCall("pow", (_e(base), _e(exp)))
|
|
196
|
+
|
|
197
|
+
def log(x: ColumnProxy | Expr) -> FuncCall:
|
|
198
|
+
return FuncCall("log", (_e(x),))
|
|
199
|
+
|
|
200
|
+
def exp(x: ColumnProxy | Expr) -> FuncCall:
|
|
201
|
+
return FuncCall("exp", (_e(x),))
|
|
202
|
+
|
|
203
|
+
def sin(x: ColumnProxy | Expr) -> FuncCall:
|
|
204
|
+
return FuncCall("sin", (_e(x),))
|
|
205
|
+
|
|
206
|
+
def cos(x: ColumnProxy | Expr) -> FuncCall:
|
|
207
|
+
return FuncCall("cos", (_e(x),))
|
|
208
|
+
|
|
209
|
+
def tan(x: ColumnProxy | Expr) -> FuncCall:
|
|
210
|
+
return FuncCall("tan", (_e(x),))
|
|
211
|
+
|
|
212
|
+
def floor(x: ColumnProxy | Expr) -> FuncCall:
|
|
213
|
+
return FuncCall("floor", (_e(x),))
|
|
214
|
+
|
|
215
|
+
def ceil(x: ColumnProxy | Expr) -> FuncCall:
|
|
216
|
+
return FuncCall("ceil", (_e(x),))
|
|
217
|
+
|
|
218
|
+
def sign(x: ColumnProxy | Expr) -> FuncCall:
|
|
219
|
+
return FuncCall("sign", (_e(x),))
|
|
220
|
+
|
|
221
|
+
def min_val(a: ColumnProxy | Expr, b: ColumnProxy | Expr) -> FuncCall:
|
|
222
|
+
return FuncCall("min_val", (_e(a), _e(b)))
|
|
223
|
+
|
|
224
|
+
def max_val(a: ColumnProxy | Expr, b: ColumnProxy | Expr) -> FuncCall:
|
|
225
|
+
return FuncCall("max_val", (_e(a), _e(b)))
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
# ── String (7) ────────────────────────────────────────────────────────
|
|
229
|
+
|
|
230
|
+
def len_(s: ColumnProxy | Expr) -> FuncCall:
|
|
231
|
+
return FuncCall("len", (_e(s),))
|
|
232
|
+
|
|
233
|
+
def upper(s: ColumnProxy | Expr) -> FuncCall:
|
|
234
|
+
return FuncCall("upper", (_e(s),))
|
|
235
|
+
|
|
236
|
+
def lower(s: ColumnProxy | Expr) -> FuncCall:
|
|
237
|
+
return FuncCall("lower", (_e(s),))
|
|
238
|
+
|
|
239
|
+
def trim(s: ColumnProxy | Expr) -> FuncCall:
|
|
240
|
+
return FuncCall("trim", (_e(s),))
|
|
241
|
+
|
|
242
|
+
def substr(
|
|
243
|
+
s: ColumnProxy | Expr,
|
|
244
|
+
start: ColumnProxy | Expr | int,
|
|
245
|
+
length: ColumnProxy | Expr | int,
|
|
246
|
+
) -> FuncCall:
|
|
247
|
+
return FuncCall("substr", (_e(s), _e(start), _e(length)))
|
|
248
|
+
|
|
249
|
+
def replace(
|
|
250
|
+
s: ColumnProxy | Expr,
|
|
251
|
+
find: ColumnProxy | Expr | str,
|
|
252
|
+
repl: ColumnProxy | Expr | str,
|
|
253
|
+
) -> FuncCall:
|
|
254
|
+
return FuncCall("replace", (_e(s), _e(find), _e(repl)))
|
|
255
|
+
|
|
256
|
+
def concat(*args: ColumnProxy | Expr | str) -> FuncCall:
|
|
257
|
+
return FuncCall("concat", tuple(_e(a) for a in args))
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
# ── Type Conversion (2) ──────────────────────────────────────────────
|
|
261
|
+
|
|
262
|
+
def to_float(x: ColumnProxy | Expr) -> FuncCall:
|
|
263
|
+
return FuncCall("to_float", (_e(x),))
|
|
264
|
+
|
|
265
|
+
def to_int(x: ColumnProxy | Expr) -> FuncCall:
|
|
266
|
+
return FuncCall("to_int", (_e(x),))
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
# ── HNSW Direct (1) ──────────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
def hnsw_nearest(
|
|
272
|
+
index_name: str,
|
|
273
|
+
query_vec: ColumnProxy | Expr | list,
|
|
274
|
+
k: int,
|
|
275
|
+
*,
|
|
276
|
+
ef_search: int | None = None,
|
|
277
|
+
) -> FuncCall:
|
|
278
|
+
"""Direct HNSW nearest-neighbor search.
|
|
279
|
+
|
|
280
|
+
Datalog: hnsw_nearest("idx", [0.1, 0.2], 10, Id, Dist)
|
|
281
|
+
"""
|
|
282
|
+
args: list[Expr] = [Literal(index_name), _e(query_vec), Literal(k)]
|
|
283
|
+
if ef_search is not None:
|
|
284
|
+
args.append(Literal(ef_search))
|
|
285
|
+
return FuncCall("hnsw_nearest", tuple(args))
|
inputlayer/index.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""HNSW index definition and compilation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from inputlayer.relation import Relation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class HnswIndex:
|
|
14
|
+
"""HNSW vector index configuration.
|
|
15
|
+
|
|
16
|
+
Compiles to::
|
|
17
|
+
|
|
18
|
+
.index create <name> on <relation>(<column>) type hnsw
|
|
19
|
+
metric <metric> m <m> ef_construction <ef_c> ef_search <ef_s>
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
name: str
|
|
23
|
+
relation: type[Relation]
|
|
24
|
+
column: str
|
|
25
|
+
metric: str = "cosine"
|
|
26
|
+
m: int = 16
|
|
27
|
+
ef_construction: int = 100
|
|
28
|
+
ef_search: int = 50
|
|
29
|
+
|
|
30
|
+
def to_datalog(self) -> str:
|
|
31
|
+
"""Compile this index definition to a Datalog meta command."""
|
|
32
|
+
from inputlayer.relation import Relation
|
|
33
|
+
|
|
34
|
+
rel_name = Relation._resolve_name(self.relation)
|
|
35
|
+
return (
|
|
36
|
+
f".index create {self.name} on {rel_name}({self.column}) "
|
|
37
|
+
f"type hnsw metric {self.metric} "
|
|
38
|
+
f"m {self.m} ef_construction {self.ef_construction} "
|
|
39
|
+
f"ef_search {self.ef_search}"
|
|
40
|
+
)
|