Adding upstream version 10.6.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
26f20be569
commit
fafa4a7b95
36 changed files with 1007 additions and 270 deletions
|
@ -65,6 +65,8 @@ class Generator:
|
|||
exp.ReturnsProperty: lambda self, e: self.naked_property(e),
|
||||
exp.ExecuteAsProperty: lambda self, e: self.naked_property(e),
|
||||
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",
|
||||
}
|
||||
|
||||
# Whether 'CREATE ... TRANSIENT ... TABLE' is allowed
|
||||
|
@ -97,6 +99,20 @@ 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,
|
||||
|
@ -113,8 +129,6 @@ class Generator:
|
|||
exp.TableFormatProperty,
|
||||
}
|
||||
|
||||
WITH_SINGLE_ALTER_TABLE_ACTION = (exp.AlterColumn, exp.RenameTable, exp.AddConstraint)
|
||||
|
||||
WITH_SEPARATED_COMMENTS = (exp.Select, exp.From, exp.Where, exp.Binary)
|
||||
SENTINEL_LINE_BREAK = "__SQLGLOT__LB__"
|
||||
|
||||
|
@ -122,7 +136,6 @@ class Generator:
|
|||
"time_mapping",
|
||||
"time_trie",
|
||||
"pretty",
|
||||
"configured_pretty",
|
||||
"quote_start",
|
||||
"quote_end",
|
||||
"identifier_start",
|
||||
|
@ -177,7 +190,6 @@ class Generator:
|
|||
self.time_mapping = time_mapping or {}
|
||||
self.time_trie = time_trie
|
||||
self.pretty = pretty if pretty is not None else sqlglot.pretty
|
||||
self.configured_pretty = self.pretty
|
||||
self.quote_start = quote_start or "'"
|
||||
self.quote_end = quote_end or "'"
|
||||
self.identifier_start = identifier_start or '"'
|
||||
|
@ -442,8 +454,20 @@ class Generator:
|
|||
return "UNIQUE"
|
||||
|
||||
def create_sql(self, expression: exp.Create) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
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:
|
||||
this_name = self.sql(expression.this, "this")
|
||||
this_properties = self.sql(expression, "properties")
|
||||
this_schema = f"({self.expressions(expression.this)})"
|
||||
this = f"{this_name}, {this_properties} {this_schema}"
|
||||
properties = ""
|
||||
else:
|
||||
this = self.sql(expression, "this")
|
||||
properties = self.sql(expression, "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 ""
|
||||
|
@ -456,7 +480,10 @@ class Generator:
|
|||
exists_sql = " IF NOT EXISTS" if expression.args.get("exists") else ""
|
||||
unique = " UNIQUE" if expression.args.get("unique") else ""
|
||||
materialized = " MATERIALIZED" if expression.args.get("materialized") else ""
|
||||
properties = self.sql(expression, "properties")
|
||||
set_ = " SET" if expression.args.get("set") else ""
|
||||
multiset = " MULTISET" if expression.args.get("multiset") else ""
|
||||
global_temporary = " GLOBAL TEMPORARY" if expression.args.get("global_temporary") else ""
|
||||
volatile = " VOLATILE" if expression.args.get("volatile") else ""
|
||||
data = expression.args.get("data")
|
||||
if data is None:
|
||||
data = ""
|
||||
|
@ -475,7 +502,7 @@ class Generator:
|
|||
|
||||
indexes = expression.args.get("indexes")
|
||||
index_sql = ""
|
||||
if indexes is not None:
|
||||
if indexes:
|
||||
indexes_sql = []
|
||||
for index in indexes:
|
||||
ind_unique = " UNIQUE" if index.args.get("unique") else ""
|
||||
|
@ -500,6 +527,10 @@ class Generator:
|
|||
external,
|
||||
unique,
|
||||
materialized,
|
||||
set_,
|
||||
multiset,
|
||||
global_temporary,
|
||||
volatile,
|
||||
)
|
||||
)
|
||||
no_schema_binding = (
|
||||
|
@ -569,13 +600,14 @@ class Generator:
|
|||
|
||||
def delete_sql(self, expression: exp.Delete) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
this = f" FROM {this}" if this else ""
|
||||
using_sql = (
|
||||
f" USING {self.expressions(expression, 'using', sep=', USING ')}"
|
||||
if expression.args.get("using")
|
||||
else ""
|
||||
)
|
||||
where_sql = self.sql(expression, "where")
|
||||
sql = f"DELETE FROM {this}{using_sql}{where_sql}"
|
||||
sql = f"DELETE{this}{using_sql}{where_sql}"
|
||||
return self.prepend_ctes(expression, sql)
|
||||
|
||||
def drop_sql(self, expression: exp.Drop) -> str:
|
||||
|
@ -630,28 +662,27 @@ class Generator:
|
|||
return f"N{self.sql(expression, 'this')}"
|
||||
|
||||
def partition_sql(self, expression: exp.Partition) -> str:
|
||||
keys = csv(
|
||||
*[
|
||||
f"""{prop.name}='{prop.text("value")}'""" if prop.text("value") else prop.name
|
||||
for prop in expression.this
|
||||
]
|
||||
)
|
||||
return f"PARTITION({keys})"
|
||||
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.WITH_PROPERTIES:
|
||||
if p_class in self.BEFORE_PROPERTIES:
|
||||
before_properties.append(p)
|
||||
elif p_class in self.WITH_PROPERTIES:
|
||||
with_properties.append(p)
|
||||
elif p_class in self.ROOT_PROPERTIES:
|
||||
root_properties.append(p)
|
||||
|
||||
return self.root_properties(
|
||||
exp.Properties(expressions=root_properties)
|
||||
) + self.with_properties(exp.Properties(expressions=with_properties))
|
||||
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))
|
||||
)
|
||||
|
||||
def root_properties(self, properties: exp.Properties) -> str:
|
||||
if properties.expressions:
|
||||
|
@ -659,13 +690,17 @@ class Generator:
|
|||
return ""
|
||||
|
||||
def properties(
|
||||
self, properties: exp.Properties, prefix: str = "", sep: str = ", ", suffix: str = ""
|
||||
self,
|
||||
properties: exp.Properties,
|
||||
prefix: str = "",
|
||||
sep: str = ", ",
|
||||
suffix: str = "",
|
||||
before: bool = False,
|
||||
) -> str:
|
||||
if properties.expressions:
|
||||
expressions = self.expressions(properties, sep=sep, indent=False)
|
||||
return (
|
||||
f"{prefix}{' ' if prefix and prefix != ' ' else ''}{self.wrap(expressions)}{suffix}"
|
||||
)
|
||||
expressions = expressions if before else self.wrap(expressions)
|
||||
return f"{prefix}{' ' if prefix and prefix != ' ' else ''}{expressions}{suffix}"
|
||||
return ""
|
||||
|
||||
def with_properties(self, properties: exp.Properties) -> str:
|
||||
|
@ -687,6 +722,98 @@ class Generator:
|
|||
options = f" {options}" if options else ""
|
||||
return f"LIKE {self.sql(expression, 'this')}{options}"
|
||||
|
||||
def fallbackproperty_sql(self, expression: exp.FallbackProperty) -> str:
|
||||
no = "NO " if expression.args.get("no") else ""
|
||||
protection = " PROTECTION" if expression.args.get("protection") else ""
|
||||
return f"{no}FALLBACK{protection}"
|
||||
|
||||
def journalproperty_sql(self, expression: exp.JournalProperty) -> str:
|
||||
no = "NO " if expression.args.get("no") else ""
|
||||
dual = "DUAL " if expression.args.get("dual") else ""
|
||||
before = "BEFORE " if expression.args.get("before") else ""
|
||||
return f"{no}{dual}{before}JOURNAL"
|
||||
|
||||
def freespaceproperty_sql(self, expression: exp.FreespaceProperty) -> str:
|
||||
freespace = self.sql(expression, "this")
|
||||
percent = " PERCENT" if expression.args.get("percent") else ""
|
||||
return f"FREESPACE={freespace}{percent}"
|
||||
|
||||
def afterjournalproperty_sql(self, expression: exp.AfterJournalProperty) -> str:
|
||||
no = "NO " if expression.args.get("no") else ""
|
||||
dual = "DUAL " if expression.args.get("dual") else ""
|
||||
local = ""
|
||||
if expression.args.get("local") is not None:
|
||||
local = "LOCAL " if expression.args.get("local") else "NOT LOCAL "
|
||||
return f"{no}{dual}{local}AFTER JOURNAL"
|
||||
|
||||
def checksumproperty_sql(self, expression: exp.ChecksumProperty) -> str:
|
||||
if expression.args.get("default"):
|
||||
property = "DEFAULT"
|
||||
elif expression.args.get("on"):
|
||||
property = "ON"
|
||||
else:
|
||||
property = "OFF"
|
||||
return f"CHECKSUM={property}"
|
||||
|
||||
def mergeblockratioproperty_sql(self, expression: exp.MergeBlockRatioProperty) -> str:
|
||||
if expression.args.get("no"):
|
||||
return "NO MERGEBLOCKRATIO"
|
||||
if expression.args.get("default"):
|
||||
return "DEFAULT MERGEBLOCKRATIO"
|
||||
|
||||
percent = " PERCENT" if expression.args.get("percent") else ""
|
||||
return f"MERGEBLOCKRATIO={self.sql(expression, 'this')}{percent}"
|
||||
|
||||
def datablocksizeproperty_sql(self, expression: exp.DataBlocksizeProperty) -> str:
|
||||
default = expression.args.get("default")
|
||||
min = expression.args.get("min")
|
||||
if default is not None or min is not None:
|
||||
if default:
|
||||
property = "DEFAULT"
|
||||
elif min:
|
||||
property = "MINIMUM"
|
||||
else:
|
||||
property = "MAXIMUM"
|
||||
return f"{property} DATABLOCKSIZE"
|
||||
else:
|
||||
units = expression.args.get("units")
|
||||
units = f" {units}" if units else ""
|
||||
return f"DATABLOCKSIZE={self.sql(expression, 'size')}{units}"
|
||||
|
||||
def blockcompressionproperty_sql(self, expression: exp.BlockCompressionProperty) -> str:
|
||||
autotemp = expression.args.get("autotemp")
|
||||
always = expression.args.get("always")
|
||||
default = expression.args.get("default")
|
||||
manual = expression.args.get("manual")
|
||||
never = expression.args.get("never")
|
||||
|
||||
if autotemp is not None:
|
||||
property = f"AUTOTEMP({self.expressions(autotemp)})"
|
||||
elif always:
|
||||
property = "ALWAYS"
|
||||
elif default:
|
||||
property = "DEFAULT"
|
||||
elif manual:
|
||||
property = "MANUAL"
|
||||
elif never:
|
||||
property = "NEVER"
|
||||
return f"BLOCKCOMPRESSION={property}"
|
||||
|
||||
def isolatedloadingproperty_sql(self, expression: exp.IsolatedLoadingProperty) -> str:
|
||||
no = expression.args.get("no")
|
||||
no = " NO" if no else ""
|
||||
concurrent = expression.args.get("concurrent")
|
||||
concurrent = " CONCURRENT" if concurrent else ""
|
||||
|
||||
for_ = ""
|
||||
if expression.args.get("for_all"):
|
||||
for_ = " FOR ALL"
|
||||
elif expression.args.get("for_insert"):
|
||||
for_ = " FOR INSERT"
|
||||
elif expression.args.get("for_none"):
|
||||
for_ = " FOR NONE"
|
||||
return f"WITH{no}{concurrent} ISOLATED LOADING{for_}"
|
||||
|
||||
def insert_sql(self, expression: exp.Insert) -> str:
|
||||
overwrite = expression.args.get("overwrite")
|
||||
|
||||
|
@ -833,10 +960,21 @@ class Generator:
|
|||
grouping_sets = (
|
||||
f"{self.seg('GROUPING SETS')} {self.wrap(grouping_sets)}" if grouping_sets else ""
|
||||
)
|
||||
cube = self.expressions(expression, key="cube", indent=False)
|
||||
cube = f"{self.seg('CUBE')} {self.wrap(cube)}" if cube else ""
|
||||
rollup = self.expressions(expression, key="rollup", indent=False)
|
||||
rollup = f"{self.seg('ROLLUP')} {self.wrap(rollup)}" if rollup else ""
|
||||
|
||||
cube = expression.args.get("cube")
|
||||
if cube is True:
|
||||
cube = self.seg("WITH CUBE")
|
||||
else:
|
||||
cube = self.expressions(expression, key="cube", indent=False)
|
||||
cube = f"{self.seg('CUBE')} {self.wrap(cube)}" if cube else ""
|
||||
|
||||
rollup = expression.args.get("rollup")
|
||||
if rollup is True:
|
||||
rollup = self.seg("WITH ROLLUP")
|
||||
else:
|
||||
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}"
|
||||
|
||||
def having_sql(self, expression: exp.Having) -> str:
|
||||
|
@ -980,10 +1118,37 @@ class Generator:
|
|||
|
||||
return f"{self.sql(expression, 'this')}{sort_order}{nulls_sort_change}"
|
||||
|
||||
def matchrecognize_sql(self, expression: exp.MatchRecognize) -> str:
|
||||
partition = self.partition_by_sql(expression)
|
||||
order = self.sql(expression, "order")
|
||||
measures = self.sql(expression, "measures")
|
||||
measures = self.seg(f"MEASURES {measures}") if measures else ""
|
||||
rows = self.sql(expression, "rows")
|
||||
rows = self.seg(rows) if rows else ""
|
||||
after = self.sql(expression, "after")
|
||||
after = self.seg(after) if after else ""
|
||||
pattern = self.sql(expression, "pattern")
|
||||
pattern = self.seg(f"PATTERN ({pattern})") if pattern else ""
|
||||
define = self.sql(expression, "define")
|
||||
define = self.seg(f"DEFINE {define}") if define else ""
|
||||
body = "".join(
|
||||
(
|
||||
partition,
|
||||
order,
|
||||
measures,
|
||||
rows,
|
||||
after,
|
||||
pattern,
|
||||
define,
|
||||
)
|
||||
)
|
||||
return f"{self.seg('MATCH_RECOGNIZE')} {self.wrap(body)}"
|
||||
|
||||
def query_modifiers(self, expression: exp.Expression, *sqls: str) -> str:
|
||||
return csv(
|
||||
*sqls,
|
||||
*[self.sql(sql) for sql in expression.args.get("joins") or []],
|
||||
self.sql(expression, "match"),
|
||||
*[self.sql(sql) for sql in expression.args.get("laterals") or []],
|
||||
self.sql(expression, "where"),
|
||||
self.sql(expression, "group"),
|
||||
|
@ -1092,8 +1257,7 @@ class Generator:
|
|||
def window_sql(self, expression: exp.Window) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
|
||||
partition = self.expressions(expression, key="partition_by", flat=True)
|
||||
partition = f"PARTITION BY {partition}" if partition else ""
|
||||
partition = self.partition_by_sql(expression)
|
||||
|
||||
order = expression.args.get("order")
|
||||
order_sql = self.order_sql(order, flat=True) if order else ""
|
||||
|
@ -1113,6 +1277,10 @@ class Generator:
|
|||
|
||||
return f"{this} ({window_args.strip()})"
|
||||
|
||||
def partition_by_sql(self, expression: exp.Window | exp.MatchRecognize) -> str:
|
||||
partition = self.expressions(expression, key="partition_by", flat=True)
|
||||
return f"PARTITION BY {partition}" if partition else ""
|
||||
|
||||
def window_spec_sql(self, expression: exp.WindowSpec) -> str:
|
||||
kind = self.sql(expression, "kind")
|
||||
start = csv(self.sql(expression, "start"), self.sql(expression, "start_side"), sep=" ")
|
||||
|
@ -1386,16 +1554,19 @@ class Generator:
|
|||
actions = self.expressions(expression, "actions", prefix="ADD COLUMN ")
|
||||
elif isinstance(actions[0], exp.Schema):
|
||||
actions = self.expressions(expression, "actions", prefix="ADD COLUMNS ")
|
||||
elif isinstance(actions[0], exp.Drop):
|
||||
actions = self.expressions(expression, "actions")
|
||||
elif isinstance(actions[0], self.WITH_SINGLE_ALTER_TABLE_ACTION):
|
||||
actions = self.sql(actions[0])
|
||||
elif isinstance(actions[0], exp.Delete):
|
||||
actions = self.expressions(expression, "actions", flat=True)
|
||||
else:
|
||||
self.unsupported(f"Unsupported ALTER TABLE action {actions[0].__class__.__name__}")
|
||||
actions = self.expressions(expression, "actions")
|
||||
|
||||
exists = " IF EXISTS" if expression.args.get("exists") else ""
|
||||
return f"ALTER TABLE{exists} {self.sql(expression, 'this')} {actions}"
|
||||
|
||||
def droppartition_sql(self, expression: exp.DropPartition) -> str:
|
||||
expressions = self.expressions(expression)
|
||||
exists = " IF EXISTS " if expression.args.get("exists") else " "
|
||||
return f"DROP{exists}{expressions}"
|
||||
|
||||
def addconstraint_sql(self, expression: exp.AddConstraint) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
expression_ = self.sql(expression, "expression")
|
||||
|
@ -1447,6 +1618,9 @@ class Generator:
|
|||
def escape_sql(self, expression: exp.Escape) -> str:
|
||||
return self.binary(expression, "ESCAPE")
|
||||
|
||||
def glob_sql(self, expression: exp.Glob) -> str:
|
||||
return self.binary(expression, "GLOB")
|
||||
|
||||
def gt_sql(self, expression: exp.GT) -> str:
|
||||
return self.binary(expression, ">")
|
||||
|
||||
|
@ -1499,7 +1673,11 @@ class Generator:
|
|||
return f"TRY_CAST({self.sql(expression, 'this')} AS {self.sql(expression, 'to')})"
|
||||
|
||||
def use_sql(self, expression: exp.Use) -> str:
|
||||
return f"USE {self.sql(expression, 'this')}"
|
||||
kind = self.sql(expression, "kind")
|
||||
kind = f" {kind}" if kind else ""
|
||||
this = self.sql(expression, "this")
|
||||
this = f" {this}" if this else ""
|
||||
return f"USE{kind}{this}"
|
||||
|
||||
def binary(self, expression: exp.Binary, op: str) -> str:
|
||||
return f"{self.sql(expression, 'this')} {op} {self.sql(expression, 'expression')}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue