sqlglotc 30.18.0__tar.gz → 30.19.0__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.
- {sqlglotc-30.18.0/sqlglotc.egg-info → sqlglotc-30.19.0}/PKG-INFO +2 -2
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/aggregate.py +6 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/array.py +6 -1
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/core.py +4 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/json.py +4 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/query.py +20 -5
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/string.py +1 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generator.py +23 -14
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/clickhouse.py +10 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/databricks.py +1 -1
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/doris.py +15 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/duckdb.py +12 -12
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/fabric.py +5 -5
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/mysql.py +12 -2
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/python.py +10 -1
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/singlestore.py +11 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/spark.py +3 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/sqlite.py +52 -25
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/teradata.py +1 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/trino.py +41 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/tsql.py +61 -3
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/lineage.py +1 -1
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/annotate_types.py +5 -4
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/canonicalize_internal_names.py +4 -4
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/qualify_columns.py +57 -13
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/resolver.py +23 -7
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/scope.py +27 -21
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/simplify.py +73 -43
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parser.py +49 -36
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/bigquery.py +0 -6
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/hive.py +6 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/mysql.py +53 -7
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/redshift.py +2 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/snowflake.py +7 -2
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/sqlite.py +5 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/trino.py +0 -6
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/tsql.py +2 -2
- {sqlglotc-30.18.0 → sqlglotc-30.19.0/sqlglotc.egg-info}/PKG-INFO +2 -2
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglotc.egg-info/requires.txt +1 -1
- sqlglotc-30.19.0/sqlglotc.egg-info/scm_version.json +8 -0
- sqlglotc-30.18.0/sqlglotc.egg-info/scm_version.json +0 -8
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/MANIFEST.in +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/pyproject.toml +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/setup.cfg +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/setup.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/anonymize.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/errors.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/executor/table.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/builders.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/constraints.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/datatypes.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/ddl.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/dml.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/functions.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/math.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/properties.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/expressions/temporal.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/athena.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/bigquery.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/dax.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/dremio.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/drill.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/druid.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/dune.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/exasol.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/hive.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/materialize.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/oracle.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/postgres.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/presto.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/prql.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/redshift.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/risingwave.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/snowflake.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/solr.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/spark2.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/starrocks.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/generators/tableau.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/helper.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/qualify.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/optimizer/qualify_tables.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/athena.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/base.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/clickhouse.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/databricks.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/dax.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/doris.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/dremio.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/drill.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/druid.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/duckdb.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/dune.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/exasol.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/fabric.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/materialize.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/oracle.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/postgres.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/presto.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/prql.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/risingwave.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/singlestore.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/solr.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/spark.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/spark2.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/starrocks.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/tableau.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/parsers/teradata.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/schema.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/serde.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/time.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/tokenizer_core.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglot/trie.py +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglotc.egg-info/SOURCES.txt +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglotc.egg-info/scm_file_list.json +0 -0
- {sqlglotc-30.18.0 → sqlglotc-30.19.0}/sqlglotc.egg-info/top_level.txt +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlglotc
|
|
3
|
-
Version: 30.
|
|
3
|
+
Version: 30.19.0
|
|
4
4
|
Summary: mypyc-compiled extensions for sqlglot
|
|
5
5
|
Author-email: Toby Mao <toby.mao@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
7
7
|
Project-URL: Homepage, https://sqlglot.com/
|
|
8
8
|
Project-URL: Repository, https://github.com/tobymao/sqlglot
|
|
9
9
|
Requires-Python: >=3.10
|
|
10
|
-
Requires-Dist: sqlglot==30.
|
|
10
|
+
Requires-Dist: sqlglot==30.19.0
|
|
11
11
|
Provides-Extra: dev
|
|
12
12
|
Requires-Dist: setuptools>=61.0; extra == "dev"
|
|
13
13
|
Requires-Dist: setuptools_scm; extra == "dev"
|
|
@@ -5,6 +5,12 @@ from __future__ import annotations
|
|
|
5
5
|
from sqlglot.expressions.core import Expression, Func, AggFunc, Binary
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class Agg(Expression, AggFunc):
|
|
9
|
+
@property
|
|
10
|
+
def output_name(self) -> str:
|
|
11
|
+
return self.this.name
|
|
12
|
+
|
|
13
|
+
|
|
8
14
|
class AIAgg(Expression, AggFunc):
|
|
9
15
|
arg_types = {"this": True, "expression": True}
|
|
10
16
|
_sql_names = ["AI_AGG"]
|
|
@@ -240,10 +240,15 @@ class Explode(Expression, Func, UDTF):
|
|
|
240
240
|
is_var_len_args = True
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
class Inline(Expression, Func):
|
|
243
|
+
class Inline(Expression, Func, UDTF):
|
|
244
244
|
pass
|
|
245
245
|
|
|
246
246
|
|
|
247
|
+
class Stack(Expression, Func, UDTF):
|
|
248
|
+
arg_types = {"this": True, "expressions": True}
|
|
249
|
+
is_var_len_args = True
|
|
250
|
+
|
|
251
|
+
|
|
247
252
|
@trait
|
|
248
253
|
class ExplodeOuter(Expr):
|
|
249
254
|
pass
|
|
@@ -1828,6 +1828,10 @@ class Identifier(Expression):
|
|
|
1828
1828
|
class DynamicIdentifier(Expression, Func):
|
|
1829
1829
|
arg_types = {"this": True, "expressions": False}
|
|
1830
1830
|
|
|
1831
|
+
@property
|
|
1832
|
+
def name(self) -> str:
|
|
1833
|
+
return self.this.name if self.this else ""
|
|
1834
|
+
|
|
1831
1835
|
|
|
1832
1836
|
class Opclass(Expression):
|
|
1833
1837
|
arg_types = {"this": True, "expression": True}
|
|
@@ -240,6 +240,10 @@ class OpenJSON(Expression, Func):
|
|
|
240
240
|
arg_types = {"this": True, "path": False, "expressions": False}
|
|
241
241
|
|
|
242
242
|
|
|
243
|
+
class FromJson(Expression, Func):
|
|
244
|
+
arg_types = {"this": True, "expression": True, "options": False}
|
|
245
|
+
|
|
246
|
+
|
|
243
247
|
class ParseJSON(Expression, Func):
|
|
244
248
|
# BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
|
|
245
249
|
# Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
|
|
@@ -12,6 +12,7 @@ from sqlglot.expressions.core import (
|
|
|
12
12
|
Condition,
|
|
13
13
|
Distinct,
|
|
14
14
|
Dot,
|
|
15
|
+
DynamicIdentifier,
|
|
15
16
|
Expr,
|
|
16
17
|
Expression,
|
|
17
18
|
Func,
|
|
@@ -624,7 +625,6 @@ class Group(Expression):
|
|
|
624
625
|
arg_types = {
|
|
625
626
|
"expressions": False,
|
|
626
627
|
"grouping_sets": False,
|
|
627
|
-
"grouping_sets_as_group_by_element": False,
|
|
628
628
|
"cube": False,
|
|
629
629
|
"rollup": False,
|
|
630
630
|
"totals": False,
|
|
@@ -967,9 +967,10 @@ class Table(Expression, Selectable):
|
|
|
967
967
|
|
|
968
968
|
@property
|
|
969
969
|
def name(self) -> str:
|
|
970
|
-
|
|
970
|
+
this = self.this
|
|
971
|
+
if not this or (isinstance(this, Func) and not isinstance(this, DynamicIdentifier)):
|
|
971
972
|
return ""
|
|
972
|
-
return
|
|
973
|
+
return this.name
|
|
973
974
|
|
|
974
975
|
@property
|
|
975
976
|
def db(self) -> str:
|
|
@@ -1019,6 +1020,20 @@ class Table(Expression, Selectable):
|
|
|
1019
1020
|
return col
|
|
1020
1021
|
|
|
1021
1022
|
|
|
1023
|
+
def _is_star(expression: Expr) -> bool:
|
|
1024
|
+
stack = [expression]
|
|
1025
|
+
while stack:
|
|
1026
|
+
node = stack.pop()
|
|
1027
|
+
if isinstance(node, SetOperation):
|
|
1028
|
+
stack.append(node.this)
|
|
1029
|
+
stack.append(node.expression)
|
|
1030
|
+
elif isinstance(node, Subquery):
|
|
1031
|
+
stack.append(node.this)
|
|
1032
|
+
elif node.is_star:
|
|
1033
|
+
return True
|
|
1034
|
+
return False
|
|
1035
|
+
|
|
1036
|
+
|
|
1022
1037
|
class SetOperation(Expression, Query):
|
|
1023
1038
|
arg_types = {
|
|
1024
1039
|
"with_": False,
|
|
@@ -1061,7 +1076,7 @@ class SetOperation(Expression, Query):
|
|
|
1061
1076
|
|
|
1062
1077
|
@property
|
|
1063
1078
|
def is_star(self) -> bool:
|
|
1064
|
-
return self
|
|
1079
|
+
return _is_star(self)
|
|
1065
1080
|
|
|
1066
1081
|
@property
|
|
1067
1082
|
def selects(self) -> list[Expr]:
|
|
@@ -1719,7 +1734,7 @@ class Subquery(Expression, DerivedTable, Query):
|
|
|
1719
1734
|
|
|
1720
1735
|
@property
|
|
1721
1736
|
def is_star(self) -> bool:
|
|
1722
|
-
return self
|
|
1737
|
+
return _is_star(self)
|
|
1723
1738
|
|
|
1724
1739
|
@property
|
|
1725
1740
|
def output_name(self) -> str:
|
|
@@ -535,6 +535,12 @@ class Generator:
|
|
|
535
535
|
# True means limit 1 happens after the set op, False means it it happens on y.
|
|
536
536
|
SET_OP_MODIFIERS = True
|
|
537
537
|
|
|
538
|
+
# Whether a SELECT operand can have a branch-local LIMIT/TOP without parentheses.
|
|
539
|
+
SET_OP_LIMITS = False
|
|
540
|
+
|
|
541
|
+
# Whether set operation operands can be parenthesized without a SELECT wrapper.
|
|
542
|
+
SET_OP_PARENTHESIZED_OPERANDS = True
|
|
543
|
+
|
|
538
544
|
# Whether parameters from COPY statement are wrapped in parentheses
|
|
539
545
|
COPY_PARAMS_ARE_WRAPPED = True
|
|
540
546
|
|
|
@@ -1902,16 +1908,16 @@ class Generator:
|
|
|
1902
1908
|
if not self.SET_OP_MODIFIERS:
|
|
1903
1909
|
limit = expression.args.get("limit")
|
|
1904
1910
|
order = expression.args.get("order")
|
|
1911
|
+
offset = expression.args.get("offset")
|
|
1905
1912
|
|
|
1906
|
-
if limit or order:
|
|
1913
|
+
if limit or order or offset:
|
|
1907
1914
|
select = self._move_ctes_to_top_level(
|
|
1908
1915
|
exp.subquery(expression, "_l_0", copy=False).select("*", copy=False)
|
|
1909
1916
|
)
|
|
1910
1917
|
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
select = select.order_by(order.pop(), copy=False)
|
|
1918
|
+
for arg in ("limit", "order", "offset"):
|
|
1919
|
+
if value := expression.args.get(arg):
|
|
1920
|
+
select.set(arg, value.pop())
|
|
1915
1921
|
return self.sql(select)
|
|
1916
1922
|
|
|
1917
1923
|
sqls: list[str] = []
|
|
@@ -1929,6 +1935,14 @@ class Generator:
|
|
|
1929
1935
|
)
|
|
1930
1936
|
stack.append(node.this)
|
|
1931
1937
|
else:
|
|
1938
|
+
if (
|
|
1939
|
+
not self.SET_OP_LIMITS
|
|
1940
|
+
and isinstance(node, exp.Select)
|
|
1941
|
+
and node.args.get("limit")
|
|
1942
|
+
):
|
|
1943
|
+
node = node.subquery(copy=False)
|
|
1944
|
+
if not self.SET_OP_PARENTHESIZED_OPERANDS:
|
|
1945
|
+
node = exp.select("*").from_(node, copy=False)
|
|
1932
1946
|
sqls.append(self.sql(node))
|
|
1933
1947
|
|
|
1934
1948
|
this = self.sep().join(sqls)
|
|
@@ -2836,7 +2850,7 @@ class Generator:
|
|
|
2836
2850
|
):
|
|
2837
2851
|
add_separator = True
|
|
2838
2852
|
|
|
2839
|
-
if grouping_sets
|
|
2853
|
+
if grouping_sets:
|
|
2840
2854
|
if self.SUPPORTS_GROUPING_SETS_AS_SUFFIX:
|
|
2841
2855
|
add_separator = False
|
|
2842
2856
|
else:
|
|
@@ -3324,8 +3338,8 @@ class Generator:
|
|
|
3324
3338
|
self.sql(expression, "order"),
|
|
3325
3339
|
*self.offset_limit_modifiers(expression, isinstance(limit, exp.Fetch), limit),
|
|
3326
3340
|
*self.after_limit_modifiers(expression),
|
|
3327
|
-
self.options_modifier(expression),
|
|
3328
3341
|
self.sql(expression, "for_"),
|
|
3342
|
+
self.options_modifier(expression),
|
|
3329
3343
|
sep="",
|
|
3330
3344
|
)
|
|
3331
3345
|
|
|
@@ -3822,6 +3836,7 @@ class Generator:
|
|
|
3822
3836
|
path = self.expressions(expression, sep="", flat=True).lstrip(".")
|
|
3823
3837
|
|
|
3824
3838
|
if self.QUOTE_JSON_PATH:
|
|
3839
|
+
path = self.escape_str(path)
|
|
3825
3840
|
path = f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}"
|
|
3826
3841
|
|
|
3827
3842
|
return path
|
|
@@ -3840,7 +3855,7 @@ class Generator:
|
|
|
3840
3855
|
|
|
3841
3856
|
if self._quote_json_path_key_using_brackets and self.JSON_PATH_SINGLE_QUOTE_ESCAPE:
|
|
3842
3857
|
escaped = expression.replace("'", "\\'")
|
|
3843
|
-
escaped = f"
|
|
3858
|
+
escaped = f"'{escaped}'"
|
|
3844
3859
|
else:
|
|
3845
3860
|
escaped = expression.replace('"', '\\"')
|
|
3846
3861
|
escaped = f'"{escaped}"'
|
|
@@ -5401,12 +5416,6 @@ class Generator:
|
|
|
5401
5416
|
|
|
5402
5417
|
this = self.json_path_part(this)
|
|
5403
5418
|
|
|
5404
|
-
if quoted and self.QUOTE_JSON_PATH:
|
|
5405
|
-
# The whole path is rendered as a single quoted string literal, so the bracketed key
|
|
5406
|
-
# (which may itself contain backslash-escaped quotes, e.g. ["x \"y\"z"]) must be
|
|
5407
|
-
# escaped again for the outer string literal (-> ["x \\"y\\"z"]).
|
|
5408
|
-
this = self.escape_str(this)
|
|
5409
|
-
|
|
5410
5419
|
return (
|
|
5411
5420
|
f"[{this}]"
|
|
5412
5421
|
if self._quote_json_path_key_using_brackets and self.JSON_PATH_BRACKETED_KEY_SUPPORTED
|
|
@@ -186,6 +186,7 @@ class ClickHouseGenerator(generator.Generator):
|
|
|
186
186
|
TABLE_HINTS = False
|
|
187
187
|
GROUPINGS_SEP = ""
|
|
188
188
|
SET_OP_MODIFIERS = False
|
|
189
|
+
SET_OP_LIMITS = True
|
|
189
190
|
ARRAY_SIZE_NAME = "LENGTH"
|
|
190
191
|
WRAP_DERIVED_VALUES = False
|
|
191
192
|
AUTO_REFRESH_BARE_INTERVALS = True
|
|
@@ -445,6 +446,15 @@ class ClickHouseGenerator(generator.Generator):
|
|
|
445
446
|
|
|
446
447
|
return self.func("groupConcat", this)
|
|
447
448
|
|
|
449
|
+
def select_sql(self, expression: exp.Select) -> str:
|
|
450
|
+
limit = expression.args.get("limit")
|
|
451
|
+
if isinstance(limit, exp.Fetch) and not expression.args.get("order"):
|
|
452
|
+
count = limit.args.get("count")
|
|
453
|
+
expression.set(
|
|
454
|
+
"limit", exp.Limit(expression=count if count is not None else exp.Literal.number(1))
|
|
455
|
+
)
|
|
456
|
+
return super().select_sql(expression)
|
|
457
|
+
|
|
448
458
|
def offset_sql(self, expression: exp.Offset) -> str:
|
|
449
459
|
offset = super().offset_sql(expression)
|
|
450
460
|
|
|
@@ -97,10 +97,10 @@ class DatabricksGenerator(SparkGenerator):
|
|
|
97
97
|
return f"{self.sql(expression, 'this')} TIMESERIES"
|
|
98
98
|
|
|
99
99
|
def jsonpath_sql(self, expression: exp.JSONPath) -> str:
|
|
100
|
-
expression.set("escape", None)
|
|
101
100
|
path = super().jsonpath_sql(expression)
|
|
102
101
|
|
|
103
102
|
if isinstance(expression.parent, exp.JSONExtractScalar):
|
|
103
|
+
path = self.escape_str(path)
|
|
104
104
|
return f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}"
|
|
105
105
|
|
|
106
106
|
return path
|
|
@@ -104,6 +104,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
104
104
|
"alter",
|
|
105
105
|
"analyze",
|
|
106
106
|
"analyzed",
|
|
107
|
+
"analyzer",
|
|
107
108
|
"and",
|
|
108
109
|
"anti",
|
|
109
110
|
"append",
|
|
@@ -111,6 +112,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
111
112
|
"array_range",
|
|
112
113
|
"as",
|
|
113
114
|
"asc",
|
|
115
|
+
"asof",
|
|
114
116
|
"at",
|
|
115
117
|
"authors",
|
|
116
118
|
"auto",
|
|
@@ -132,6 +134,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
132
134
|
"bitxor",
|
|
133
135
|
"blob",
|
|
134
136
|
"boolean",
|
|
137
|
+
"both",
|
|
135
138
|
"brief",
|
|
136
139
|
"broker",
|
|
137
140
|
"buckets",
|
|
@@ -148,6 +151,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
148
151
|
"catalogs",
|
|
149
152
|
"chain",
|
|
150
153
|
"char",
|
|
154
|
+
"char_filter",
|
|
151
155
|
"character",
|
|
152
156
|
"charset",
|
|
153
157
|
"check",
|
|
@@ -227,6 +231,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
227
231
|
"drop",
|
|
228
232
|
"dropp",
|
|
229
233
|
"dual",
|
|
234
|
+
"dump",
|
|
230
235
|
"duplicate",
|
|
231
236
|
"dynamic",
|
|
232
237
|
"else",
|
|
@@ -329,8 +334,10 @@ class DorisGenerator(MySQLGenerator):
|
|
|
329
334
|
"largeint",
|
|
330
335
|
"last",
|
|
331
336
|
"lateral",
|
|
337
|
+
"layout",
|
|
332
338
|
"ldap",
|
|
333
339
|
"ldap_admin_password",
|
|
340
|
+
"leading",
|
|
334
341
|
"left",
|
|
335
342
|
"less",
|
|
336
343
|
"level",
|
|
@@ -352,6 +359,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
352
359
|
"match",
|
|
353
360
|
"match_all",
|
|
354
361
|
"match_any",
|
|
362
|
+
"match_condition",
|
|
355
363
|
"match_phrase",
|
|
356
364
|
"match_phrase_edge",
|
|
357
365
|
"match_phrase_prefix",
|
|
@@ -377,6 +385,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
377
385
|
"next",
|
|
378
386
|
"ngram_bf",
|
|
379
387
|
"no",
|
|
388
|
+
"no_use_mv",
|
|
380
389
|
"non_nullable",
|
|
381
390
|
"not",
|
|
382
391
|
"null",
|
|
@@ -410,6 +419,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
410
419
|
"permissive",
|
|
411
420
|
"physical",
|
|
412
421
|
"plan",
|
|
422
|
+
"play",
|
|
413
423
|
"process",
|
|
414
424
|
"plugin",
|
|
415
425
|
"plugins",
|
|
@@ -520,6 +530,9 @@ class DorisGenerator(MySQLGenerator):
|
|
|
520
530
|
"timestampdiff",
|
|
521
531
|
"tinyint",
|
|
522
532
|
"to",
|
|
533
|
+
"token_filter",
|
|
534
|
+
"tokenizer",
|
|
535
|
+
"trailing",
|
|
523
536
|
"transaction",
|
|
524
537
|
"trash",
|
|
525
538
|
"tree",
|
|
@@ -527,6 +540,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
527
540
|
"trim",
|
|
528
541
|
"true",
|
|
529
542
|
"truncate",
|
|
543
|
+
"try_cast",
|
|
530
544
|
"type",
|
|
531
545
|
"type_cast",
|
|
532
546
|
"types",
|
|
@@ -539,6 +553,7 @@ class DorisGenerator(MySQLGenerator):
|
|
|
539
553
|
"unsigned",
|
|
540
554
|
"update",
|
|
541
555
|
"use",
|
|
556
|
+
"use_mv",
|
|
542
557
|
"user",
|
|
543
558
|
"using",
|
|
544
559
|
"value",
|
|
@@ -651,17 +651,6 @@ def _struct_sql(self: DuckDBGenerator, expression: exp.Struct) -> str:
|
|
|
651
651
|
return f"ROW({csv_args})" if is_bq_inline_struct else f"{{{csv_args}}}"
|
|
652
652
|
|
|
653
653
|
|
|
654
|
-
def _datatype_sql(self: DuckDBGenerator, expression: exp.DataType) -> str:
|
|
655
|
-
if expression.is_type("array"):
|
|
656
|
-
return f"{self.expressions(expression, flat=True)}[{self.expressions(expression, key='values', flat=True)}]"
|
|
657
|
-
|
|
658
|
-
# Modifiers are not supported for TIME, [TIME | TIMESTAMP] WITH TIME ZONE
|
|
659
|
-
if expression.is_type(exp.DType.TIME, exp.DType.TIMETZ, exp.DType.TIMESTAMPTZ):
|
|
660
|
-
return expression.this.value
|
|
661
|
-
|
|
662
|
-
return self.datatype_sql(expression)
|
|
663
|
-
|
|
664
|
-
|
|
665
654
|
def _json_format_sql(self: DuckDBGenerator, expression: exp.JSONFormat) -> str:
|
|
666
655
|
sql = self.func("TO_JSON", expression.this, expression.args.get("options"))
|
|
667
656
|
return f"CAST({sql} AS TEXT)"
|
|
@@ -1665,7 +1654,6 @@ class DuckDBGenerator(generator.Generator):
|
|
|
1665
1654
|
if e.args.get("abbreviated")
|
|
1666
1655
|
else self.func("MONTHNAME", e.this)
|
|
1667
1656
|
),
|
|
1668
|
-
exp.DataType: _datatype_sql,
|
|
1669
1657
|
exp.Date: _date_sql,
|
|
1670
1658
|
exp.DateAdd: _date_delta_to_binary_interval_op(),
|
|
1671
1659
|
exp.DateFromParts: _date_from_parts_sql,
|
|
@@ -2308,6 +2296,18 @@ class DuckDBGenerator(generator.Generator):
|
|
|
2308
2296
|
_TRYCAST_DATE_SLASH_FMT = "%m/%d/%Y"
|
|
2309
2297
|
_TRYCAST_DATE_MON_FMT = "%d-%b-%Y"
|
|
2310
2298
|
|
|
2299
|
+
def datatype_sql(self, expression: exp.DataType) -> str:
|
|
2300
|
+
if expression.is_type(exp.DType.ARRAY):
|
|
2301
|
+
return f"{self.expressions(expression, flat=True)}[{self.expressions(expression, key='values', flat=True)}]"
|
|
2302
|
+
|
|
2303
|
+
# Modifiers are not supported for TIME, [TIME | TIMESTAMP] WITH TIME ZONE
|
|
2304
|
+
if expression.is_type(
|
|
2305
|
+
exp.DType.TIME, exp.DType.TIMETZ, exp.DType.TIMESTAMPTZ, exp.DType.TIMESTAMPLTZ
|
|
2306
|
+
):
|
|
2307
|
+
expression.set("expressions", None)
|
|
2308
|
+
|
|
2309
|
+
return super().datatype_sql(expression)
|
|
2310
|
+
|
|
2311
2311
|
def _array_bag_sql(self, condition: exp.Expr, arr1: exp.Expr, arr2: exp.Expr) -> str:
|
|
2312
2312
|
cond = exp.Paren(this=exp.replace_placeholders(condition, arr1=arr1, arr2=arr2))
|
|
2313
2313
|
return self.sql(
|
|
@@ -53,22 +53,22 @@ class FabricGenerator(TSQLGenerator):
|
|
|
53
53
|
**TSQLGenerator.TYPE_MAPPING,
|
|
54
54
|
exp.DType.DATETIME: "DATETIME2",
|
|
55
55
|
exp.DType.DECIMAL: "DECIMAL",
|
|
56
|
-
exp.DType.IMAGE: "VARBINARY",
|
|
56
|
+
exp.DType.IMAGE: "VARBINARY(MAX)",
|
|
57
57
|
exp.DType.INT: "INT",
|
|
58
|
-
exp.DType.JSON: "VARCHAR",
|
|
59
|
-
exp.DType.MONEY: "DECIMAL",
|
|
58
|
+
exp.DType.JSON: "VARCHAR(MAX)",
|
|
59
|
+
exp.DType.MONEY: "DECIMAL(19, 4)",
|
|
60
60
|
exp.DType.NCHAR: "CHAR",
|
|
61
61
|
exp.DType.NVARCHAR: "VARCHAR",
|
|
62
62
|
exp.DType.ROWVERSION: "ROWVERSION",
|
|
63
63
|
exp.DType.SMALLDATETIME: "DATETIME2",
|
|
64
|
-
exp.DType.SMALLMONEY: "DECIMAL",
|
|
64
|
+
exp.DType.SMALLMONEY: "DECIMAL(10, 4)",
|
|
65
65
|
exp.DType.TIMESTAMP: "DATETIME2",
|
|
66
66
|
exp.DType.TIMESTAMPNTZ: "DATETIME2",
|
|
67
67
|
exp.DType.TIMESTAMPTZ: "DATETIME2",
|
|
68
68
|
exp.DType.TINYINT: "SMALLINT",
|
|
69
69
|
exp.DType.UTINYINT: "SMALLINT",
|
|
70
70
|
exp.DType.UUID: "UNIQUEIDENTIFIER",
|
|
71
|
-
exp.DType.XML: "VARCHAR",
|
|
71
|
+
exp.DType.XML: "VARCHAR(MAX)",
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
TRANSFORMS = {
|
|
@@ -17,6 +17,7 @@ from sqlglot.dialects.dialect import (
|
|
|
17
17
|
no_pivot_sql,
|
|
18
18
|
no_tablesample_sql,
|
|
19
19
|
no_trycast_sql,
|
|
20
|
+
if_sql,
|
|
20
21
|
remove_ts_or_ds_to_date,
|
|
21
22
|
rename_func,
|
|
22
23
|
strposition_sql,
|
|
@@ -165,6 +166,8 @@ class MySQLGenerator(generator.Generator):
|
|
|
165
166
|
f"""GROUP_CONCAT({self.sql(e, "this")} SEPARATOR {self.sql(e, "separator") or "','"})"""
|
|
166
167
|
),
|
|
167
168
|
exp.ILike: no_ilike_sql,
|
|
169
|
+
# https://dev.mysql.com/doc/refman/9.7/en/flow-control-functions.html#function_if
|
|
170
|
+
exp.If: if_sql(false_value="NULL"),
|
|
168
171
|
exp.JSONExtractScalar: arrow_json_extract_sql,
|
|
169
172
|
exp.Length: length_or_char_length_sql,
|
|
170
173
|
exp.LogicalOr: rename_func("MAX"),
|
|
@@ -692,6 +695,15 @@ class MySQLGenerator(generator.Generator):
|
|
|
692
695
|
global_ = " GLOBAL" if expression.args.get("global_") else ""
|
|
693
696
|
|
|
694
697
|
target = self.sql(expression, "target")
|
|
698
|
+
|
|
699
|
+
# SHOW CREATE ... takes a possibly qualified name, it has no FROM clause
|
|
700
|
+
# https://dev.mysql.com/doc/refman/8.4/en/show-create-table.html
|
|
701
|
+
if expression.name.startswith("CREATE") and (db_id := self.sql(expression, "db")):
|
|
702
|
+
target = f"{db_id}.{target}"
|
|
703
|
+
db = ""
|
|
704
|
+
else:
|
|
705
|
+
db = self._prefixed_sql("FROM", expression, "db")
|
|
706
|
+
|
|
695
707
|
target = f" {target}" if target else ""
|
|
696
708
|
if expression.name in ("COLUMNS", "INDEX"):
|
|
697
709
|
target = f" FROM{target}"
|
|
@@ -702,8 +714,6 @@ class MySQLGenerator(generator.Generator):
|
|
|
702
714
|
elif expression.name == "PROJECTIONS":
|
|
703
715
|
target = f" ON TABLE{target}" if target else ""
|
|
704
716
|
|
|
705
|
-
db = self._prefixed_sql("FROM", expression, "db")
|
|
706
|
-
|
|
707
717
|
like = self._prefixed_sql("LIKE", expression, "like")
|
|
708
718
|
where = self.sql(expression, "where")
|
|
709
719
|
|
|
@@ -90,6 +90,15 @@ def _dpipe_sql(self: generator.Generator, e: exp.DPipe) -> str:
|
|
|
90
90
|
return self.func("SAFECONCAT" if e.args.get("safe") else "CONCAT", e.this, e.expression)
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
def _distinct_sql(self, e: exp.Distinct) -> str:
|
|
94
|
+
this = self.expressions(e, flat=True)
|
|
95
|
+
|
|
96
|
+
if len(e.expressions) == 1:
|
|
97
|
+
return f"set({this})"
|
|
98
|
+
|
|
99
|
+
return f"set(ZIPNOTNULL({this}))"
|
|
100
|
+
|
|
101
|
+
|
|
93
102
|
class PythonGenerator(generator.Generator):
|
|
94
103
|
TRANSFORMS = {
|
|
95
104
|
**{klass: _rename for klass in subclasses(exp.__name__, exp.Binary)},
|
|
@@ -105,7 +114,7 @@ class PythonGenerator(generator.Generator):
|
|
|
105
114
|
exp.Concat: lambda self, e: self.func(
|
|
106
115
|
"SAFECONCAT" if e.args.get("safe") else "CONCAT", *e.expressions
|
|
107
116
|
),
|
|
108
|
-
exp.Distinct:
|
|
117
|
+
exp.Distinct: _distinct_sql,
|
|
109
118
|
exp.Div: _div_sql,
|
|
110
119
|
exp.DPipe: _dpipe_sql,
|
|
111
120
|
exp.Extract: lambda self, e: f"EXTRACT('{e.name.lower()}', {self.sql(e, 'expression')})",
|
|
@@ -1454,6 +1454,17 @@ class SingleStoreGenerator(MySQLGenerator):
|
|
|
1454
1454
|
|
|
1455
1455
|
return self.sql(res)
|
|
1456
1456
|
|
|
1457
|
+
def withingroup_sql(self, expression: exp.WithinGroup) -> str:
|
|
1458
|
+
# SingleStore includes trailing NULLs in percentile calculations, so we sort them first
|
|
1459
|
+
if isinstance(expression.this, (exp.PercentileCont, exp.PercentileDisc)) and isinstance(
|
|
1460
|
+
expression.expression, exp.Order
|
|
1461
|
+
):
|
|
1462
|
+
expression = expression.copy()
|
|
1463
|
+
for ordered in expression.expression.expressions:
|
|
1464
|
+
ordered.set("nulls_first", True)
|
|
1465
|
+
|
|
1466
|
+
return super().withingroup_sql(expression)
|
|
1467
|
+
|
|
1457
1468
|
def all_sql(self, expression: exp.All) -> str:
|
|
1458
1469
|
self.unsupported("ALL subquery predicate is not supported in SingleStore")
|
|
1459
1470
|
return super().all_sql(expression)
|
|
@@ -128,6 +128,9 @@ class SparkGenerator(Spark2Generator):
|
|
|
128
128
|
exp.SafeMultiply: rename_func("TRY_MULTIPLY"),
|
|
129
129
|
exp.SafeSubtract: rename_func("TRY_SUBTRACT"),
|
|
130
130
|
exp.StartsWith: rename_func("STARTSWITH"),
|
|
131
|
+
exp.StabilityProperty: lambda self, e: (
|
|
132
|
+
"DETERMINISTIC" if e.name == "IMMUTABLE" else "NOT DETERMINISTIC"
|
|
133
|
+
),
|
|
131
134
|
exp.TimeAdd: date_delta_to_binary_interval_op(cast=False),
|
|
132
135
|
exp.TimeSub: date_delta_to_binary_interval_op(cast=False),
|
|
133
136
|
exp.TsOrDsAdd: _dateadd_sql,
|