-
Notifications
You must be signed in to change notification settings - Fork 543
/
subqueries.py
76 lines (58 loc) · 1.79 KB
/
subqueries.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
from __future__ import annotations
from public import public
import ibis.expr.datashape as ds
import ibis.expr.datatypes as dt
import ibis.expr.rules as rlz
from ibis.common.annotations import attribute
from ibis.common.exceptions import IntegrityError
from ibis.expr.operations.core import Value
from ibis.expr.operations.relations import Relation # noqa: TCH001
@public
class Subquery(Value):
rel: Relation
@attribute
def relations(self):
return frozenset()
@public
class ExistsSubquery(Subquery):
dtype = dt.boolean
shape = ds.columnar
@public
class ScalarSubquery(Subquery):
shape = ds.scalar
def __init__(self, rel):
if len(rel.schema) != 1:
raise IntegrityError(
"Relation passed to ScalarSubquery() must have exactly one "
f"column, got {len(rel.schema)}"
)
super().__init__(rel=rel)
@attribute
def value(self):
(value,) = self.rel.values.values()
return value
@attribute
def dtype(self):
return self.value.dtype
@public
class InSubquery(Subquery):
needle: Value
dtype = dt.boolean
shape = rlz.shape_like("needle")
def __init__(self, rel, needle):
if len(rel.schema) != 1:
raise IntegrityError(
"Relation passed to InSubquery() must have exactly one "
f"column, got {len(rel.schema)}"
)
(value,) = rel.values.values()
if not rlz.comparable(value, needle):
raise IntegrityError(f"{needle!r} is not comparable to {value!r}")
super().__init__(rel=rel, needle=needle)
@attribute
def value(self):
(value,) = self.rel.values.values()
return value
@attribute
def relations(self):
return self.needle.relations