diff options
Diffstat (limited to 'sqlglot')
-rw-r--r-- | sqlglot/dialects/snowflake.py | 1 | ||||
-rw-r--r-- | sqlglot/executor/env.py | 2 | ||||
-rw-r--r-- | sqlglot/executor/python.py | 2 | ||||
-rw-r--r-- | sqlglot/expressions.py | 11 | ||||
-rw-r--r-- | sqlglot/generator.py | 21 | ||||
-rw-r--r-- | sqlglot/parser.py | 2 |
6 files changed, 25 insertions, 14 deletions
diff --git a/sqlglot/dialects/snowflake.py b/sqlglot/dialects/snowflake.py index d488d7d..1f620df 100644 --- a/sqlglot/dialects/snowflake.py +++ b/sqlglot/dialects/snowflake.py @@ -275,6 +275,7 @@ class Snowflake(Dialect): KEYWORDS = { **tokens.Tokenizer.KEYWORDS, + "BYTEINT": TokenType.INT, "CHAR VARYING": TokenType.VARCHAR, "CHARACTER VARYING": TokenType.VARCHAR, "EXCLUDE": TokenType.EXCEPT, diff --git a/sqlglot/executor/env.py b/sqlglot/executor/env.py index d2c4e72..5300224 100644 --- a/sqlglot/executor/env.py +++ b/sqlglot/executor/env.py @@ -163,6 +163,7 @@ ENV = { "IF": lambda predicate, true, false: true if predicate else false, "INTDIV": null_if_any(lambda e, this: e // this), "INTERVAL": interval, + "LEFT": null_if_any(lambda this, e: this[:e]), "LIKE": null_if_any( lambda this, e: bool(re.match(e.replace("_", ".").replace("%", ".*"), this)) ), @@ -176,6 +177,7 @@ ENV = { "ORD": null_if_any(ord), "ORDERED": ordered, "POW": pow, + "RIGHT": null_if_any(lambda this, e: this[-e:]), "STRPOSITION": str_position, "SUB": null_if_any(lambda e, this: e - this), "SUBSTRING": substring, diff --git a/sqlglot/executor/python.py b/sqlglot/executor/python.py index 3f96f90..635ec2c 100644 --- a/sqlglot/executor/python.py +++ b/sqlglot/executor/python.py @@ -420,7 +420,7 @@ class Python(Dialect): exp.Column: lambda self, e: f"scope[{self.sql(e, 'table') or None}][{self.sql(e.this)}]", exp.Distinct: lambda self, e: f"set({self.sql(e, 'this')})", exp.Extract: lambda self, e: f"EXTRACT('{e.name.lower()}', {self.sql(e, 'expression')})", - exp.In: lambda self, e: f"{self.sql(e, 'this')} in ({self.expressions(e, flat=True)})", + exp.In: lambda self, e: f"{self.sql(e, 'this')} in {{{self.expressions(e, flat=True)}}}", exp.Interval: lambda self, e: f"INTERVAL({self.sql(e.this)}, '{self.sql(e.unit)}')", exp.Is: lambda self, e: self.binary(e, "is"), exp.Lambda: _lambda_sql, diff --git a/sqlglot/expressions.py b/sqlglot/expressions.py index db94a37..1c0af58 100644 --- a/sqlglot/expressions.py +++ b/sqlglot/expressions.py @@ -1528,6 +1528,7 @@ class Insert(Expression): "exists": False, "partition": False, "alternative": False, + "where": False, } def with_( @@ -5704,11 +5705,12 @@ def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]: } -def table_name(table: Table | str) -> str: +def table_name(table: Table | str, dialect: DialectType = None) -> str: """Get the full name of a table as a string. Args: - table: table expression node or string. + table: Table expression node or string. + dialect: The dialect to generate the table name for. Examples: >>> from sqlglot import exp, parse_one @@ -5724,7 +5726,10 @@ def table_name(table: Table | str) -> str: if not table: raise ValueError(f"Cannot parse {table}") - return ".".join(part for part in (table.text("catalog"), table.text("db"), table.name) if part) + return ".".join( + part.sql(dialect=dialect) if not SAFE_IDENTIFIER_RE.match(part.name) else part.name + for part in table.parts + ) def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E: diff --git a/sqlglot/generator.py b/sqlglot/generator.py index 8d82db4..81e0ac3 100644 --- a/sqlglot/generator.py +++ b/sqlglot/generator.py @@ -912,7 +912,7 @@ class Generator: return f"{prefix}{string}" def partition_sql(self, expression: exp.Partition) -> str: - return f"PARTITION({self.expressions(expression)})" + return f"PARTITION({self.expressions(expression, flat=True)})" def properties_sql(self, expression: exp.Properties) -> str: root_properties = [] @@ -1102,23 +1102,24 @@ class Generator: overwrite = expression.args.get("overwrite") if isinstance(expression.this, exp.Directory): - this = "OVERWRITE " if overwrite else "INTO " + this = " OVERWRITE" if overwrite else " INTO" else: - this = "OVERWRITE TABLE " if overwrite else "INTO " + this = " OVERWRITE TABLE" if overwrite else " INTO" alternative = expression.args.get("alternative") - alternative = f" OR {alternative} " if alternative else " " - this = f"{this}{self.sql(expression, 'this')}" + alternative = f" OR {alternative}" if alternative else "" + this = f"{this} {self.sql(expression, 'this')}" - exists = " IF EXISTS " if expression.args.get("exists") else " " + exists = " IF EXISTS" if expression.args.get("exists") else "" partition_sql = ( - self.sql(expression, "partition") if expression.args.get("partition") else "" + f" {self.sql(expression, 'partition')}" if expression.args.get("partition") else "" ) - expression_sql = self.sql(expression, "expression") + where = self.sql(expression, "where") + where = f"{self.sep()}REPLACE WHERE {where}" if where else "" + expression_sql = f"{self.sep()}{self.sql(expression, 'expression')}" conflict = self.sql(expression, "conflict") returning = self.sql(expression, "returning") - sep = self.sep() if partition_sql else "" - sql = f"INSERT{alternative}{this}{exists}{partition_sql}{sep}{expression_sql}{conflict}{returning}" + sql = f"INSERT{alternative}{this}{exists}{partition_sql}{where}{expression_sql}{conflict}{returning}" return self.prepend_ctes(expression, sql) def intersect_sql(self, expression: exp.Intersect) -> str: diff --git a/sqlglot/parser.py b/sqlglot/parser.py index a9648ef..e16a88e 100644 --- a/sqlglot/parser.py +++ b/sqlglot/parser.py @@ -1677,6 +1677,8 @@ class Parser(metaclass=_Parser): this=this, exists=self._parse_exists(), partition=self._parse_partition(), + where=self._match_pair(TokenType.REPLACE, TokenType.WHERE) + and self._parse_conjunction(), expression=self._parse_ddl_select(), conflict=self._parse_on_conflict(), returning=self._parse_returning(), |