diff options
Diffstat (limited to 'sqlglot/generator.py')
-rw-r--r-- | sqlglot/generator.py | 69 |
1 files changed, 58 insertions, 11 deletions
diff --git a/sqlglot/generator.py b/sqlglot/generator.py index 0c1578a..3935133 100644 --- a/sqlglot/generator.py +++ b/sqlglot/generator.py @@ -50,7 +50,7 @@ class Generator: The default is on the smaller end because the length only represents a segment and not the true line length. Default: 80 - comments: Whether or not to preserve comments in the ouput SQL code. + comments: Whether or not to preserve comments in the output SQL code. Default: True """ @@ -236,7 +236,10 @@ class Generator: return sql sep = "\n" if self.pretty else " " - comments = sep.join(f"/*{self.pad_comment(comment)}*/" for comment in comments) + comments = sep.join(f"/*{self.pad_comment(comment)}*/" for comment in comments if comment) + + if not comments: + return sql if isinstance(expression, self.WITH_SEPARATED_COMMENTS): return f"{comments}{self.sep()}{sql}" @@ -362,10 +365,10 @@ class Generator: kind = self.sql(expression, "kind") constraints = self.expressions(expression, key="constraints", sep=" ", flat=True) exists = "IF NOT EXISTS " if expression.args.get("exists") else "" + kind = f" {kind}" if kind else "" + constraints = f" {constraints}" if constraints else "" - if not constraints: - return f"{exists}{column} {kind}" - return f"{exists}{column} {kind} {constraints}" + return f"{exists}{column}{kind}{constraints}" def columnconstraint_sql(self, expression: exp.ColumnConstraint) -> str: this = self.sql(expression, "this") @@ -416,7 +419,7 @@ class Generator: this = self.sql(expression, "this") kind = self.sql(expression, "kind").upper() expression_sql = self.sql(expression, "expression") - expression_sql = f"AS{self.sep()}{expression_sql}" if expression_sql else "" + expression_sql = f" AS{self.sep()}{expression_sql}" if expression_sql else "" temporary = " TEMPORARY" if expression.args.get("temporary") else "" transient = ( " TRANSIENT" if self.CREATE_TRANSIENT and expression.args.get("transient") else "" @@ -427,6 +430,40 @@ class Generator: unique = " UNIQUE" if expression.args.get("unique") else "" materialized = " MATERIALIZED" if expression.args.get("materialized") else "" properties = self.sql(expression, "properties") + 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 "" + + indexes = expression.args.get("indexes") + index_sql = "" + if indexes is not None: + indexes_sql = [] + for index in indexes: + ind_unique = " UNIQUE" if index.args.get("unique") else "" + ind_primary = " PRIMARY" if index.args.get("primary") else "" + ind_amp = " AMP" if index.args.get("amp") else "" + ind_name = f" {index.name}" if index.name else "" + ind_columns = ( + f' ({self.expressions(index, key="columns", flat=True)})' + if index.args.get("columns") + else "" + ) + indexes_sql.append( + f"{ind_unique}{ind_primary}{ind_amp} INDEX{ind_name}{ind_columns}" + ) + index_sql = "".join(indexes_sql) modifiers = "".join( ( @@ -438,7 +475,10 @@ class Generator: materialized, ) ) - expression_sql = f"CREATE{modifiers} {kind}{exists_sql} {this}{properties} {expression_sql}" + + 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}" return self.prepend_ctes(expression, expression_sql) def describe_sql(self, expression: exp.Describe) -> str: @@ -668,6 +708,8 @@ class Generator: alias = self.sql(expression, "alias") alias = f"{sep}{alias}" if alias else "" + hints = self.expressions(expression, key="hints", sep=", ", flat=True) + hints = f" WITH ({hints})" if hints else "" laterals = self.expressions(expression, key="laterals", sep="") joins = self.expressions(expression, key="joins", sep="") pivots = self.expressions(expression, key="pivots", sep="") @@ -676,7 +718,7 @@ class Generator: pivots = f"{pivots}{alias}" alias = "" - return f"{table}{alias}{laterals}{joins}{pivots}" + return f"{table}{alias}{hints}{laterals}{joins}{pivots}" def tablesample_sql(self, expression: exp.TableSample) -> str: if self.alias_post_tablesample and expression.this.alias: @@ -1020,7 +1062,9 @@ class Generator: if not partition and not order and not spec and alias: return f"{this} {alias}" - return f"{this} ({alias}{partition_sql}{order_sql}{spec_sql})" + window_args = alias + partition_sql + order_sql + spec_sql + + return f"{this} ({window_args.strip()})" def window_spec_sql(self, expression: exp.WindowSpec) -> str: kind = self.sql(expression, "kind") @@ -1130,6 +1174,8 @@ class Generator: query = expression.args.get("query") unnest = expression.args.get("unnest") field = expression.args.get("field") + is_global = " GLOBAL" if expression.args.get("is_global") else "" + if query: in_sql = self.wrap(query) elif unnest: @@ -1138,7 +1184,8 @@ class Generator: in_sql = self.sql(field) else: in_sql = f"({self.expressions(expression, flat=True)})" - return f"{self.sql(expression, 'this')} IN {in_sql}" + + return f"{self.sql(expression, 'this')}{is_global} IN {in_sql}" def in_unnest_op(self, unnest: exp.Unnest) -> str: return f"(SELECT {self.sql(unnest)})" @@ -1433,7 +1480,7 @@ class Generator: result_sqls = [] for i, e in enumerate(expressions): sql = self.sql(e, comment=False) - comments = self.maybe_comment("", e) + comments = self.maybe_comment("", e) if isinstance(e, exp.Expression) else "" if self.pretty: if self._leading_comma: |