Merging upstream version 25.5.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
298e7a8147
commit
029b9c2c73
136 changed files with 80990 additions and 72541 deletions
|
@ -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}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue