Merging upstream version 18.11.2.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
15b8b39545
commit
c37998973e
88 changed files with 52059 additions and 46960 deletions
|
@ -86,6 +86,7 @@ class Generator:
|
|||
exp.OnUpdateColumnConstraint: lambda self, e: f"ON UPDATE {self.sql(e, 'this')}",
|
||||
exp.PathColumnConstraint: lambda self, e: f"PATH {self.sql(e, 'this')}",
|
||||
exp.ReturnsProperty: lambda self, e: self.naked_property(e),
|
||||
exp.SampleProperty: lambda self, e: f"SAMPLE BY {self.sql(e, 'this')}",
|
||||
exp.SetProperty: lambda self, e: f"{'MULTI' if e.args.get('multi') else ''}SET",
|
||||
exp.SettingsProperty: lambda self, e: f"SETTINGS{self.seg('')}{(self.expressions(e))}",
|
||||
exp.SqlSecurityProperty: lambda self, e: f"SQL SECURITY {'DEFINER' if e.args.get('definer') else 'INVOKER'}",
|
||||
|
@ -204,6 +205,21 @@ class Generator:
|
|||
# Whether or not session variables / parameters are supported, e.g. @x in T-SQL
|
||||
SUPPORTS_PARAMETERS = True
|
||||
|
||||
# Whether or not to include the type of a computed column in the CREATE DDL
|
||||
COMPUTED_COLUMN_WITH_TYPE = True
|
||||
|
||||
# Whether or not CREATE TABLE .. COPY .. is supported. False means we'll generate CLONE instead of COPY
|
||||
SUPPORTS_TABLE_COPY = True
|
||||
|
||||
# Whether or not parentheses are required around the table sample's expression
|
||||
TABLESAMPLE_REQUIRES_PARENS = True
|
||||
|
||||
# Whether or not COLLATE is a function instead of a binary operator
|
||||
COLLATE_IS_FUNC = False
|
||||
|
||||
# Whether or not data types support additional specifiers like e.g. CHAR or BYTE (oracle)
|
||||
DATA_TYPE_SPECIFIERS_ALLOWED = False
|
||||
|
||||
TYPE_MAPPING = {
|
||||
exp.DataType.Type.NCHAR: "CHAR",
|
||||
exp.DataType.Type.NVARCHAR: "VARCHAR",
|
||||
|
@ -282,6 +298,7 @@ class Generator:
|
|||
exp.RowFormatProperty: exp.Properties.Location.POST_SCHEMA,
|
||||
exp.RowFormatDelimitedProperty: exp.Properties.Location.POST_SCHEMA,
|
||||
exp.RowFormatSerdeProperty: exp.Properties.Location.POST_SCHEMA,
|
||||
exp.SampleProperty: exp.Properties.Location.POST_SCHEMA,
|
||||
exp.SchemaCommentProperty: exp.Properties.Location.POST_SCHEMA,
|
||||
exp.SerdeProperties: exp.Properties.Location.POST_SCHEMA,
|
||||
exp.Set: exp.Properties.Location.POST_SCHEMA,
|
||||
|
@ -324,13 +341,12 @@ class Generator:
|
|||
exp.Paren,
|
||||
)
|
||||
|
||||
UNESCAPED_SEQUENCE_TABLE = None # type: ignore
|
||||
|
||||
SENTINEL_LINE_BREAK = "__SQLGLOT__LB__"
|
||||
|
||||
# Autofilled
|
||||
INVERSE_TIME_MAPPING: t.Dict[str, str] = {}
|
||||
INVERSE_TIME_TRIE: t.Dict = {}
|
||||
INVERSE_ESCAPE_SEQUENCES: t.Dict[str, str] = {}
|
||||
INDEX_OFFSET = 0
|
||||
UNNEST_COLUMN_ONLY = False
|
||||
ALIAS_POST_TABLESAMPLE = False
|
||||
|
@ -480,8 +496,7 @@ class Generator:
|
|||
if not comments or isinstance(expression, exp.Binary):
|
||||
return sql
|
||||
|
||||
sep = "\n" if self.pretty else " "
|
||||
comments_sql = sep.join(
|
||||
comments_sql = " ".join(
|
||||
f"/*{self.pad_comment(comment)}*/" for comment in comments if comment
|
||||
)
|
||||
|
||||
|
@ -649,6 +664,9 @@ class Generator:
|
|||
position = self.sql(expression, "position")
|
||||
position = f" {position}" if position else ""
|
||||
|
||||
if expression.find(exp.ComputedColumnConstraint) and not self.COMPUTED_COLUMN_WITH_TYPE:
|
||||
kind = ""
|
||||
|
||||
return f"{exists}{column}{kind}{constraints}{position}"
|
||||
|
||||
def columnconstraint_sql(self, expression: exp.ColumnConstraint) -> str:
|
||||
|
@ -750,9 +768,11 @@ class Generator:
|
|||
)
|
||||
|
||||
begin = " BEGIN" if expression.args.get("begin") else ""
|
||||
end = " END" if expression.args.get("end") else ""
|
||||
|
||||
expression_sql = self.sql(expression, "expression")
|
||||
if expression_sql:
|
||||
expression_sql = f"{begin}{self.sep()}{expression_sql}"
|
||||
expression_sql = f"{begin}{self.sep()}{expression_sql}{end}"
|
||||
|
||||
if self.CREATE_FUNCTION_RETURN_AS or not isinstance(expression.expression, exp.Return):
|
||||
if properties_locs.get(exp.Properties.Location.POST_ALIAS):
|
||||
|
@ -817,7 +837,8 @@ class Generator:
|
|||
def clone_sql(self, expression: exp.Clone) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
shallow = "SHALLOW " if expression.args.get("shallow") else ""
|
||||
this = f"{shallow}CLONE {this}"
|
||||
keyword = "COPY" if expression.args.get("copy") and self.SUPPORTS_TABLE_COPY else "CLONE"
|
||||
this = f"{shallow}{keyword} {this}"
|
||||
when = self.sql(expression, "when")
|
||||
|
||||
if when:
|
||||
|
@ -877,7 +898,7 @@ class Generator:
|
|||
def datatypeparam_sql(self, expression: exp.DataTypeParam) -> str:
|
||||
this = self.sql(expression, "this")
|
||||
specifier = self.sql(expression, "expression")
|
||||
specifier = f" {specifier}" if specifier else ""
|
||||
specifier = f" {specifier}" if specifier and self.DATA_TYPE_SPECIFIERS_ALLOWED else ""
|
||||
return f"{this}{specifier}"
|
||||
|
||||
def datatype_sql(self, expression: exp.DataType) -> str:
|
||||
|
@ -1329,8 +1350,13 @@ class Generator:
|
|||
pivots = f" {pivots}" if pivots else ""
|
||||
joins = self.expressions(expression, key="joins", sep="", skip_first=True)
|
||||
laterals = self.expressions(expression, key="laterals", sep="")
|
||||
file_format = self.sql(expression, "format")
|
||||
if file_format:
|
||||
pattern = self.sql(expression, "pattern")
|
||||
pattern = f", PATTERN => {pattern}" if pattern else ""
|
||||
file_format = f" (FILE_FORMAT => {file_format}{pattern})"
|
||||
|
||||
return f"{table}{version}{alias}{hints}{pivots}{joins}{laterals}"
|
||||
return f"{table}{version}{file_format}{alias}{hints}{pivots}{joins}{laterals}"
|
||||
|
||||
def tablesample_sql(
|
||||
self, expression: exp.TableSample, seed_prefix: str = "SEED", sep=" AS "
|
||||
|
@ -1343,6 +1369,7 @@ class Generator:
|
|||
else:
|
||||
this = self.sql(expression, "this")
|
||||
alias = ""
|
||||
|
||||
method = self.sql(expression, "method")
|
||||
method = f"{method.upper()} " if method and self.TABLESAMPLE_WITH_METHOD else ""
|
||||
numerator = self.sql(expression, "bucket_numerator")
|
||||
|
@ -1354,13 +1381,20 @@ class Generator:
|
|||
percent = f"{percent} PERCENT" if percent else ""
|
||||
rows = self.sql(expression, "rows")
|
||||
rows = f"{rows} ROWS" if rows else ""
|
||||
|
||||
size = self.sql(expression, "size")
|
||||
if size and self.TABLESAMPLE_SIZE_IS_PERCENT:
|
||||
size = f"{size} PERCENT"
|
||||
|
||||
seed = self.sql(expression, "seed")
|
||||
seed = f" {seed_prefix} ({seed})" if seed else ""
|
||||
kind = expression.args.get("kind", "TABLESAMPLE")
|
||||
return f"{this} {kind} {method}({bucket}{percent}{rows}{size}){seed}{alias}"
|
||||
|
||||
expr = f"{bucket}{percent}{rows}{size}"
|
||||
if self.TABLESAMPLE_REQUIRES_PARENS:
|
||||
expr = f"({expr})"
|
||||
|
||||
return f"{this} {kind} {method}{expr}{seed}{alias}"
|
||||
|
||||
def pivot_sql(self, expression: exp.Pivot) -> str:
|
||||
expressions = self.expressions(expression, flat=True)
|
||||
|
@ -1638,8 +1672,8 @@ class Generator:
|
|||
|
||||
def escape_str(self, text: str) -> str:
|
||||
text = text.replace(self.QUOTE_END, self._escaped_quote_end)
|
||||
if self.UNESCAPED_SEQUENCE_TABLE:
|
||||
text = text.translate(self.UNESCAPED_SEQUENCE_TABLE)
|
||||
if self.INVERSE_ESCAPE_SEQUENCES:
|
||||
text = "".join(self.INVERSE_ESCAPE_SEQUENCES.get(ch, ch) for ch in text)
|
||||
elif self.pretty:
|
||||
text = text.replace("\n", self.SENTINEL_LINE_BREAK)
|
||||
return text
|
||||
|
@ -2301,6 +2335,8 @@ class Generator:
|
|||
return f"CURRENT_DATE({zone})" if zone else "CURRENT_DATE"
|
||||
|
||||
def collate_sql(self, expression: exp.Collate) -> str:
|
||||
if self.COLLATE_IS_FUNC:
|
||||
return self.function_fallback_sql(expression)
|
||||
return self.binary(expression, "COLLATE")
|
||||
|
||||
def command_sql(self, expression: exp.Command) -> str:
|
||||
|
@ -2359,7 +2395,7 @@ class Generator:
|
|||
collate = f" COLLATE {collate}" if collate else ""
|
||||
using = self.sql(expression, "using")
|
||||
using = f" USING {using}" if using else ""
|
||||
return f"ALTER COLUMN {this} TYPE {dtype}{collate}{using}"
|
||||
return f"ALTER COLUMN {this} SET DATA TYPE {dtype}{collate}{using}"
|
||||
|
||||
default = self.sql(expression, "default")
|
||||
if default:
|
||||
|
@ -2396,7 +2432,7 @@ class Generator:
|
|||
elif isinstance(actions[0], exp.Delete):
|
||||
actions = self.expressions(expression, key="actions", flat=True)
|
||||
else:
|
||||
actions = self.expressions(expression, key="actions")
|
||||
actions = self.expressions(expression, key="actions", flat=True)
|
||||
|
||||
exists = " IF EXISTS" if expression.args.get("exists") else ""
|
||||
only = " ONLY" if expression.args.get("only") else ""
|
||||
|
@ -2593,7 +2629,7 @@ class Generator:
|
|||
self,
|
||||
expression: t.Optional[exp.Expression] = None,
|
||||
key: t.Optional[str] = None,
|
||||
sqls: t.Optional[t.List[str]] = None,
|
||||
sqls: t.Optional[t.Collection[str | exp.Expression]] = None,
|
||||
flat: bool = False,
|
||||
indent: bool = True,
|
||||
skip_first: bool = False,
|
||||
|
@ -2841,6 +2877,9 @@ class Generator:
|
|||
def columnprefix_sql(self, expression: exp.ColumnPrefix) -> str:
|
||||
return f"{self.sql(expression, 'this')}({self.sql(expression, 'expression')})"
|
||||
|
||||
def opclass_sql(self, expression: exp.Opclass) -> str:
|
||||
return f"{self.sql(expression, 'this')} {self.sql(expression, 'expression')}"
|
||||
|
||||
|
||||
def cached_generator(
|
||||
cache: t.Optional[t.Dict[int, str]] = None
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue