summaryrefslogtreecommitdiffstats
path: root/sqlglot/generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'sqlglot/generator.py')
-rw-r--r--sqlglot/generator.py102
1 files changed, 47 insertions, 55 deletions
diff --git a/sqlglot/generator.py b/sqlglot/generator.py
index 18ae42a..0a7a81f 100644
--- a/sqlglot/generator.py
+++ b/sqlglot/generator.py
@@ -64,15 +64,22 @@ class Generator:
"TS_OR_DS_ADD", e.this, e.expression, e.args.get("unit")
),
exp.VarMap: lambda self, e: self.func("MAP", e.args["keys"], e.args["values"]),
- exp.CharacterSetProperty: lambda self, e: f"{'DEFAULT ' if e.args['default'] else ''}CHARACTER SET={self.sql(e, 'this')}",
+ exp.CharacterSetProperty: lambda self, e: f"{'DEFAULT ' if e.args.get('default') else ''}CHARACTER SET={self.sql(e, 'this')}",
+ exp.ExecuteAsProperty: lambda self, e: self.naked_property(e),
+ exp.ExternalProperty: lambda self, e: "EXTERNAL",
exp.LanguageProperty: lambda self, e: self.naked_property(e),
exp.LocationProperty: lambda self, e: self.naked_property(e),
+ exp.LogProperty: lambda self, e: f"{'NO ' if e.args.get('no') else ''}LOG",
+ exp.MaterializedProperty: lambda self, e: "MATERIALIZED",
+ exp.NoPrimaryIndexProperty: lambda self, e: "NO PRIMARY INDEX",
+ exp.OnCommitProperty: lambda self, e: "ON COMMIT PRESERVE ROWS",
exp.ReturnsProperty: lambda self, e: self.naked_property(e),
- exp.ExecuteAsProperty: lambda self, e: self.naked_property(e),
+ exp.SetProperty: lambda self, e: f"{'MULTI' if e.args.get('multi') else ''}SET",
+ exp.SqlSecurityProperty: lambda self, e: f"SQL SECURITY {'DEFINER' if e.args.get('definer') else 'INVOKER'}",
+ exp.TemporaryProperty: lambda self, e: f"{'GLOBAL ' if e.args.get('global_') else ''}TEMPORARY",
+ exp.TransientProperty: lambda self, e: "TRANSIENT",
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'}",
exp.CaseSpecificColumnConstraint: lambda self, e: f"{'NOT ' if e.args.get('not_') else ''}CASESPECIFIC",
exp.CharacterSetColumnConstraint: lambda self, e: f"CHARACTER SET {self.sql(e, 'this')}",
exp.DateFormatColumnConstraint: lambda self, e: f"FORMAT {self.sql(e, 'this')}",
@@ -87,9 +94,6 @@ class Generator:
exp.InlineLengthColumnConstraint: lambda self, e: f"INLINE LENGTH {self.sql(e, 'this')}",
}
- # Whether 'CREATE ... TRANSIENT ... TABLE' is allowed
- CREATE_TRANSIENT = False
-
# Whether or not null ordering is supported in order by
NULL_ORDERING_SUPPORTED = True
@@ -112,6 +116,7 @@ class Generator:
exp.DataType.Type.LONGTEXT: "TEXT",
exp.DataType.Type.MEDIUMBLOB: "BLOB",
exp.DataType.Type.LONGBLOB: "BLOB",
+ exp.DataType.Type.INET: "INET",
}
STAR_MAPPING = {
@@ -140,6 +145,7 @@ class Generator:
exp.DistStyleProperty: exp.Properties.Location.POST_SCHEMA,
exp.EngineProperty: exp.Properties.Location.POST_SCHEMA,
exp.ExecuteAsProperty: exp.Properties.Location.POST_SCHEMA,
+ exp.ExternalProperty: exp.Properties.Location.POST_CREATE,
exp.FallbackProperty: exp.Properties.Location.POST_NAME,
exp.FileFormatProperty: exp.Properties.Location.POST_WITH,
exp.FreespaceProperty: exp.Properties.Location.POST_NAME,
@@ -150,7 +156,10 @@ class Generator:
exp.LocationProperty: exp.Properties.Location.POST_SCHEMA,
exp.LockingProperty: exp.Properties.Location.POST_ALIAS,
exp.LogProperty: exp.Properties.Location.POST_NAME,
+ exp.MaterializedProperty: exp.Properties.Location.POST_CREATE,
exp.MergeBlockRatioProperty: exp.Properties.Location.POST_NAME,
+ exp.NoPrimaryIndexProperty: exp.Properties.Location.POST_EXPRESSION,
+ exp.OnCommitProperty: exp.Properties.Location.POST_EXPRESSION,
exp.PartitionedByProperty: exp.Properties.Location.POST_WITH,
exp.Property: exp.Properties.Location.POST_WITH,
exp.ReturnsProperty: exp.Properties.Location.POST_SCHEMA,
@@ -158,10 +167,14 @@ class Generator:
exp.RowFormatSerdeProperty: exp.Properties.Location.POST_SCHEMA,
exp.SchemaCommentProperty: exp.Properties.Location.POST_SCHEMA,
exp.SerdeProperties: exp.Properties.Location.POST_SCHEMA,
+ exp.SetProperty: exp.Properties.Location.POST_CREATE,
exp.SortKeyProperty: exp.Properties.Location.POST_SCHEMA,
exp.SqlSecurityProperty: exp.Properties.Location.POST_CREATE,
exp.TableFormatProperty: exp.Properties.Location.POST_WITH,
+ exp.TemporaryProperty: exp.Properties.Location.POST_CREATE,
+ exp.TransientProperty: exp.Properties.Location.POST_CREATE,
exp.VolatilityProperty: exp.Properties.Location.POST_SCHEMA,
+ exp.WithDataProperty: exp.Properties.Location.POST_EXPRESSION,
exp.WithJournalTableProperty: exp.Properties.Location.POST_NAME,
}
@@ -537,34 +550,9 @@ class Generator:
else:
expression_sql = f" AS{expression_sql}"
- temporary = " TEMPORARY" if expression.args.get("temporary") else ""
- transient = (
- " TRANSIENT" if self.CREATE_TRANSIENT and expression.args.get("transient") else ""
- )
- external = " EXTERNAL" if expression.args.get("external") else ""
replace = " OR REPLACE" if expression.args.get("replace") else ""
- 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 ""
- 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 = ""
- elif data:
- data = " WITH DATA"
- else:
- data = " WITH NO DATA"
- statistics = expression.args.get("statistics")
- if statistics is None:
- statistics = ""
- elif statistics:
- statistics = " AND STATISTICS"
- else:
- statistics = " AND NO STATISTICS"
- no_primary_index = " NO PRIMARY INDEX" if expression.args.get("no_primary_index") else ""
+ exists_sql = " IF NOT EXISTS" if expression.args.get("exists") else ""
indexes = expression.args.get("indexes")
index_sql = ""
@@ -605,28 +593,24 @@ class Generator:
wrapped=False,
)
- modifiers = "".join(
- (
- replace,
- temporary,
- transient,
- external,
- unique,
- materialized,
- set_,
- multiset,
- global_temporary,
- volatile,
- postcreate_props_sql,
+ modifiers = "".join((replace, unique, postcreate_props_sql))
+
+ postexpression_props_sql = ""
+ if properties_locs.get(exp.Properties.Location.POST_EXPRESSION):
+ postexpression_props_sql = self.properties(
+ exp.Properties(
+ expressions=properties_locs[exp.Properties.Location.POST_EXPRESSION]
+ ),
+ sep=" ",
+ prefix=" ",
+ wrapped=False,
)
- )
+
no_schema_binding = (
" WITH NO SCHEMA BINDING" if expression.args.get("no_schema_binding") else ""
)
- post_expression_modifiers = "".join((data, statistics, no_primary_index))
-
- expression_sql = f"CREATE{modifiers} {kind}{exists_sql} {this}{properties_sql}{expression_sql}{post_expression_modifiers}{index_sql}{no_schema_binding}"
+ expression_sql = f"CREATE{modifiers} {kind}{exists_sql} {this}{properties_sql}{expression_sql}{postexpression_props_sql}{index_sql}{no_schema_binding}"
return self.prepend_ctes(expression, expression_sql)
def describe_sql(self, expression: exp.Describe) -> str:
@@ -810,6 +794,8 @@ class Generator:
properties_locs[exp.Properties.Location.POST_CREATE].append(p)
elif p_loc == exp.Properties.Location.POST_ALIAS:
properties_locs[exp.Properties.Location.POST_ALIAS].append(p)
+ elif p_loc == exp.Properties.Location.POST_EXPRESSION:
+ properties_locs[exp.Properties.Location.POST_EXPRESSION].append(p)
elif p_loc == exp.Properties.Location.UNSUPPORTED:
self.unsupported(f"Unsupported property {p.key}")
@@ -931,6 +917,14 @@ class Generator:
override = " OVERRIDE" if expression.args.get("override") else ""
return f"LOCKING {kind}{this} {for_or_in} {lock_type}{override}"
+ def withdataproperty_sql(self, expression: exp.WithDataProperty) -> str:
+ data_sql = f"WITH {'NO ' if expression.args.get('no') else ''}DATA"
+ statistics = expression.args.get("statistics")
+ statistics_sql = ""
+ if statistics is not None:
+ statistics_sql = f" AND {'NO ' if not statistics else ''}STATISTICS"
+ return f"{data_sql}{statistics_sql}"
+
def insert_sql(self, expression: exp.Insert) -> str:
overwrite = expression.args.get("overwrite")
@@ -1003,10 +997,6 @@ class Generator:
system_time = expression.args.get("system_time")
system_time = f" {self.sql(expression, 'system_time')}" if system_time else ""
- if alias and pivots:
- pivots = f"{pivots}{alias}"
- alias = ""
-
return f"{table}{system_time}{alias}{hints}{laterals}{joins}{pivots}"
def tablesample_sql(self, expression: exp.TableSample) -> str:
@@ -1034,11 +1024,13 @@ class Generator:
def pivot_sql(self, expression: exp.Pivot) -> str:
this = self.sql(expression, "this")
+ alias = self.sql(expression, "alias")
+ alias = f" AS {alias}" if alias else ""
unpivot = expression.args.get("unpivot")
direction = "UNPIVOT" if unpivot else "PIVOT"
expressions = self.expressions(expression, key="expressions")
field = self.sql(expression, "field")
- return f"{this} {direction}({expressions} FOR {field})"
+ return f"{this} {direction}({expressions} FOR {field}){alias}"
def tuple_sql(self, expression: exp.Tuple) -> str:
return f"({self.expressions(expression, flat=True)})"