sqlspec 0.22.0__py3-none-any.whl → 0.23.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.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- sqlspec/_sql.py +36 -0
- sqlspec/builder/mixins/_join_operations.py +205 -85
- {sqlspec-0.22.0.dist-info → sqlspec-0.23.0.dist-info}/METADATA +1 -1
- {sqlspec-0.22.0.dist-info → sqlspec-0.23.0.dist-info}/RECORD +8 -8
- {sqlspec-0.22.0.dist-info → sqlspec-0.23.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.22.0.dist-info → sqlspec-0.23.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.22.0.dist-info → sqlspec-0.23.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.22.0.dist-info → sqlspec-0.23.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/_sql.py
CHANGED
|
@@ -628,6 +628,42 @@ class SQLFactory:
|
|
|
628
628
|
"""Create a CROSS JOIN builder."""
|
|
629
629
|
return JoinBuilder("cross join")
|
|
630
630
|
|
|
631
|
+
@property
|
|
632
|
+
def lateral_join_(self) -> "JoinBuilder":
|
|
633
|
+
"""Create a LATERAL JOIN builder.
|
|
634
|
+
|
|
635
|
+
Returns:
|
|
636
|
+
JoinBuilder configured for LATERAL JOIN
|
|
637
|
+
|
|
638
|
+
Example:
|
|
639
|
+
```python
|
|
640
|
+
query = (
|
|
641
|
+
sql.select("u.name", "arr.value")
|
|
642
|
+
.from_("users u")
|
|
643
|
+
.join(sql.lateral_join_("UNNEST(u.tags)").on("true"))
|
|
644
|
+
)
|
|
645
|
+
```
|
|
646
|
+
"""
|
|
647
|
+
return JoinBuilder("lateral join", lateral=True)
|
|
648
|
+
|
|
649
|
+
@property
|
|
650
|
+
def left_lateral_join_(self) -> "JoinBuilder":
|
|
651
|
+
"""Create a LEFT LATERAL JOIN builder.
|
|
652
|
+
|
|
653
|
+
Returns:
|
|
654
|
+
JoinBuilder configured for LEFT LATERAL JOIN
|
|
655
|
+
"""
|
|
656
|
+
return JoinBuilder("left join", lateral=True)
|
|
657
|
+
|
|
658
|
+
@property
|
|
659
|
+
def cross_lateral_join_(self) -> "JoinBuilder":
|
|
660
|
+
"""Create a CROSS LATERAL JOIN builder.
|
|
661
|
+
|
|
662
|
+
Returns:
|
|
663
|
+
JoinBuilder configured for CROSS LATERAL JOIN
|
|
664
|
+
"""
|
|
665
|
+
return JoinBuilder("cross join", lateral=True)
|
|
666
|
+
|
|
631
667
|
def __getattr__(self, name: str) -> "Column":
|
|
632
668
|
"""Dynamically create column references.
|
|
633
669
|
|
|
@@ -14,7 +14,6 @@ from sqlspec.exceptions import SQLBuilderError
|
|
|
14
14
|
from sqlspec.utils.type_guards import has_query_builder_parameters
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
|
-
from sqlspec.builder._column import ColumnExpression
|
|
18
17
|
from sqlspec.core.statement import SQL
|
|
19
18
|
from sqlspec.protocols import SQLBuilderProtocol
|
|
20
19
|
|
|
@@ -36,74 +35,133 @@ class JoinClauseMixin:
|
|
|
36
35
|
on: Optional[Union[str, exp.Expression, "SQL"]] = None,
|
|
37
36
|
alias: Optional[str] = None,
|
|
38
37
|
join_type: str = "INNER",
|
|
38
|
+
lateral: bool = False,
|
|
39
39
|
) -> Self:
|
|
40
40
|
builder = cast("SQLBuilderProtocol", self)
|
|
41
|
+
self._validate_join_context(builder)
|
|
42
|
+
|
|
43
|
+
# Handle Join expressions directly (from JoinBuilder.on() calls)
|
|
44
|
+
if isinstance(table, exp.Join):
|
|
45
|
+
if builder._expression is not None and isinstance(builder._expression, exp.Select):
|
|
46
|
+
builder._expression = builder._expression.join(table, copy=False)
|
|
47
|
+
return cast("Self", builder)
|
|
48
|
+
|
|
49
|
+
table_expr = self._parse_table_expression(table, alias, builder)
|
|
50
|
+
on_expr = self._parse_on_condition(on, builder)
|
|
51
|
+
join_expr = self._create_join_expression(table_expr, on_expr, join_type)
|
|
52
|
+
|
|
53
|
+
if lateral:
|
|
54
|
+
self._apply_lateral_modifier(join_expr)
|
|
55
|
+
|
|
56
|
+
if builder._expression is not None and isinstance(builder._expression, exp.Select):
|
|
57
|
+
builder._expression = builder._expression.join(join_expr, copy=False)
|
|
58
|
+
return cast("Self", builder)
|
|
59
|
+
|
|
60
|
+
def _validate_join_context(self, builder: "SQLBuilderProtocol") -> None:
|
|
61
|
+
"""Validate that the join can be applied to the current expression."""
|
|
41
62
|
if builder._expression is None:
|
|
42
63
|
builder._expression = exp.Select()
|
|
43
64
|
if not isinstance(builder._expression, exp.Select):
|
|
44
65
|
msg = "JOIN clause is only supported for SELECT statements."
|
|
45
66
|
raise SQLBuilderError(msg)
|
|
46
|
-
|
|
67
|
+
|
|
68
|
+
def _parse_table_expression(
|
|
69
|
+
self, table: Union[str, exp.Expression, Any], alias: Optional[str], builder: "SQLBuilderProtocol"
|
|
70
|
+
) -> exp.Expression:
|
|
71
|
+
"""Parse table parameter into a SQLGlot expression."""
|
|
47
72
|
if isinstance(table, str):
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
73
|
+
return parse_table_expression(table, alias)
|
|
74
|
+
if has_query_builder_parameters(table):
|
|
75
|
+
return self._handle_query_builder_table(table, alias, builder)
|
|
76
|
+
if isinstance(table, exp.Expression):
|
|
77
|
+
return table
|
|
78
|
+
return cast("exp.Expression", table)
|
|
79
|
+
|
|
80
|
+
def _handle_query_builder_table(
|
|
81
|
+
self, table: Any, alias: Optional[str], builder: "SQLBuilderProtocol"
|
|
82
|
+
) -> exp.Expression:
|
|
83
|
+
"""Handle table parameters that are query builders."""
|
|
84
|
+
if hasattr(table, "_expression") and getattr(table, "_expression", None) is not None:
|
|
85
|
+
table_expr_value = getattr(table, "_expression", None)
|
|
86
|
+
if table_expr_value is not None:
|
|
87
|
+
subquery_exp = exp.paren(table_expr_value)
|
|
57
88
|
else:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
subquery_exp = exp.paren(exp.Anonymous(this=""))
|
|
90
|
+
return exp.alias_(subquery_exp, alias) if alias else subquery_exp
|
|
91
|
+
subquery = table.build()
|
|
92
|
+
sql_str = subquery.sql if hasattr(subquery, "sql") and not callable(subquery.sql) else str(subquery)
|
|
93
|
+
subquery_exp = exp.paren(exp.maybe_parse(sql_str, dialect=getattr(builder, "dialect", None)))
|
|
94
|
+
return exp.alias_(subquery_exp, alias) if alias else subquery_exp
|
|
95
|
+
|
|
96
|
+
def _parse_on_condition(
|
|
97
|
+
self, on: Optional[Union[str, exp.Expression, "SQL"]], builder: "SQLBuilderProtocol"
|
|
98
|
+
) -> Optional[exp.Expression]:
|
|
99
|
+
"""Parse ON condition into a SQLGlot expression."""
|
|
100
|
+
if on is None:
|
|
101
|
+
return None
|
|
102
|
+
|
|
103
|
+
if isinstance(on, str):
|
|
104
|
+
return exp.condition(on)
|
|
105
|
+
if hasattr(on, "expression") and hasattr(on, "sql"):
|
|
106
|
+
return self._handle_sql_object_condition(on, builder)
|
|
107
|
+
if isinstance(on, exp.Expression):
|
|
108
|
+
return on
|
|
109
|
+
# Last resort - convert to string and parse
|
|
110
|
+
return exp.condition(str(on))
|
|
111
|
+
|
|
112
|
+
def _handle_sql_object_condition(self, on: Any, builder: "SQLBuilderProtocol") -> exp.Expression:
|
|
113
|
+
"""Handle SQL object conditions with parameter binding."""
|
|
114
|
+
expression = getattr(on, "expression", None)
|
|
115
|
+
if expression is not None and isinstance(expression, exp.Expression):
|
|
116
|
+
# Merge parameters from SQL object into builder
|
|
117
|
+
if hasattr(on, "parameters") and hasattr(builder, "add_parameter"):
|
|
118
|
+
sql_parameters = getattr(on, "parameters", {})
|
|
119
|
+
for param_name, param_value in sql_parameters.items():
|
|
120
|
+
builder.add_parameter(param_value, name=param_name)
|
|
121
|
+
return cast("exp.Expression", expression)
|
|
122
|
+
# If expression is None, fall back to parsing the raw SQL
|
|
123
|
+
sql_text = getattr(on, "sql", "")
|
|
124
|
+
# Merge parameters even when parsing raw SQL
|
|
125
|
+
if hasattr(on, "parameters") and hasattr(builder, "add_parameter"):
|
|
126
|
+
sql_parameters = getattr(on, "parameters", {})
|
|
127
|
+
for param_name, param_value in sql_parameters.items():
|
|
128
|
+
builder.add_parameter(param_value, name=param_name)
|
|
129
|
+
parsed_expr = exp.maybe_parse(sql_text)
|
|
130
|
+
return parsed_expr if parsed_expr is not None else exp.condition(str(sql_text))
|
|
131
|
+
|
|
132
|
+
def _create_join_expression(
|
|
133
|
+
self, table_expr: exp.Expression, on_expr: Optional[exp.Expression], join_type: str
|
|
134
|
+
) -> exp.Join:
|
|
135
|
+
"""Create the appropriate JOIN expression based on join type."""
|
|
93
136
|
join_type_upper = join_type.upper()
|
|
94
137
|
if join_type_upper == "INNER":
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
138
|
+
return exp.Join(this=table_expr, on=on_expr)
|
|
139
|
+
if join_type_upper == "LEFT":
|
|
140
|
+
return exp.Join(this=table_expr, on=on_expr, side="LEFT")
|
|
141
|
+
if join_type_upper == "RIGHT":
|
|
142
|
+
return exp.Join(this=table_expr, on=on_expr, side="RIGHT")
|
|
143
|
+
if join_type_upper == "FULL":
|
|
144
|
+
return exp.Join(this=table_expr, on=on_expr, side="FULL", kind="OUTER")
|
|
145
|
+
if join_type_upper == "CROSS":
|
|
146
|
+
return exp.Join(this=table_expr, kind="CROSS")
|
|
147
|
+
msg = f"Unsupported join type: {join_type}"
|
|
148
|
+
raise SQLBuilderError(msg)
|
|
149
|
+
|
|
150
|
+
def _apply_lateral_modifier(self, join_expr: exp.Join) -> None:
|
|
151
|
+
"""Apply LATERAL modifier to the join expression."""
|
|
152
|
+
current_kind = join_expr.args.get("kind")
|
|
153
|
+
current_side = join_expr.args.get("side")
|
|
154
|
+
|
|
155
|
+
if current_kind == "CROSS":
|
|
156
|
+
join_expr.set("kind", "CROSS LATERAL")
|
|
157
|
+
elif current_kind == "OUTER" and current_side == "FULL":
|
|
158
|
+
join_expr.set("side", "FULL") # Keep side
|
|
159
|
+
join_expr.set("kind", "OUTER LATERAL")
|
|
160
|
+
elif current_side:
|
|
161
|
+
join_expr.set("kind", f"{current_side} LATERAL")
|
|
162
|
+
join_expr.set("side", None) # Clear side to avoid duplication
|
|
102
163
|
else:
|
|
103
|
-
|
|
104
|
-
raise SQLBuilderError(msg)
|
|
105
|
-
builder._expression = builder._expression.join(join_expr, copy=False)
|
|
106
|
-
return cast("Self", builder)
|
|
164
|
+
join_expr.set("kind", "LATERAL")
|
|
107
165
|
|
|
108
166
|
def inner_join(
|
|
109
167
|
self, table: Union[str, exp.Expression, Any], on: Union[str, exp.Expression, "SQL"], alias: Optional[str] = None
|
|
@@ -154,6 +212,63 @@ class JoinClauseMixin:
|
|
|
154
212
|
builder._expression = builder._expression.join(join_expr, copy=False)
|
|
155
213
|
return cast("Self", builder)
|
|
156
214
|
|
|
215
|
+
def lateral_join(
|
|
216
|
+
self,
|
|
217
|
+
table: Union[str, exp.Expression, Any],
|
|
218
|
+
on: Optional[Union[str, exp.Expression, "SQL"]] = None,
|
|
219
|
+
alias: Optional[str] = None,
|
|
220
|
+
) -> Self:
|
|
221
|
+
"""Create a LATERAL JOIN.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
table: Table, subquery, or table function to join
|
|
225
|
+
on: Optional join condition (for LATERAL JOINs with ON clause)
|
|
226
|
+
alias: Optional alias for the joined table/subquery
|
|
227
|
+
|
|
228
|
+
Returns:
|
|
229
|
+
Self for method chaining
|
|
230
|
+
|
|
231
|
+
Example:
|
|
232
|
+
```python
|
|
233
|
+
query = (
|
|
234
|
+
sql.select("u.name", "arr.value")
|
|
235
|
+
.from_("users u")
|
|
236
|
+
.lateral_join("UNNEST(u.tags)", alias="arr")
|
|
237
|
+
)
|
|
238
|
+
```
|
|
239
|
+
"""
|
|
240
|
+
return self.join(table, on=on, alias=alias, join_type="INNER", lateral=True)
|
|
241
|
+
|
|
242
|
+
def left_lateral_join(
|
|
243
|
+
self,
|
|
244
|
+
table: Union[str, exp.Expression, Any],
|
|
245
|
+
on: Optional[Union[str, exp.Expression, "SQL"]] = None,
|
|
246
|
+
alias: Optional[str] = None,
|
|
247
|
+
) -> Self:
|
|
248
|
+
"""Create a LEFT LATERAL JOIN.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
table: Table, subquery, or table function to join
|
|
252
|
+
on: Optional join condition
|
|
253
|
+
alias: Optional alias for the joined table/subquery
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
Self for method chaining
|
|
257
|
+
"""
|
|
258
|
+
return self.join(table, on=on, alias=alias, join_type="LEFT", lateral=True)
|
|
259
|
+
|
|
260
|
+
def cross_lateral_join(self, table: Union[str, exp.Expression, Any], alias: Optional[str] = None) -> Self:
|
|
261
|
+
"""Create a CROSS LATERAL JOIN (no ON condition).
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
table: Table, subquery, or table function to join
|
|
265
|
+
alias: Optional alias for the joined table/subquery
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
Self for method chaining
|
|
269
|
+
"""
|
|
270
|
+
return self.join(table, on=None, alias=alias, join_type="CROSS", lateral=True)
|
|
271
|
+
|
|
157
272
|
|
|
158
273
|
@trait
|
|
159
274
|
class JoinBuilder:
|
|
@@ -181,32 +296,19 @@ class JoinBuilder:
|
|
|
181
296
|
```
|
|
182
297
|
"""
|
|
183
298
|
|
|
184
|
-
def __init__(self, join_type: str) -> None:
|
|
299
|
+
def __init__(self, join_type: str, lateral: bool = False) -> None:
|
|
185
300
|
"""Initialize the join builder.
|
|
186
301
|
|
|
187
302
|
Args:
|
|
188
|
-
join_type: Type of join (inner, left, right, full, cross)
|
|
303
|
+
join_type: Type of join (inner, left, right, full, cross, lateral)
|
|
304
|
+
lateral: Whether this is a LATERAL join
|
|
189
305
|
"""
|
|
190
306
|
self._join_type = join_type.upper()
|
|
307
|
+
self._lateral = lateral
|
|
191
308
|
self._table: Optional[Union[str, exp.Expression]] = None
|
|
192
309
|
self._condition: Optional[exp.Expression] = None
|
|
193
310
|
self._alias: Optional[str] = None
|
|
194
311
|
|
|
195
|
-
def __eq__(self, other: object) -> "ColumnExpression": # type: ignore[override]
|
|
196
|
-
"""Equal to (==) - not typically used but needed for type consistency."""
|
|
197
|
-
from sqlspec.builder._column import ColumnExpression
|
|
198
|
-
|
|
199
|
-
# JoinBuilder doesn't have a direct expression, so this is a placeholder
|
|
200
|
-
# In practice, this shouldn't be called as joins are used differently
|
|
201
|
-
placeholder_expr = exp.Literal.string(f"join_{self._join_type.lower()}")
|
|
202
|
-
if other is None:
|
|
203
|
-
return ColumnExpression(exp.Is(this=placeholder_expr, expression=exp.Null()))
|
|
204
|
-
return ColumnExpression(exp.EQ(this=placeholder_expr, expression=exp.convert(other)))
|
|
205
|
-
|
|
206
|
-
def __hash__(self) -> int:
|
|
207
|
-
"""Make JoinBuilder hashable."""
|
|
208
|
-
return hash(id(self))
|
|
209
|
-
|
|
210
312
|
def __call__(self, table: Union[str, exp.Expression], alias: Optional[str] = None) -> Self:
|
|
211
313
|
"""Set the table to join.
|
|
212
314
|
|
|
@@ -254,15 +356,33 @@ class JoinBuilder:
|
|
|
254
356
|
table_expr = exp.alias_(table_expr, self._alias)
|
|
255
357
|
|
|
256
358
|
# Create the appropriate join type using same pattern as existing JoinClauseMixin
|
|
257
|
-
if self._join_type
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
359
|
+
if self._join_type in {"INNER JOIN", "INNER", "LATERAL JOIN"}:
|
|
360
|
+
join_expr = exp.Join(this=table_expr, on=condition_expr)
|
|
361
|
+
elif self._join_type in {"LEFT JOIN", "LEFT"}:
|
|
362
|
+
join_expr = exp.Join(this=table_expr, on=condition_expr, side="LEFT")
|
|
363
|
+
elif self._join_type in {"RIGHT JOIN", "RIGHT"}:
|
|
364
|
+
join_expr = exp.Join(this=table_expr, on=condition_expr, side="RIGHT")
|
|
365
|
+
elif self._join_type in {"FULL JOIN", "FULL"}:
|
|
366
|
+
join_expr = exp.Join(this=table_expr, on=condition_expr, side="FULL", kind="OUTER")
|
|
367
|
+
elif self._join_type in {"CROSS JOIN", "CROSS"}:
|
|
266
368
|
# CROSS JOIN doesn't use ON condition
|
|
267
|
-
|
|
268
|
-
|
|
369
|
+
join_expr = exp.Join(this=table_expr, kind="CROSS")
|
|
370
|
+
else:
|
|
371
|
+
join_expr = exp.Join(this=table_expr, on=condition_expr)
|
|
372
|
+
|
|
373
|
+
if self._lateral or self._join_type == "LATERAL JOIN":
|
|
374
|
+
current_kind = join_expr.args.get("kind")
|
|
375
|
+
current_side = join_expr.args.get("side")
|
|
376
|
+
|
|
377
|
+
if current_kind == "CROSS":
|
|
378
|
+
join_expr.set("kind", "CROSS LATERAL")
|
|
379
|
+
elif current_kind == "OUTER" and current_side == "FULL":
|
|
380
|
+
join_expr.set("side", "FULL") # Keep side
|
|
381
|
+
join_expr.set("kind", "OUTER LATERAL")
|
|
382
|
+
elif current_side:
|
|
383
|
+
join_expr.set("kind", f"{current_side} LATERAL")
|
|
384
|
+
join_expr.set("side", None) # Clear side to avoid duplication
|
|
385
|
+
else:
|
|
386
|
+
join_expr.set("kind", "LATERAL")
|
|
387
|
+
|
|
388
|
+
return join_expr
|
|
@@ -2,7 +2,7 @@ sqlspec/__init__.py,sha256=JkL9cp1h19tz1rCl-3WAep6kbZs8JLxNlb1SrQl8PWc,2114
|
|
|
2
2
|
sqlspec/__main__.py,sha256=lXBKZMOXA1uY735Rnsb-GS7aXy0nt22tYmd2X9FcxrY,253
|
|
3
3
|
sqlspec/__metadata__.py,sha256=IUw6MCTy1oeUJ1jAVYbuJLkOWbiAWorZ5W-E-SAD9N4,395
|
|
4
4
|
sqlspec/_serialization.py,sha256=6U5-smk2h2yl0i6am2prtOLJTdu4NJQdcLlSfSUMaUQ,2590
|
|
5
|
-
sqlspec/_sql.py,sha256=
|
|
5
|
+
sqlspec/_sql.py,sha256=QHx_awVF6yFxcNLcuAk19AnJe1FvX1FwqjxhJcUjXD4,46221
|
|
6
6
|
sqlspec/_typing.py,sha256=jv-7QHGLrJLfnP86bR-Xcmj3PDoddNZEKDz_vYRBiAU,22684
|
|
7
7
|
sqlspec/base.py,sha256=koDh1AecwCAkntSqSda6J_cpMOLonXiV6hh3GCCXf_s,25459
|
|
8
8
|
sqlspec/cli.py,sha256=Fe5Wbnrb_fkE9qm4gbBEXx3d0Q7VR-S-1t76ouAx2mg,20120
|
|
@@ -72,7 +72,7 @@ sqlspec/builder/mixins/__init__.py,sha256=YXhAzKmQbQtne5j26SKWY8PUxwosl0RhlhLoah
|
|
|
72
72
|
sqlspec/builder/mixins/_cte_and_set_ops.py,sha256=gANbAnL7ulkIMS1NG47nd_5laEsjwmEaROu-kTVbbF4,9152
|
|
73
73
|
sqlspec/builder/mixins/_delete_operations.py,sha256=LCzXoNtPUVgJ5KxhKoQj-METq51g5aDqoEmDmB66e08,1271
|
|
74
74
|
sqlspec/builder/mixins/_insert_operations.py,sha256=ipU1Hhue6MRFfbouDDXyONGC9-jmW7LYuo4HuMtioJs,10437
|
|
75
|
-
sqlspec/builder/mixins/_join_operations.py,sha256=
|
|
75
|
+
sqlspec/builder/mixins/_join_operations.py,sha256=1CN1E6TwtFng4ftKmIYN0MAJNZLkWISGB2UY1E1tivw,16036
|
|
76
76
|
sqlspec/builder/mixins/_merge_operations.py,sha256=v2JZbyOZyT5mS0cJo82ckjE9eR2LqoAS-YO2NJWK2a4,24297
|
|
77
77
|
sqlspec/builder/mixins/_order_limit_operations.py,sha256=i5QXZ_1aCzAhv3VG4Tp08kW8vYqEHU04TRoZPZgS2KA,5573
|
|
78
78
|
sqlspec/builder/mixins/_pivot_operations.py,sha256=s3b2zSOL0zEXEGXo1lBm5MuqXWl15qMww_krsmFqj3I,6163
|
|
@@ -131,9 +131,9 @@ sqlspec/utils/singleton.py,sha256=-j-s6LS0pP_wTEUYIyK2wSdoeIE_tn7O7B-j7_aODRQ,12
|
|
|
131
131
|
sqlspec/utils/sync_tools.py,sha256=ONdhmx1Dq0_c6ReRaTlXzz6dVmAwz6CybCvsTUAVu1g,8768
|
|
132
132
|
sqlspec/utils/text.py,sha256=ZqaXCVuUbdj_110pdTYjmAxfV3ZtR7J6EixuNazQLFY,3333
|
|
133
133
|
sqlspec/utils/type_guards.py,sha256=ktXwBQLLqOvk1W2wJcmk3bUprrsegs8nAZ879qDe0AU,32880
|
|
134
|
-
sqlspec-0.
|
|
135
|
-
sqlspec-0.
|
|
136
|
-
sqlspec-0.
|
|
137
|
-
sqlspec-0.
|
|
138
|
-
sqlspec-0.
|
|
139
|
-
sqlspec-0.
|
|
134
|
+
sqlspec-0.23.0.dist-info/METADATA,sha256=bSrPoVRmVNHSvsvNGO7j_Il8xpIlsHqz82B57bjjbRM,23548
|
|
135
|
+
sqlspec-0.23.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
136
|
+
sqlspec-0.23.0.dist-info/entry_points.txt,sha256=G-ZqY1Nuuw3Iys7nXw23f6ILenk_Lt47VdK2mhJCWHg,53
|
|
137
|
+
sqlspec-0.23.0.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
|
|
138
|
+
sqlspec-0.23.0.dist-info/licenses/NOTICE,sha256=Lyir8ozXWov7CyYS4huVaOCNrtgL17P-bNV-5daLntQ,1634
|
|
139
|
+
sqlspec-0.23.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|