ydb-sqlglot-plugin 0.2.0__tar.gz → 0.2.2__tar.gz
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.
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/PKG-INFO +1 -1
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/pyproject.toml +1 -1
- ydb_sqlglot_plugin-0.2.2/ydb_sqlglot/version.py +1 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot/ydb.py +57 -48
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/PKG-INFO +1 -1
- ydb_sqlglot_plugin-0.2.0/ydb_sqlglot/version.py +0 -1
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/LICENSE +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/README.md +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/setup.cfg +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot/__init__.py +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/SOURCES.txt +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/dependency_links.txt +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/entry_points.txt +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/requires.txt +0 -0
- {ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.2.2"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import inspect as _inspect
|
|
1
2
|
import re
|
|
2
3
|
import typing as t
|
|
3
4
|
|
|
@@ -403,26 +404,6 @@ def _apply_subquery_alias_columns(expression: exp.Expression) -> None:
|
|
|
403
404
|
alias.set("columns", [])
|
|
404
405
|
|
|
405
406
|
|
|
406
|
-
def _has_implicit_cross_join(expression: exp.Expression) -> bool:
|
|
407
|
-
"""Return True if the expression tree contains an implicit cross join.
|
|
408
|
-
|
|
409
|
-
An implicit cross join arises from comma-separated FROM tables, e.g.
|
|
410
|
-
``FROM t1, t2``. In the sqlglot AST this appears as a ``Join`` node
|
|
411
|
-
with no ``kind``, no ``on`` clause, and no ``using`` clause.
|
|
412
|
-
YDB disables implicit cross joins by default; callers can prepend
|
|
413
|
-
``PRAGMA AnsiImplicitCrossJoin;`` when this returns True.
|
|
414
|
-
"""
|
|
415
|
-
for node in expression.walk():
|
|
416
|
-
if isinstance(node, exp.Join):
|
|
417
|
-
if (
|
|
418
|
-
not node.args.get("kind")
|
|
419
|
-
and not node.args.get("on")
|
|
420
|
-
and not node.args.get("using")
|
|
421
|
-
):
|
|
422
|
-
return True
|
|
423
|
-
return False
|
|
424
|
-
|
|
425
|
-
|
|
426
407
|
class FlattenBy(exp.Expression):
|
|
427
408
|
"""YDB-specific FLATTEN [LIST|DICT] BY clause on a table reference."""
|
|
428
409
|
arg_types = {"this": True, "expressions": True, "kind": False}
|
|
@@ -446,6 +427,13 @@ _YDB_GENERIC_TYPES = {
|
|
|
446
427
|
}
|
|
447
428
|
|
|
448
429
|
|
|
430
|
+
# sqlglot >= 30.0.0 changed Parser.expression() to take a pre-built instance instead of
|
|
431
|
+
# (cls, **kwargs). Detect once so the YDB parser override below can support both APIs.
|
|
432
|
+
_EXPRESSION_TAKES_INSTANCE = (
|
|
433
|
+
"instance" in _inspect.signature(parser.Parser.expression).parameters
|
|
434
|
+
)
|
|
435
|
+
|
|
436
|
+
|
|
449
437
|
def _reassemble_ctes(
|
|
450
438
|
statements: t.List[t.Optional[exp.Expression]],
|
|
451
439
|
) -> t.List[t.Optional[exp.Expression]]:
|
|
@@ -602,6 +590,38 @@ class YDB(Dialect):
|
|
|
602
590
|
statements = super().parse(raw_tokens, sql)
|
|
603
591
|
return _reassemble_ctes(statements)
|
|
604
592
|
|
|
593
|
+
def expression(self, exp_class_or_instance, token=None, comments=None, **kwargs):
|
|
594
|
+
"""Bridge sqlglot's two `Parser.expression()` calling conventions.
|
|
595
|
+
|
|
596
|
+
sqlglot < 30 expects ``expression(cls, **kwargs)`` and instantiates internally.
|
|
597
|
+
sqlglot >= 30 expects a pre-built ``expression(instance)`` and rejects kwargs.
|
|
598
|
+
Several call sites in this dialect (and a few in upstream code paths we exercise)
|
|
599
|
+
mix both styles, so normalise here before delegating.
|
|
600
|
+
"""
|
|
601
|
+
if _EXPRESSION_TAKES_INSTANCE:
|
|
602
|
+
if not isinstance(exp_class_or_instance, exp.Expression):
|
|
603
|
+
exp_class_or_instance = exp_class_or_instance(**kwargs)
|
|
604
|
+
return super().expression(
|
|
605
|
+
exp_class_or_instance, token=token, comments=comments
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
if isinstance(exp_class_or_instance, exp.Expression):
|
|
609
|
+
# Old super() would attempt instance(**kwargs) -> "object is not callable".
|
|
610
|
+
instance = exp_class_or_instance
|
|
611
|
+
if token is not None:
|
|
612
|
+
update_positions = getattr(instance, "update_positions", None)
|
|
613
|
+
if update_positions is not None:
|
|
614
|
+
update_positions(token)
|
|
615
|
+
if comments:
|
|
616
|
+
instance.add_comments(comments)
|
|
617
|
+
else:
|
|
618
|
+
self._add_comments(instance)
|
|
619
|
+
return self.validate_expression(instance)
|
|
620
|
+
|
|
621
|
+
return super().expression(
|
|
622
|
+
exp_class_or_instance, token=token, comments=comments, **kwargs
|
|
623
|
+
)
|
|
624
|
+
|
|
605
625
|
def _parse_dcolon(self) -> t.Optional[exp.Expression]:
|
|
606
626
|
return self._parse_function(anonymous=True) or self._parse_var(any_token=True)
|
|
607
627
|
|
|
@@ -779,7 +799,9 @@ class YDB(Dialect):
|
|
|
779
799
|
|
|
780
800
|
def _parse_lambda_body(self, params):
|
|
781
801
|
if (
|
|
782
|
-
self._curr
|
|
802
|
+
self._curr is None
|
|
803
|
+
or self._curr.token_type != TokenType.R_PAREN
|
|
804
|
+
or self._next is None
|
|
783
805
|
or self._next.token_type != TokenType.ARROW
|
|
784
806
|
):
|
|
785
807
|
return None
|
|
@@ -1384,12 +1406,6 @@ class YDB(Dialect):
|
|
|
1384
1406
|
else:
|
|
1385
1407
|
sql = self._generate_create_table(expression)
|
|
1386
1408
|
|
|
1387
|
-
# Prepend PRAGMA AnsiImplicitCrossJoin only when the query contains
|
|
1388
|
-
# implicit cross joins (FROM t1, t2 syntax). YDB disables them by
|
|
1389
|
-
# default; the pragma restores standard SQL semantics.
|
|
1390
|
-
if _has_implicit_cross_join(expression):
|
|
1391
|
-
sql = "PRAGMA AnsiImplicitCrossJoin;\n" + sql
|
|
1392
|
-
|
|
1393
1409
|
return sql
|
|
1394
1410
|
|
|
1395
1411
|
def unnest_subqueries(self, expression):
|
|
@@ -2180,15 +2196,15 @@ class YDB(Dialect):
|
|
|
2180
2196
|
# we move the WHERE expression from ON, using literals
|
|
2181
2197
|
def join_sql(self, expression: exp.Join) -> str:
|
|
2182
2198
|
on_condition = expression.args.get("on")
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
#
|
|
2186
|
-
# YDB requires
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
expression.set("kind",
|
|
2191
|
-
expression.set("
|
|
2199
|
+
using = expression.args.get("using")
|
|
2200
|
+
|
|
2201
|
+
# Any join with no ON/USING clause becomes an explicit CROSS JOIN.
|
|
2202
|
+
# YDB requires an ON clause for outer joins, and emitting CROSS JOIN
|
|
2203
|
+
# explicitly (instead of the comma-separated form) keeps the output
|
|
2204
|
+
# valid without any extra pragma.
|
|
2205
|
+
if not on_condition and not using:
|
|
2206
|
+
expression.set("kind", "CROSS")
|
|
2207
|
+
expression.set("side", None)
|
|
2192
2208
|
return super().join_sql(expression)
|
|
2193
2209
|
|
|
2194
2210
|
if on_condition:
|
|
@@ -2256,18 +2272,11 @@ class YDB(Dialect):
|
|
|
2256
2272
|
on_condition = exp.and_(on_condition, cond)
|
|
2257
2273
|
expression.set("on", on_condition)
|
|
2258
2274
|
else:
|
|
2259
|
-
# No valid equality conditions
|
|
2260
|
-
#
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
):
|
|
2265
|
-
# Convert to CROSS JOIN by removing kind and ON
|
|
2266
|
-
expression.set("kind", None)
|
|
2267
|
-
expression.set("on", None)
|
|
2268
|
-
expression.set("side", "CROSS")
|
|
2269
|
-
else:
|
|
2270
|
-
expression.set("on", None)
|
|
2275
|
+
# No valid equality conditions remain on the JOIN — fall back
|
|
2276
|
+
# to an explicit CROSS JOIN regardless of the original kind.
|
|
2277
|
+
expression.set("kind", "CROSS")
|
|
2278
|
+
expression.set("on", None)
|
|
2279
|
+
expression.set("side", None)
|
|
2271
2280
|
|
|
2272
2281
|
if conditions_to_move:
|
|
2273
2282
|
select_stmt = expression.find_ancestor(exp.Select)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "0.2.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/requires.txt
RENAMED
|
File without changes
|
{ydb_sqlglot_plugin-0.2.0 → ydb_sqlglot_plugin-0.2.2}/ydb_sqlglot_plugin.egg-info/top_level.txt
RENAMED
|
File without changes
|