1
0
Fork 0

Adding upstream version 10.6.3.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 15:09:11 +01:00
parent fafa4a7b95
commit ab1b3ea4d6
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
48 changed files with 906 additions and 266 deletions

View file

@ -67,6 +67,7 @@ class Generator:
exp.VolatilityProperty: lambda self, e: e.name,
exp.WithJournalTableProperty: lambda self, e: f"WITH JOURNAL TABLE={self.sql(e, 'this')}",
exp.LogProperty: lambda self, e: f"{'NO ' if e.args.get('no') else ''}LOG",
exp.SqlSecurityProperty: lambda self, e: f"SQL SECURITY {'DEFINER' if e.args.get('definer') else 'INVOKER'}",
}
# Whether 'CREATE ... TRANSIENT ... TABLE' is allowed
@ -75,6 +76,9 @@ class Generator:
# Whether or not null ordering is supported in order by
NULL_ORDERING_SUPPORTED = True
# Whether or not locking reads (i.e. SELECT ... FOR UPDATE/SHARE) are supported
LOCKING_READS_SUPPORTED = False
# Always do union distinct or union all
EXPLICIT_UNION = False
@ -99,34 +103,42 @@ class Generator:
STRUCT_DELIMITER = ("<", ">")
BEFORE_PROPERTIES = {
exp.FallbackProperty,
exp.WithJournalTableProperty,
exp.LogProperty,
exp.JournalProperty,
exp.AfterJournalProperty,
exp.ChecksumProperty,
exp.FreespaceProperty,
exp.MergeBlockRatioProperty,
exp.DataBlocksizeProperty,
exp.BlockCompressionProperty,
exp.IsolatedLoadingProperty,
}
ROOT_PROPERTIES = {
exp.ReturnsProperty,
exp.LanguageProperty,
exp.DistStyleProperty,
exp.DistKeyProperty,
exp.SortKeyProperty,
exp.LikeProperty,
}
WITH_PROPERTIES = {
exp.Property,
exp.FileFormatProperty,
exp.PartitionedByProperty,
exp.TableFormatProperty,
PROPERTIES_LOCATION = {
exp.AfterJournalProperty: exp.Properties.Location.PRE_SCHEMA,
exp.AlgorithmProperty: exp.Properties.Location.POST_CREATE,
exp.AutoIncrementProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.BlockCompressionProperty: exp.Properties.Location.PRE_SCHEMA,
exp.CharacterSetProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.ChecksumProperty: exp.Properties.Location.PRE_SCHEMA,
exp.CollateProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.DataBlocksizeProperty: exp.Properties.Location.PRE_SCHEMA,
exp.DefinerProperty: exp.Properties.Location.POST_CREATE,
exp.DistKeyProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.DistStyleProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.EngineProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.ExecuteAsProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.FallbackProperty: exp.Properties.Location.PRE_SCHEMA,
exp.FileFormatProperty: exp.Properties.Location.POST_SCHEMA_WITH,
exp.FreespaceProperty: exp.Properties.Location.PRE_SCHEMA,
exp.IsolatedLoadingProperty: exp.Properties.Location.PRE_SCHEMA,
exp.JournalProperty: exp.Properties.Location.PRE_SCHEMA,
exp.LanguageProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.LikeProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.LocationProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.LogProperty: exp.Properties.Location.PRE_SCHEMA,
exp.MergeBlockRatioProperty: exp.Properties.Location.PRE_SCHEMA,
exp.PartitionedByProperty: exp.Properties.Location.POST_SCHEMA_WITH,
exp.Property: exp.Properties.Location.POST_SCHEMA_WITH,
exp.ReturnsProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.RowFormatDelimitedProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.RowFormatSerdeProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.SchemaCommentProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.SerdeProperties: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.SortKeyProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.SqlSecurityProperty: exp.Properties.Location.POST_CREATE,
exp.TableFormatProperty: exp.Properties.Location.POST_SCHEMA_WITH,
exp.VolatilityProperty: exp.Properties.Location.POST_SCHEMA_ROOT,
exp.WithJournalTableProperty: exp.Properties.Location.PRE_SCHEMA,
}
WITH_SEPARATED_COMMENTS = (exp.Select, exp.From, exp.Where, exp.Binary)
@ -284,10 +296,10 @@ class Generator:
)
return f"({self.sep('')}{this_sql}{self.seg(')', sep='')}"
def no_identify(self, func: t.Callable[[], str]) -> str:
def no_identify(self, func: t.Callable[..., str], *args, **kwargs) -> str:
original = self.identify
self.identify = False
result = func()
result = func(*args, **kwargs)
self.identify = original
return result
@ -455,19 +467,33 @@ class Generator:
def create_sql(self, expression: exp.Create) -> str:
kind = self.sql(expression, "kind").upper()
has_before_properties = expression.args.get("properties")
has_before_properties = (
has_before_properties.args.get("before") if has_before_properties else None
)
if kind == "TABLE" and has_before_properties:
properties = expression.args.get("properties")
properties_exp = expression.copy()
properties_locs = self.locate_properties(properties) if properties else {}
if properties_locs.get(exp.Properties.Location.POST_SCHEMA_ROOT) or properties_locs.get(
exp.Properties.Location.POST_SCHEMA_WITH
):
properties_exp.set(
"properties",
exp.Properties(
expressions=[
*properties_locs[exp.Properties.Location.POST_SCHEMA_ROOT],
*properties_locs[exp.Properties.Location.POST_SCHEMA_WITH],
]
),
)
if kind == "TABLE" and properties_locs.get(exp.Properties.Location.PRE_SCHEMA):
this_name = self.sql(expression.this, "this")
this_properties = self.sql(expression, "properties")
this_properties = self.properties(
exp.Properties(expressions=properties_locs[exp.Properties.Location.PRE_SCHEMA]),
wrapped=False,
)
this_schema = f"({self.expressions(expression.this)})"
this = f"{this_name}, {this_properties} {this_schema}"
properties = ""
properties_sql = ""
else:
this = self.sql(expression, "this")
properties = self.sql(expression, "properties")
properties_sql = self.sql(properties_exp, "properties")
begin = " BEGIN" if expression.args.get("begin") else ""
expression_sql = self.sql(expression, "expression")
expression_sql = f" AS{begin}{self.sep()}{expression_sql}" if expression_sql else ""
@ -514,11 +540,31 @@ class Generator:
if index.args.get("columns")
else ""
)
if index.args.get("primary") and properties_locs.get(
exp.Properties.Location.POST_INDEX
):
postindex_props_sql = self.properties(
exp.Properties(
expressions=properties_locs[exp.Properties.Location.POST_INDEX]
),
wrapped=False,
)
ind_columns = f"{ind_columns} {postindex_props_sql}"
indexes_sql.append(
f"{ind_unique}{ind_primary}{ind_amp} INDEX{ind_name}{ind_columns}"
)
index_sql = "".join(indexes_sql)
postcreate_props_sql = ""
if properties_locs.get(exp.Properties.Location.POST_CREATE):
postcreate_props_sql = self.properties(
exp.Properties(expressions=properties_locs[exp.Properties.Location.POST_CREATE]),
sep=" ",
prefix=" ",
wrapped=False,
)
modifiers = "".join(
(
replace,
@ -531,6 +577,7 @@ class Generator:
multiset,
global_temporary,
volatile,
postcreate_props_sql,
)
)
no_schema_binding = (
@ -539,7 +586,7 @@ class Generator:
post_expression_modifiers = "".join((data, statistics, no_primary_index))
expression_sql = f"CREATE{modifiers} {kind}{exists_sql} {this}{properties}{expression_sql}{post_expression_modifiers}{index_sql}{no_schema_binding}"
expression_sql = f"CREATE{modifiers} {kind}{exists_sql} {this}{properties_sql}{expression_sql}{post_expression_modifiers}{index_sql}{no_schema_binding}"
return self.prepend_ctes(expression, expression_sql)
def describe_sql(self, expression: exp.Describe) -> str:
@ -665,24 +712,19 @@ class Generator:
return f"PARTITION({self.expressions(expression)})"
def properties_sql(self, expression: exp.Properties) -> str:
before_properties = []
root_properties = []
with_properties = []
for p in expression.expressions:
p_class = p.__class__
if p_class in self.BEFORE_PROPERTIES:
before_properties.append(p)
elif p_class in self.WITH_PROPERTIES:
p_loc = self.PROPERTIES_LOCATION[p.__class__]
if p_loc == exp.Properties.Location.POST_SCHEMA_WITH:
with_properties.append(p)
elif p_class in self.ROOT_PROPERTIES:
elif p_loc == exp.Properties.Location.POST_SCHEMA_ROOT:
root_properties.append(p)
return (
self.properties(exp.Properties(expressions=before_properties), before=True)
+ self.root_properties(exp.Properties(expressions=root_properties))
+ self.with_properties(exp.Properties(expressions=with_properties))
)
return self.root_properties(
exp.Properties(expressions=root_properties)
) + self.with_properties(exp.Properties(expressions=with_properties))
def root_properties(self, properties: exp.Properties) -> str:
if properties.expressions:
@ -695,17 +737,41 @@ class Generator:
prefix: str = "",
sep: str = ", ",
suffix: str = "",
before: bool = False,
wrapped: bool = True,
) -> str:
if properties.expressions:
expressions = self.expressions(properties, sep=sep, indent=False)
expressions = expressions if before else self.wrap(expressions)
expressions = self.wrap(expressions) if wrapped else expressions
return f"{prefix}{' ' if prefix and prefix != ' ' else ''}{expressions}{suffix}"
return ""
def with_properties(self, properties: exp.Properties) -> str:
return self.properties(properties, prefix=self.seg("WITH"))
def locate_properties(
self, properties: exp.Properties
) -> t.Dict[exp.Properties.Location, list[exp.Property]]:
properties_locs: t.Dict[exp.Properties.Location, list[exp.Property]] = {
key: [] for key in exp.Properties.Location
}
for p in properties.expressions:
p_loc = self.PROPERTIES_LOCATION[p.__class__]
if p_loc == exp.Properties.Location.PRE_SCHEMA:
properties_locs[exp.Properties.Location.PRE_SCHEMA].append(p)
elif p_loc == exp.Properties.Location.POST_INDEX:
properties_locs[exp.Properties.Location.POST_INDEX].append(p)
elif p_loc == exp.Properties.Location.POST_SCHEMA_ROOT:
properties_locs[exp.Properties.Location.POST_SCHEMA_ROOT].append(p)
elif p_loc == exp.Properties.Location.POST_SCHEMA_WITH:
properties_locs[exp.Properties.Location.POST_SCHEMA_WITH].append(p)
elif p_loc == exp.Properties.Location.POST_CREATE:
properties_locs[exp.Properties.Location.POST_CREATE].append(p)
elif p_loc == exp.Properties.Location.UNSUPPORTED:
self.unsupported(f"Unsupported property {p.key}")
return properties_locs
def property_sql(self, expression: exp.Property) -> str:
property_cls = expression.__class__
if property_cls == exp.Property:
@ -713,7 +779,7 @@ class Generator:
property_name = exp.Properties.PROPERTY_TO_NAME.get(property_cls)
if not property_name:
self.unsupported(f"Unsupported property {property_name}")
self.unsupported(f"Unsupported property {expression.key}")
return f"{property_name}={self.sql(expression, 'this')}"
@ -975,7 +1041,7 @@ class Generator:
rollup = self.expressions(expression, key="rollup", indent=False)
rollup = f"{self.seg('ROLLUP')} {self.wrap(rollup)}" if rollup else ""
return f"{group_by}{grouping_sets}{cube}{rollup}"
return f"{group_by}{csv(grouping_sets, cube, rollup, sep=',')}"
def having_sql(self, expression: exp.Having) -> str:
this = self.indent(self.sql(expression, "this"))
@ -1015,7 +1081,7 @@ class Generator:
def lambda_sql(self, expression: exp.Lambda, arrow_sep: str = "->") -> str:
args = self.expressions(expression, flat=True)
args = f"({args})" if len(args.split(",")) > 1 else args
return self.no_identify(lambda: f"{args} {arrow_sep} {self.sql(expression, 'this')}")
return f"{args} {arrow_sep} {self.sql(expression, 'this')}"
def lateral_sql(self, expression: exp.Lateral) -> str:
this = self.sql(expression, "this")
@ -1043,6 +1109,14 @@ class Generator:
this = self.sql(expression, "this")
return f"{this}{self.seg('OFFSET')} {self.sql(expression, 'expression')}"
def lock_sql(self, expression: exp.Lock) -> str:
if self.LOCKING_READS_SUPPORTED:
lock_type = "UPDATE" if expression.args["update"] else "SHARE"
return self.seg(f"FOR {lock_type}")
self.unsupported("Locking reads using 'FOR UPDATE/SHARE' are not supported")
return ""
def literal_sql(self, expression: exp.Literal) -> str:
text = expression.this or ""
if expression.is_string:
@ -1163,6 +1237,7 @@ class Generator:
self.sql(expression, "order"),
self.sql(expression, "limit"),
self.sql(expression, "offset"),
self.sql(expression, "lock"),
sep="",
)
@ -1773,7 +1848,7 @@ class Generator:
def userdefinedfunction_sql(self, expression: exp.UserDefinedFunction) -> str:
this = self.sql(expression, "this")
expressions = self.no_identify(lambda: self.expressions(expression))
expressions = self.no_identify(self.expressions, expression)
expressions = (
self.wrap(expressions) if expression.args.get("wrapped") else f" {expressions}"
)