summaryrefslogtreecommitdiffstats
path: root/sqlglot/dialects
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2023-09-12 08:28:54 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2023-09-12 08:28:54 +0000
commit7db33518a4264e422294a1e20fbd1c1505d9a62d (patch)
treeaeb9ae54563b1f8f9c26fd54d0c207b082b89cd4 /sqlglot/dialects
parentReleasing debian version 18.2.0-1. (diff)
downloadsqlglot-7db33518a4264e422294a1e20fbd1c1505d9a62d.tar.xz
sqlglot-7db33518a4264e422294a1e20fbd1c1505d9a62d.zip
Merging upstream version 18.3.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sqlglot/dialects')
-rw-r--r--sqlglot/dialects/doris.py2
-rw-r--r--sqlglot/dialects/mysql.py36
-rw-r--r--sqlglot/dialects/postgres.py6
-rw-r--r--sqlglot/dialects/spark.py7
-rw-r--r--sqlglot/dialects/teradata.py8
-rw-r--r--sqlglot/dialects/tsql.py14
6 files changed, 70 insertions, 3 deletions
diff --git a/sqlglot/dialects/doris.py b/sqlglot/dialects/doris.py
index 4b8919c..bd7e0f2 100644
--- a/sqlglot/dialects/doris.py
+++ b/sqlglot/dialects/doris.py
@@ -33,6 +33,8 @@ class Doris(MySQL):
exp.DataType.Type.TIMESTAMPTZ: "DATETIME",
}
+ TIMESTAMP_FUNC_TYPES = set()
+
TRANSFORMS = {
**MySQL.Generator.TRANSFORMS,
exp.ApproxDistinct: approx_count_distinct_sql,
diff --git a/sqlglot/dialects/mysql.py b/sqlglot/dialects/mysql.py
index f9249eb..6327796 100644
--- a/sqlglot/dialects/mysql.py
+++ b/sqlglot/dialects/mysql.py
@@ -555,7 +555,26 @@ class MySQL(Dialect):
exp.WeekOfYear: rename_func("WEEKOFYEAR"),
}
- TYPE_MAPPING = generator.Generator.TYPE_MAPPING.copy()
+ UNSIGNED_TYPE_MAPPING = {
+ exp.DataType.Type.UBIGINT: "BIGINT",
+ exp.DataType.Type.UINT: "INT",
+ exp.DataType.Type.UMEDIUMINT: "MEDIUMINT",
+ exp.DataType.Type.USMALLINT: "SMALLINT",
+ exp.DataType.Type.UTINYINT: "TINYINT",
+ }
+
+ TIMESTAMP_TYPE_MAPPING = {
+ exp.DataType.Type.TIMESTAMP: "DATETIME",
+ exp.DataType.Type.TIMESTAMPTZ: "TIMESTAMP",
+ exp.DataType.Type.TIMESTAMPLTZ: "TIMESTAMP",
+ }
+
+ TYPE_MAPPING = {
+ **generator.Generator.TYPE_MAPPING,
+ **UNSIGNED_TYPE_MAPPING,
+ **TIMESTAMP_TYPE_MAPPING,
+ }
+
TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMTEXT)
TYPE_MAPPING.pop(exp.DataType.Type.LONGTEXT)
TYPE_MAPPING.pop(exp.DataType.Type.MEDIUMBLOB)
@@ -580,6 +599,18 @@ class MySQL(Dialect):
exp.DataType.Type.VARCHAR: "CHAR",
}
+ TIMESTAMP_FUNC_TYPES = {
+ exp.DataType.Type.TIMESTAMPTZ,
+ exp.DataType.Type.TIMESTAMPLTZ,
+ }
+
+ def datatype_sql(self, expression: exp.DataType) -> str:
+ # https://dev.mysql.com/doc/refman/8.0/en/numeric-type-syntax.html
+ result = super().datatype_sql(expression)
+ if expression.this in self.UNSIGNED_TYPE_MAPPING:
+ result = f"{result} UNSIGNED"
+ return result
+
def limit_sql(self, expression: exp.Limit, top: bool = False) -> str:
# MySQL requires simple literal values for its LIMIT clause.
expression = simplify_literal(expression.copy())
@@ -599,6 +630,9 @@ class MySQL(Dialect):
return f"{self.sql(expression, 'this')} MEMBER OF({self.sql(expression, 'expression')})"
def cast_sql(self, expression: exp.Cast, safe_prefix: t.Optional[str] = None) -> str:
+ if expression.to.this in self.TIMESTAMP_FUNC_TYPES:
+ return self.func("TIMESTAMP", expression.this)
+
to = self.CAST_MAPPING.get(expression.to.this)
if to:
diff --git a/sqlglot/dialects/postgres.py b/sqlglot/dialects/postgres.py
index c26e121..5027013 100644
--- a/sqlglot/dialects/postgres.py
+++ b/sqlglot/dialects/postgres.py
@@ -190,7 +190,11 @@ def _remove_target_from_merge(expression: exp.Expression) -> exp.Expression:
if isinstance(expression, exp.Merge):
alias = expression.this.args.get("alias")
- normalize = lambda identifier: Postgres.normalize_identifier(identifier).name
+ normalize = (
+ lambda identifier: Postgres.normalize_identifier(identifier).name
+ if identifier
+ else None
+ )
targets = {normalize(expression.this.this)}
diff --git a/sqlglot/dialects/spark.py b/sqlglot/dialects/spark.py
index a4435f6..9d4a1ab 100644
--- a/sqlglot/dialects/spark.py
+++ b/sqlglot/dialects/spark.py
@@ -35,6 +35,13 @@ def _parse_datediff(args: t.List) -> exp.Expression:
class Spark(Spark2):
+ class Tokenizer(Spark2.Tokenizer):
+ RAW_STRINGS = [
+ (prefix + q, q)
+ for q in t.cast(t.List[str], Spark2.Tokenizer.QUOTES)
+ for prefix in ("r", "R")
+ ]
+
class Parser(Spark2.Parser):
FUNCTIONS = {
**Spark2.Parser.FUNCTIONS,
diff --git a/sqlglot/dialects/teradata.py b/sqlglot/dialects/teradata.py
index 163cc13..d9de968 100644
--- a/sqlglot/dialects/teradata.py
+++ b/sqlglot/dialects/teradata.py
@@ -45,6 +45,7 @@ class Teradata(Dialect):
"MOD": TokenType.MOD,
"NE": TokenType.NEQ,
"NOT=": TokenType.NEQ,
+ "SAMPLE": TokenType.TABLE_SAMPLE,
"SEL": TokenType.SELECT,
"ST_GEOMETRY": TokenType.GEOMETRY,
"TOP": TokenType.TOP,
@@ -55,6 +56,8 @@ class Teradata(Dialect):
SINGLE_TOKENS.pop("%")
class Parser(parser.Parser):
+ TABLESAMPLE_CSV = True
+
CHARSET_TRANSLATORS = {
"GRAPHIC_TO_KANJISJIS",
"GRAPHIC_TO_LATIN",
@@ -171,6 +174,11 @@ class Teradata(Dialect):
exp.Use: lambda self, e: f"DATABASE {self.sql(e, 'this')}",
}
+ def tablesample_sql(
+ self, expression: exp.TableSample, seed_prefix: str = "SEED", sep=" AS "
+ ) -> str:
+ return f"{self.sql(expression, 'this')} SAMPLE {self.expressions(expression)}"
+
def partitionedbyproperty_sql(self, expression: exp.PartitionedByProperty) -> str:
return f"PARTITION BY {self.sql(expression, 'this')}"
diff --git a/sqlglot/dialects/tsql.py b/sqlglot/dialects/tsql.py
index b26f499..19c586e 100644
--- a/sqlglot/dialects/tsql.py
+++ b/sqlglot/dialects/tsql.py
@@ -57,6 +57,8 @@ TRANSPILE_SAFE_NUMBER_FMT = {"N", "C"}
DEFAULT_START_DATE = datetime.date(1900, 1, 1)
+BIT_TYPES = {exp.EQ, exp.NEQ, exp.Is, exp.In, exp.Select, exp.Alias}
+
def _format_time_lambda(
exp_class: t.Type[E], full_format_mapping: t.Optional[bool] = None
@@ -584,6 +586,7 @@ class TSQL(Dialect):
RETURNING_END = False
NVL2_SUPPORTED = False
ALTER_TABLE_ADD_COLUMN_KEYWORD = False
+ LIMIT_FETCH = "FETCH"
TYPE_MAPPING = {
**generator.Generator.TYPE_MAPPING,
@@ -630,7 +633,16 @@ class TSQL(Dialect):
exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
}
- LIMIT_FETCH = "FETCH"
+ def boolean_sql(self, expression: exp.Boolean) -> str:
+ if type(expression.parent) in BIT_TYPES:
+ return "1" if expression.this else "0"
+
+ return "(1 = 1)" if expression.this else "(1 = 0)"
+
+ def is_sql(self, expression: exp.Is) -> str:
+ if isinstance(expression.expression, exp.Boolean):
+ return self.binary(expression, "=")
+ return self.binary(expression, "IS")
def createable_sql(self, expression: exp.Create, locations: t.DefaultDict) -> str:
sql = self.sql(expression, "this")