1
0
Fork 0

Merging upstream version 25.5.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 21:41:14 +01:00
parent 298e7a8147
commit 029b9c2c73
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
136 changed files with 80990 additions and 72541 deletions

View file

@ -87,9 +87,11 @@ class Generator(metaclass=_Generator):
e: f"CLUSTERED ({self.expressions(e, 'this', indent=False)})",
exp.CollateColumnConstraint: lambda self, e: f"COLLATE {self.sql(e, 'this')}",
exp.CommentColumnConstraint: lambda self, e: f"COMMENT {self.sql(e, 'this')}",
exp.ConnectByRoot: lambda self, e: f"CONNECT_BY_ROOT {self.sql(e, 'this')}",
exp.CopyGrantsProperty: lambda *_: "COPY GRANTS",
exp.DateFormatColumnConstraint: lambda self, e: f"FORMAT {self.sql(e, 'this')}",
exp.DefaultColumnConstraint: lambda self, e: f"DEFAULT {self.sql(e, 'this')}",
exp.DynamicProperty: lambda *_: "DYNAMIC",
exp.EncodeColumnConstraint: lambda self, e: f"ENCODE {self.sql(e, 'this')}",
exp.EphemeralColumnConstraint: lambda self,
e: f"EPHEMERAL{(' ' + self.sql(e, 'this')) if e.this else ''}",
@ -131,6 +133,7 @@ class Generator(metaclass=_Generator):
"RETURNS NULL ON NULL INPUT" if e.args.get("null") else self.naked_property(e)
),
exp.SampleProperty: lambda self, e: f"SAMPLE BY {self.sql(e, 'this')}",
exp.SecureProperty: lambda *_: "SECURE",
exp.SetConfigProperty: lambda self, e: self.sql(e, "this"),
exp.SetProperty: lambda _, e: f"{'MULTI' if e.args.get('multi') else ''}SET",
exp.SettingsProperty: lambda self, e: f"SETTINGS{self.seg('')}{(self.expressions(e))}",
@ -143,7 +146,7 @@ class Generator(metaclass=_Generator):
exp.TemporaryProperty: lambda *_: "TEMPORARY",
exp.TagColumnConstraint: lambda self, e: f"TAG ({self.expressions(e, flat=True)})",
exp.TitleColumnConstraint: lambda self, e: f"TITLE {self.sql(e, 'this')}",
exp.Timestamp: lambda self, e: self.func("TIMESTAMP", e.this, e.expression),
exp.Timestamp: lambda self, e: self.func("TIMESTAMP", e.this, e.args.get("zone")),
exp.ToMap: lambda self, e: f"MAP {self.sql(e, 'this')}",
exp.ToTableProperty: lambda self, e: f"TO {self.sql(e.this)}",
exp.TransformModelProperty: lambda self, e: self.func("TRANSFORM", *e.expressions),
@ -154,6 +157,7 @@ class Generator(metaclass=_Generator):
exp.ViewAttributeProperty: lambda self, e: f"WITH {self.sql(e, 'this')}",
exp.VolatileProperty: lambda *_: "VOLATILE",
exp.WithJournalTableProperty: lambda self, e: f"WITH JOURNAL TABLE={self.sql(e, 'this')}",
exp.WithSchemaBindingProperty: lambda self, e: f"WITH SCHEMA {self.sql(e, 'this')}",
exp.WithOperator: lambda self, e: f"{self.sql(e, 'this')} WITH {self.sql(e, 'op')}",
}
@ -168,8 +172,8 @@ class Generator(metaclass=_Generator):
# Whether locking reads (i.e. SELECT ... FOR UPDATE/SHARE) are supported
LOCKING_READS_SUPPORTED = False
# Always do union distinct or union all
EXPLICIT_UNION = False
# Always do <set op> distinct or <set op> all
EXPLICIT_SET_OP = False
# Wrap derived values in parens, usually standard but spark doesn't support it
WRAP_DERIVED_VALUES = True
@ -339,10 +343,10 @@ class Generator(metaclass=_Generator):
# Whether the function TO_NUMBER is supported
SUPPORTS_TO_NUMBER = True
# Whether or not union modifiers apply to the outer union or select.
# Whether or not set op modifiers apply to the outer set op or select.
# SELECT * FROM x UNION SELECT * FROM y LIMIT 1
# True means limit 1 happens after the union, False means it it happens on y.
OUTER_UNION_MODIFIERS = True
# True means limit 1 happens after the set op, False means it it happens on y.
SET_OP_MODIFIERS = True
# Whether parameters from COPY statement are wrapped in parentheses
COPY_PARAMS_ARE_WRAPPED = True
@ -368,6 +372,12 @@ class Generator(metaclass=_Generator):
# The keywords to use when prefixing & separating WITH based properties
WITH_PROPERTIES_PREFIX = "WITH"
# Whether to quote the generated expression of exp.JsonPath
QUOTE_JSON_PATH = True
# The name to generate for the JSONPath expression. If `None`, only `this` will be generated
PARSE_JSON_NAME: t.Optional[str] = "PARSE_JSON"
TYPE_MAPPING = {
exp.DataType.Type.NCHAR: "CHAR",
exp.DataType.Type.NVARCHAR: "VARCHAR",
@ -430,6 +440,7 @@ class Generator(metaclass=_Generator):
exp.DefinerProperty: exp.Properties.Location.POST_CREATE,
exp.DictRange: exp.Properties.Location.POST_SCHEMA,
exp.DictProperty: exp.Properties.Location.POST_SCHEMA,
exp.DynamicProperty: exp.Properties.Location.POST_CREATE,
exp.DistKeyProperty: exp.Properties.Location.POST_SCHEMA,
exp.DistStyleProperty: exp.Properties.Location.POST_SCHEMA,
exp.EngineProperty: exp.Properties.Location.POST_SCHEMA,
@ -469,6 +480,7 @@ class Generator(metaclass=_Generator):
exp.RowFormatSerdeProperty: exp.Properties.Location.POST_SCHEMA,
exp.SampleProperty: exp.Properties.Location.POST_SCHEMA,
exp.SchemaCommentProperty: exp.Properties.Location.POST_SCHEMA,
exp.SecureProperty: exp.Properties.Location.POST_CREATE,
exp.SerdeProperties: exp.Properties.Location.POST_SCHEMA,
exp.Set: exp.Properties.Location.POST_SCHEMA,
exp.SettingsProperty: exp.Properties.Location.POST_SCHEMA,
@ -491,6 +503,7 @@ class Generator(metaclass=_Generator):
exp.VolatileProperty: exp.Properties.Location.POST_CREATE,
exp.WithDataProperty: exp.Properties.Location.POST_EXPRESSION,
exp.WithJournalTableProperty: exp.Properties.Location.POST_NAME,
exp.WithSchemaBindingProperty: exp.Properties.Location.POST_SCHEMA,
exp.WithSystemVersioningProperty: exp.Properties.Location.POST_SCHEMA,
}
@ -506,7 +519,7 @@ class Generator(metaclass=_Generator):
exp.Insert,
exp.Join,
exp.Select,
exp.Union,
exp.SetOperation,
exp.Update,
exp.Where,
exp.With,
@ -515,7 +528,7 @@ class Generator(metaclass=_Generator):
# Expressions that should not have their comments generated in maybe_comment
EXCLUDE_COMMENTS: t.Tuple[t.Type[exp.Expression], ...] = (
exp.Binary,
exp.Union,
exp.SetOperation,
)
# Expressions that can remain unwrapped when appearing in the context of an INTERVAL
@ -1298,8 +1311,10 @@ class Generator(metaclass=_Generator):
with_storage = f" WITH ({with_storage})" if with_storage else ""
tablespace = self.sql(expression, "tablespace")
tablespace = f" USING INDEX TABLESPACE {tablespace}" if tablespace else ""
on = self.sql(expression, "on")
on = f" ON {on}" if on else ""
return f"{using}{columns}{include}{with_storage}{tablespace}{partition_by}{where}"
return f"{using}{columns}{include}{with_storage}{tablespace}{partition_by}{where}{on}"
def index_sql(self, expression: exp.Index) -> str:
unique = "UNIQUE " if expression.args.get("unique") else ""
@ -1736,7 +1751,10 @@ class Generator(metaclass=_Generator):
if when:
table = f"{table} {when}"
return f"{only}{table}{partition}{version}{file_format}{alias}{hints}{pivots}{joins}{laterals}{ordinality}"
changes = self.sql(expression, "changes")
changes = f" {changes}" if changes else ""
return f"{only}{table}{changes}{partition}{version}{file_format}{alias}{hints}{pivots}{joins}{laterals}{ordinality}"
def tablesample_sql(
self,
@ -2393,8 +2411,8 @@ class Generator(metaclass=_Generator):
this = self.indent(self.sql(expression, "this"))
return f"{self.seg('QUALIFY')}{self.sep()}{this}"
def set_operations(self, expression: exp.Union) -> str:
if not self.OUTER_UNION_MODIFIERS:
def set_operations(self, expression: exp.SetOperation) -> str:
if not self.SET_OP_MODIFIERS:
limit = expression.args.get("limit")
order = expression.args.get("order")
@ -2413,7 +2431,7 @@ class Generator(metaclass=_Generator):
while stack:
node = stack.pop()
if isinstance(node, exp.Union):
if isinstance(node, exp.SetOperation):
stack.append(node.expression)
stack.append(
self.maybe_comment(
@ -2433,8 +2451,8 @@ class Generator(metaclass=_Generator):
def union_sql(self, expression: exp.Union) -> str:
return self.set_operations(expression)
def union_op(self, expression: exp.Union) -> str:
kind = " DISTINCT" if self.EXPLICIT_UNION else ""
def union_op(self, expression: exp.SetOperation) -> str:
kind = " DISTINCT" if self.EXPLICIT_SET_OP else ""
kind = kind if expression.args.get("distinct") else " ALL"
by_name = " BY NAME" if expression.args.get("by_name") else ""
return f"UNION{kind}{by_name}"
@ -2653,7 +2671,10 @@ class Generator(metaclass=_Generator):
def jsonpath_sql(self, expression: exp.JSONPath) -> str:
path = self.expressions(expression, sep="", flat=True).lstrip(".")
return f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}"
if self.QUOTE_JSON_PATH:
path = f"{self.dialect.QUOTE_START}{path}{self.dialect.QUOTE_END}"
return path
def json_path_part(self, expression: int | str | exp.JSONPathPart) -> str:
if isinstance(expression, exp.JSONPathPart):
@ -3969,3 +3990,56 @@ class Generator(metaclass=_Generator):
this = self.sql(expression, "this")
this = f"TABLE {this}"
return self.func("GAP_FILL", this, *[v for k, v in expression.args.items() if k != "this"])
def scope_resolution(self, rhs: str, scope_name: str) -> str:
return self.func("SCOPE_RESOLUTION", scope_name or None, rhs)
def scoperesolution_sql(self, expression: exp.ScopeResolution) -> str:
this = self.sql(expression, "this")
expr = expression.expression
if isinstance(expr, exp.Func):
# T-SQL's CLR functions are case sensitive
expr = f"{self.sql(expr, 'this')}({self.format_args(*expr.expressions)})"
else:
expr = self.sql(expression, "expression")
return self.scope_resolution(expr, this)
def parsejson_sql(self, expression: exp.ParseJSON) -> str:
if self.PARSE_JSON_NAME is None:
return self.sql(expression.this)
return self.func(self.PARSE_JSON_NAME, expression.this, expression.expression)
def length_sql(self, expression: exp.Length) -> str:
return self.func("LENGTH", expression.this)
def rand_sql(self, expression: exp.Rand) -> str:
lower = self.sql(expression, "lower")
upper = self.sql(expression, "upper")
if lower and upper:
return f"({upper} - {lower}) * {self.func('RAND', expression.this)} + {lower}"
return self.func("RAND", expression.this)
def strtodate_sql(self, expression: exp.StrToDate) -> str:
return self.func("STR_TO_DATE", expression.this, expression.args.get("format"))
def strtotime_sql(self, expression: exp.StrToTime) -> str:
return self.func(
"STR_TO_TIME",
expression.this,
expression.args.get("format"),
expression.args.get("zone"),
)
def changes_sql(self, expression: exp.Changes) -> str:
information = self.sql(expression, "information")
information = f"INFORMATION => {information}"
at_before = self.sql(expression, "at_before")
at_before = f"{self.seg('')}{at_before}" if at_before else ""
end = self.sql(expression, "end")
end = f"{self.seg('')}{end}" if end else ""
return f"CHANGES ({information}){at_before}{end}"