summaryrefslogtreecommitdiffstats
path: root/tests/dialects
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2025-01-27 16:31:23 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2025-01-27 16:31:23 +0000
commit886e522786b50d8cb126baacbd1eaf92861832ec (patch)
tree6d9736731779fe0f981e8a3692c9eeb37e40fbf3 /tests/dialects
parentReleasing debian version 26.2.1-1. (diff)
downloadsqlglot-886e522786b50d8cb126baacbd1eaf92861832ec.tar.xz
sqlglot-886e522786b50d8cb126baacbd1eaf92861832ec.zip
Merging upstream version 26.3.8.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/dialects')
-rw-r--r--tests/dialects/test_athena.py13
-rw-r--r--tests/dialects/test_bigquery.py42
-rw-r--r--tests/dialects/test_clickhouse.py12
-rw-r--r--tests/dialects/test_dialect.py206
-rw-r--r--tests/dialects/test_duckdb.py7
-rw-r--r--tests/dialects/test_hive.py5
-rw-r--r--tests/dialects/test_oracle.py9
-rw-r--r--tests/dialects/test_postgres.py9
-rw-r--r--tests/dialects/test_presto.py16
-rw-r--r--tests/dialects/test_snowflake.py49
-rw-r--r--tests/dialects/test_sqlite.py1
-rw-r--r--tests/dialects/test_trino.py7
-rw-r--r--tests/dialects/test_tsql.py10
13 files changed, 319 insertions, 67 deletions
diff --git a/tests/dialects/test_athena.py b/tests/dialects/test_athena.py
index ef96938..c5ba4cc 100644
--- a/tests/dialects/test_athena.py
+++ b/tests/dialects/test_athena.py
@@ -198,7 +198,8 @@ class TestAthena(Validator):
def test_ctas(self):
# Hive tables use 'external_location' to specify the table location, Iceberg tables use 'location' to specify the table location
- # The 'table_type' property is used to determine if it's a Hive or an Iceberg table
+ # In addition, Hive tables used 'partitioned_by' to specify the partition fields and Iceberg tables use 'partitioning' to specify the partition fields
+ # The 'table_type' property is used to determine if it's a Hive or an Iceberg table. If it's omitted, it defaults to Hive
# ref: https://docs.aws.amazon.com/athena/latest/ug/create-table-as.html#ctas-table-properties
ctas_hive = exp.Create(
this=exp.to_table("foo.bar"),
@@ -207,13 +208,16 @@ class TestAthena(Validator):
expressions=[
exp.FileFormatProperty(this=exp.Literal.string("parquet")),
exp.LocationProperty(this=exp.Literal.string("s3://foo")),
+ exp.PartitionedByProperty(
+ this=exp.Schema(expressions=[exp.to_column("partition_col")])
+ ),
]
),
expression=exp.select("1"),
)
self.assertEqual(
ctas_hive.sql(dialect=self.dialect, identify=True),
- "CREATE TABLE \"foo\".\"bar\" WITH (format='parquet', external_location='s3://foo') AS SELECT 1",
+ "CREATE TABLE \"foo\".\"bar\" WITH (format='parquet', external_location='s3://foo', partitioned_by=ARRAY['partition_col']) AS SELECT 1",
)
ctas_iceberg = exp.Create(
@@ -223,11 +227,14 @@ class TestAthena(Validator):
expressions=[
exp.Property(this=exp.var("table_type"), value=exp.Literal.string("iceberg")),
exp.LocationProperty(this=exp.Literal.string("s3://foo")),
+ exp.PartitionedByProperty(
+ this=exp.Schema(expressions=[exp.to_column("partition_col")])
+ ),
]
),
expression=exp.select("1"),
)
self.assertEqual(
ctas_iceberg.sql(dialect=self.dialect, identify=True),
- "CREATE TABLE \"foo\".\"bar\" WITH (table_type='iceberg', location='s3://foo') AS SELECT 1",
+ "CREATE TABLE \"foo\".\"bar\" WITH (table_type='iceberg', location='s3://foo', partitioning=ARRAY['partition_col']) AS SELECT 1",
)
diff --git a/tests/dialects/test_bigquery.py b/tests/dialects/test_bigquery.py
index dbe4401..15372fc 100644
--- a/tests/dialects/test_bigquery.py
+++ b/tests/dialects/test_bigquery.py
@@ -1572,14 +1572,30 @@ WHERE
"SAFE_DIVIDE(x, y)",
write={
"bigquery": "SAFE_DIVIDE(x, y)",
- "duckdb": "IF((y) <> 0, (x) / (y), NULL)",
- "presto": "IF((y) <> 0, (x) / (y), NULL)",
- "trino": "IF((y) <> 0, (x) / (y), NULL)",
- "hive": "IF((y) <> 0, (x) / (y), NULL)",
- "spark2": "IF((y) <> 0, (x) / (y), NULL)",
- "spark": "IF((y) <> 0, (x) / (y), NULL)",
- "databricks": "IF((y) <> 0, (x) / (y), NULL)",
- "snowflake": "IFF((y) <> 0, (x) / (y), NULL)",
+ "duckdb": "CASE WHEN y <> 0 THEN x / y ELSE NULL END",
+ "presto": "IF(y <> 0, CAST(x AS DOUBLE) / y, NULL)",
+ "trino": "IF(y <> 0, CAST(x AS DOUBLE) / y, NULL)",
+ "hive": "IF(y <> 0, x / y, NULL)",
+ "spark2": "IF(y <> 0, x / y, NULL)",
+ "spark": "IF(y <> 0, x / y, NULL)",
+ "databricks": "IF(y <> 0, x / y, NULL)",
+ "snowflake": "IFF(y <> 0, x / y, NULL)",
+ "postgres": "CASE WHEN y <> 0 THEN CAST(x AS DOUBLE PRECISION) / y ELSE NULL END",
+ },
+ )
+ self.validate_all(
+ "SAFE_DIVIDE(x + 1, 2 * y)",
+ write={
+ "bigquery": "SAFE_DIVIDE(x + 1, 2 * y)",
+ "duckdb": "CASE WHEN (2 * y) <> 0 THEN (x + 1) / (2 * y) ELSE NULL END",
+ "presto": "IF((2 * y) <> 0, CAST((x + 1) AS DOUBLE) / (2 * y), NULL)",
+ "trino": "IF((2 * y) <> 0, CAST((x + 1) AS DOUBLE) / (2 * y), NULL)",
+ "hive": "IF((2 * y) <> 0, (x + 1) / (2 * y), NULL)",
+ "spark2": "IF((2 * y) <> 0, (x + 1) / (2 * y), NULL)",
+ "spark": "IF((2 * y) <> 0, (x + 1) / (2 * y), NULL)",
+ "databricks": "IF((2 * y) <> 0, (x + 1) / (2 * y), NULL)",
+ "snowflake": "IFF((2 * y) <> 0, (x + 1) / (2 * y), NULL)",
+ "postgres": "CASE WHEN (2 * y) <> 0 THEN CAST((x + 1) AS DOUBLE PRECISION) / (2 * y) ELSE NULL END",
},
)
self.validate_all(
@@ -1591,11 +1607,11 @@ WHERE
},
)
self.validate_all(
- "SELECT STRPOS('foo@example.com', '@')",
+ "SELECT INSTR('foo@example.com', '@')",
write={
- "bigquery": "SELECT STRPOS('foo@example.com', '@')",
+ "bigquery": "SELECT INSTR('foo@example.com', '@')",
"duckdb": "SELECT STRPOS('foo@example.com', '@')",
- "snowflake": "SELECT POSITION('@', 'foo@example.com')",
+ "snowflake": "SELECT CHARINDEX('@', 'foo@example.com')",
},
)
self.validate_all(
@@ -2239,8 +2255,8 @@ OPTIONS (
r"REGEXP_EXTRACT(svc_plugin_output, '\\\\\\((.*)')",
)
self.validate_identity(
- r"REGEXP_SUBSTR(value, pattern, position, occurence)",
- r"REGEXP_EXTRACT(value, pattern, position, occurence)",
+ r"REGEXP_SUBSTR(value, pattern, position, occurrence)",
+ r"REGEXP_EXTRACT(value, pattern, position, occurrence)",
)
self.validate_all(
diff --git a/tests/dialects/test_clickhouse.py b/tests/dialects/test_clickhouse.py
index 3bff6e2..a4ee23c 100644
--- a/tests/dialects/test_clickhouse.py
+++ b/tests/dialects/test_clickhouse.py
@@ -85,8 +85,8 @@ class TestClickhouse(Validator):
self.validate_identity("SELECT exponentialTimeDecayedAvg(60)(a, b)")
self.validate_identity("levenshteinDistance(col1, col2)", "editDistance(col1, col2)")
self.validate_identity("SELECT * FROM foo WHERE x GLOBAL IN (SELECT * FROM bar)")
- self.validate_identity("position(haystack, needle)")
- self.validate_identity("position(haystack, needle, position)")
+ self.validate_identity("POSITION(haystack, needle)")
+ self.validate_identity("POSITION(haystack, needle, position)")
self.validate_identity("CAST(x AS DATETIME)", "CAST(x AS DateTime)")
self.validate_identity("CAST(x AS TIMESTAMPTZ)", "CAST(x AS DateTime)")
self.validate_identity("CAST(x as MEDIUMINT)", "CAST(x AS Int32)")
@@ -398,9 +398,8 @@ class TestClickhouse(Validator):
"clickhouse": "SELECT quantileIf(0.5)(a, TRUE)",
},
)
- self.validate_all(
- "SELECT position(needle IN haystack)",
- write={"clickhouse": "SELECT position(haystack, needle)"},
+ self.validate_identity(
+ "SELECT POSITION(needle IN haystack)", "SELECT POSITION(haystack, needle)"
)
self.validate_identity(
"SELECT * FROM x LIMIT 10 SETTINGS max_results = 100, result = 'break'"
@@ -742,6 +741,9 @@ class TestClickhouse(Validator):
"CREATE TABLE a ENGINE=Memory AS SELECT 1 AS c COMMENT 'foo'",
"CREATE TABLE a ENGINE=Memory AS (SELECT 1 AS c) COMMENT 'foo'",
)
+ self.validate_identity(
+ 'CREATE TABLE t1 ("x" UInt32, "y" Dynamic, "z" Dynamic(max_types = 10)) ENGINE=MergeTree ORDER BY x'
+ )
self.validate_all(
"CREATE DATABASE x",
diff --git a/tests/dialects/test_dialect.py b/tests/dialects/test_dialect.py
index 1573329..d408f90 100644
--- a/tests/dialects/test_dialect.py
+++ b/tests/dialects/test_dialect.py
@@ -314,7 +314,7 @@ class TestDialect(Validator):
"materialize": "CAST(a AS SMALLINT)",
"mysql": "CAST(a AS SIGNED)",
"hive": "CAST(a AS SMALLINT)",
- "oracle": "CAST(a AS NUMBER)",
+ "oracle": "CAST(a AS SMALLINT)",
"postgres": "CAST(a AS SMALLINT)",
"presto": "CAST(a AS SMALLINT)",
"redshift": "CAST(a AS SMALLINT)",
@@ -374,10 +374,10 @@ class TestDialect(Validator):
"mysql": "TIMESTAMP(a)",
},
)
- self.validate_all("CAST(a AS TINYINT)", write={"oracle": "CAST(a AS NUMBER)"})
- self.validate_all("CAST(a AS SMALLINT)", write={"oracle": "CAST(a AS NUMBER)"})
- self.validate_all("CAST(a AS BIGINT)", write={"oracle": "CAST(a AS NUMBER)"})
- self.validate_all("CAST(a AS INT)", write={"oracle": "CAST(a AS NUMBER)"})
+ self.validate_all("CAST(a AS TINYINT)", write={"oracle": "CAST(a AS SMALLINT)"})
+ self.validate_all("CAST(a AS SMALLINT)", write={"oracle": "CAST(a AS SMALLINT)"})
+ self.validate_all("CAST(a AS BIGINT)", write={"oracle": "CAST(a AS INT)"})
+ self.validate_all("CAST(a AS INT)", write={"oracle": "CAST(a AS INT)"})
self.validate_all(
"CAST(a AS DECIMAL)",
read={"oracle": "CAST(a AS NUMBER)"},
@@ -1682,42 +1682,202 @@ class TestDialect(Validator):
},
)
self.validate_all(
- "POSITION(needle IN haystack)",
- write={
+ "STR_POSITION(haystack, needle)",
+ read={
+ "athena": "POSITION(needle in haystack)",
+ "clickhouse": "POSITION(needle in haystack)",
+ "databricks": "POSITION(needle in haystack)",
+ "drill": "POSITION(needle in haystack)",
+ "duckdb": "POSITION(needle in haystack)",
+ "materialize": "POSITION(needle in haystack)",
+ "mysql": "POSITION(needle in haystack)",
+ "postgres": "POSITION(needle in haystack)",
+ "presto": "POSITION(needle in haystack)",
+ "redshift": "POSITION(needle in haystack)",
+ "risingwave": "POSITION(needle in haystack)",
+ "snowflake": "POSITION(needle in haystack)",
+ "spark": "POSITION(needle in haystack)",
+ "spark2": "POSITION(needle in haystack)",
+ "teradata": "POSITION(needle in haystack)",
+ "trino": "POSITION(needle in haystack)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle)",
+ read={
+ "clickhouse": "POSITION(haystack, needle)",
+ "databricks": "POSITION(needle, haystack)",
+ "snowflake": "POSITION(needle, haystack)",
+ "spark2": "POSITION(needle, haystack)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle)",
+ read={
+ "athena": "STRPOS(haystack, needle)",
+ "bigquery": "STRPOS(haystack, needle)",
"drill": "STRPOS(haystack, needle)",
"duckdb": "STRPOS(haystack, needle)",
"postgres": "STRPOS(haystack, needle)",
"presto": "STRPOS(haystack, needle)",
- "spark": "LOCATE(needle, haystack)",
- "clickhouse": "position(haystack, needle)",
- "snowflake": "POSITION(needle, haystack)",
+ "redshift": "STRPOS(haystack, needle)",
+ "trino": "STRPOS(haystack, needle)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle)",
+ read={
+ "bigquery": "INSTR(haystack, needle)",
+ "databricks": "INSTR(haystack, needle)",
+ "doris": "INSTR(haystack, needle)",
+ "duckdb": "INSTR(haystack, needle)",
+ "hive": "INSTR(haystack, needle)",
+ "mysql": "INSTR(haystack, needle)",
+ "oracle": "INSTR(haystack, needle)",
+ "spark": "INSTR(haystack, needle)",
+ "spark2": "INSTR(haystack, needle)",
+ "sqlite": "INSTR(haystack, needle)",
+ "starrocks": "INSTR(haystack, needle)",
+ "teradata": "INSTR(haystack, needle)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle)",
+ read={
+ "clickhouse": "LOCATE(needle, haystack)",
+ "databricks": "LOCATE(needle, haystack)",
+ "doris": "LOCATE(needle, haystack)",
+ "hive": "LOCATE(needle, haystack)",
"mysql": "LOCATE(needle, haystack)",
+ "spark": "LOCATE(needle, haystack)",
+ "spark2": "LOCATE(needle, haystack)",
+ "starrocks": "LOCATE(needle, haystack)",
+ "teradata": "LOCATE(needle, haystack)",
},
)
self.validate_all(
"STR_POSITION(haystack, needle)",
+ read={
+ "athena": "CHARINDEX(needle, haystack)",
+ "databricks": "CHARINDEX(needle, haystack)",
+ "snowflake": "CHARINDEX(needle, haystack)",
+ "tsql": "CHARINDEX(needle, haystack)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle)",
+ read={
+ "tableau": "FIND(haystack, needle)",
+ },
write={
+ "athena": "STRPOS(haystack, needle)",
+ "bigquery": "INSTR(haystack, needle)",
+ "clickhouse": "POSITION(haystack, needle)",
+ "databricks": "LOCATE(needle, haystack)",
+ "doris": "LOCATE(needle, haystack)",
"drill": "STRPOS(haystack, needle)",
"duckdb": "STRPOS(haystack, needle)",
- "postgres": "STRPOS(haystack, needle)",
+ "hive": "LOCATE(needle, haystack)",
+ "materialize": "POSITION(needle IN haystack)",
+ "mysql": "LOCATE(needle, haystack)",
+ "oracle": "INSTR(haystack, needle)",
+ "postgres": "POSITION(needle IN haystack)",
"presto": "STRPOS(haystack, needle)",
- "bigquery": "STRPOS(haystack, needle)",
+ "redshift": "POSITION(needle IN haystack)",
+ "risingwave": "POSITION(needle IN haystack)",
+ "snowflake": "CHARINDEX(needle, haystack)",
"spark": "LOCATE(needle, haystack)",
- "clickhouse": "position(haystack, needle)",
- "snowflake": "POSITION(needle, haystack)",
- "mysql": "LOCATE(needle, haystack)",
+ "spark2": "LOCATE(needle, haystack)",
+ "sqlite": "INSTR(haystack, needle)",
+ "tableau": "FIND(haystack, needle)",
+ "teradata": "INSTR(haystack, needle)",
+ "trino": "STRPOS(haystack, needle)",
+ "tsql": "CHARINDEX(needle, haystack)",
},
)
self.validate_all(
- "POSITION(needle, haystack, pos)",
+ "STR_POSITION(haystack, needle, position)",
+ read={
+ "clickhouse": "POSITION(haystack, needle, position)",
+ "databricks": "POSITION(needle, haystack, position)",
+ "snowflake": "POSITION(needle, haystack, position)",
+ "spark": "POSITION(needle, haystack, position)",
+ "spark2": "POSITION(needle, haystack, position)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle, position)",
+ read={
+ "doris": "LOCATE(needle, haystack, position)",
+ "hive": "LOCATE(needle, haystack, position)",
+ "mysql": "LOCATE(needle, haystack, position)",
+ "spark": "LOCATE(needle, haystack, position)",
+ "spark2": "LOCATE(needle, haystack, position)",
+ "starrocks": "LOCATE(needle, haystack, position)",
+ "teradata": "LOCATE(needle, haystack, position)",
+ "clickhouse": "LOCATE(needle, haystack, position)",
+ "databricks": "LOCATE(needle, haystack, position)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle, position)",
+ read={
+ "bigquery": "INSTR(haystack, needle, position)",
+ "doris": "INSTR(haystack, needle, position)",
+ "oracle": "INSTR(haystack, needle, position)",
+ "teradata": "INSTR(haystack, needle, position)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle, position)",
+ read={
+ "databricks": "CHARINDEX(needle, haystack, position)",
+ "snowflake": "CHARINDEX(needle, haystack, position)",
+ "tsql": "CHARINDEX(needle, haystack, position)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle, position)",
+ write={
+ "athena": "IF(STRPOS(SUBSTRING(haystack, position), needle) = 0, 0, STRPOS(SUBSTRING(haystack, position), needle) + position - 1)",
+ "bigquery": "INSTR(haystack, needle, position)",
+ "clickhouse": "POSITION(haystack, needle, position)",
+ "databricks": "LOCATE(needle, haystack, position)",
+ "doris": "LOCATE(needle, haystack, position)",
+ "drill": "`IF`(STRPOS(SUBSTRING(haystack, position), needle) = 0, 0, STRPOS(SUBSTRING(haystack, position), needle) + position - 1)",
+ "duckdb": "CASE WHEN STRPOS(SUBSTRING(haystack, position), needle) = 0 THEN 0 ELSE STRPOS(SUBSTRING(haystack, position), needle) + position - 1 END",
+ "hive": "LOCATE(needle, haystack, position)",
+ "materialize": "CASE WHEN POSITION(needle IN SUBSTRING(haystack FROM position)) = 0 THEN 0 ELSE POSITION(needle IN SUBSTRING(haystack FROM position)) + position - 1 END",
+ "mysql": "LOCATE(needle, haystack, position)",
+ "oracle": "INSTR(haystack, needle, position)",
+ "postgres": "CASE WHEN POSITION(needle IN SUBSTRING(haystack FROM position)) = 0 THEN 0 ELSE POSITION(needle IN SUBSTRING(haystack FROM position)) + position - 1 END",
+ "presto": "IF(STRPOS(SUBSTRING(haystack, position), needle) = 0, 0, STRPOS(SUBSTRING(haystack, position), needle) + position - 1)",
+ "redshift": "CASE WHEN POSITION(needle IN SUBSTRING(haystack FROM position)) = 0 THEN 0 ELSE POSITION(needle IN SUBSTRING(haystack FROM position)) + position - 1 END",
+ "risingwave": "CASE WHEN POSITION(needle IN SUBSTRING(haystack FROM position)) = 0 THEN 0 ELSE POSITION(needle IN SUBSTRING(haystack FROM position)) + position - 1 END",
+ "snowflake": "CHARINDEX(needle, haystack, position)",
+ "spark": "LOCATE(needle, haystack, position)",
+ "spark2": "LOCATE(needle, haystack, position)",
+ "sqlite": "IIF(INSTR(SUBSTRING(haystack, position), needle) = 0, 0, INSTR(SUBSTRING(haystack, position), needle) + position - 1)",
+ "tableau": "IF FIND(SUBSTRING(haystack, position), needle) = 0 THEN 0 ELSE FIND(SUBSTRING(haystack, position), needle) + position - 1 END",
+ "teradata": "INSTR(haystack, needle, position)",
+ "trino": "IF(STRPOS(SUBSTRING(haystack, position), needle) = 0, 0, STRPOS(SUBSTRING(haystack, position), needle) + position - 1)",
+ "tsql": "CHARINDEX(needle, haystack, position)",
+ },
+ )
+ self.validate_all(
+ "STR_POSITION(haystack, needle, position, occurrence)",
+ read={
+ "bigquery": "INSTR(haystack, needle, position, occurrence)",
+ "oracle": "INSTR(haystack, needle, position, occurrence)",
+ "teradata": "INSTR(haystack, needle, position, occurrence)",
+ },
write={
- "drill": "`IF`(STRPOS(SUBSTR(haystack, pos), needle) = 0, 0, STRPOS(SUBSTR(haystack, pos), needle) + pos - 1)",
- "presto": "IF(STRPOS(SUBSTR(haystack, pos), needle) = 0, 0, STRPOS(SUBSTR(haystack, pos), needle) + pos - 1)",
- "postgres": "CASE WHEN STRPOS(SUBSTR(haystack, pos), needle) = 0 THEN 0 ELSE STRPOS(SUBSTR(haystack, pos), needle) + pos - 1 END",
- "spark": "LOCATE(needle, haystack, pos)",
- "clickhouse": "position(haystack, needle, pos)",
- "snowflake": "POSITION(needle, haystack, pos)",
- "mysql": "LOCATE(needle, haystack, pos)",
+ "bigquery": "INSTR(haystack, needle, position, occurrence)",
+ "oracle": "INSTR(haystack, needle, position, occurrence)",
+ "presto": "IF(STRPOS(SUBSTRING(haystack, position), needle, occurrence) = 0, 0, STRPOS(SUBSTRING(haystack, position), needle, occurrence) + position - 1)",
+ "tableau": "IF FINDNTH(SUBSTRING(haystack, position), needle, occurrence) = 0 THEN 0 ELSE FINDNTH(SUBSTRING(haystack, position), needle, occurrence) + position - 1 END",
+ "teradata": "INSTR(haystack, needle, position, occurrence)",
+ "trino": "IF(STRPOS(SUBSTRING(haystack, position), needle, occurrence) = 0, 0, STRPOS(SUBSTRING(haystack, position), needle, occurrence) + position - 1)",
},
)
self.validate_all(
diff --git a/tests/dialects/test_duckdb.py b/tests/dialects/test_duckdb.py
index 69a592d..959a1b3 100644
--- a/tests/dialects/test_duckdb.py
+++ b/tests/dialects/test_duckdb.py
@@ -903,6 +903,13 @@ class TestDuckDB(Validator):
},
)
+ self.validate_all(
+ "SELECT REGEXP_MATCHES('ThOmAs', 'thomas', 'i')",
+ read={
+ "postgres": "SELECT 'ThOmAs' ~* 'thomas'",
+ },
+ )
+
def test_array_index(self):
with self.assertLogs(helper_logger) as cm:
self.validate_all(
diff --git a/tests/dialects/test_hive.py b/tests/dialects/test_hive.py
index e52ee72..edc208c 100644
--- a/tests/dialects/test_hive.py
+++ b/tests/dialects/test_hive.py
@@ -588,8 +588,8 @@ class TestHive(Validator):
self.validate_all(
"LOCATE('a', x, 3)",
write={
- "duckdb": "CASE WHEN STRPOS(SUBSTR(x, 3), 'a') = 0 THEN 0 ELSE STRPOS(SUBSTR(x, 3), 'a') + 3 - 1 END",
- "presto": "IF(STRPOS(SUBSTR(x, 3), 'a') = 0, 0, STRPOS(SUBSTR(x, 3), 'a') + 3 - 1)",
+ "duckdb": "CASE WHEN STRPOS(SUBSTRING(x, 3), 'a') = 0 THEN 0 ELSE STRPOS(SUBSTRING(x, 3), 'a') + 3 - 1 END",
+ "presto": "IF(STRPOS(SUBSTRING(x, 3), 'a') = 0, 0, STRPOS(SUBSTRING(x, 3), 'a') + 3 - 1)",
"hive": "LOCATE('a', x, 3)",
"spark": "LOCATE('a', x, 3)",
},
@@ -740,6 +740,7 @@ class TestHive(Validator):
"presto": "SET_AGG(x)",
"snowflake": "ARRAY_UNIQUE_AGG(x)",
"spark": "COLLECT_SET(x)",
+ "trino": "ARRAY_AGG(DISTINCT x)",
},
)
self.validate_all(
diff --git a/tests/dialects/test_oracle.py b/tests/dialects/test_oracle.py
index 0abef50..ac748cd 100644
--- a/tests/dialects/test_oracle.py
+++ b/tests/dialects/test_oracle.py
@@ -394,6 +394,9 @@ JOIN departments
self.validate_identity(
"XMLTABLE('x' RETURNING SEQUENCE BY REF COLUMNS a VARCHAR2, b FLOAT)"
)
+ self.validate_identity(
+ "SELECT x.* FROM example t, XMLTABLE(XMLNAMESPACES(DEFAULT 'http://example.com/default', 'http://example.com/ns1' AS \"ns1\"), '/root/data' PASSING t.xml COLUMNS id NUMBER PATH '@id', value VARCHAR2(100) PATH 'ns1:value/text()') x"
+ )
self.validate_all(
"""SELECT warehouse_name warehouse,
@@ -513,10 +516,10 @@ FROM JSON_TABLE(res, '$.info[*]' COLUMNS(
LEVEL,
SYS_CONNECT_BY_PATH(last_name, '/') AS "Path"
FROM employees
-START WITH last_name = 'King'
-CONNECT BY PRIOR employee_id = manager_id AND LEVEL <= 4
WHERE
- level <= 3 AND department_id = 80"""
+ level <= 3 AND department_id = 80
+START WITH last_name = 'King'
+CONNECT BY PRIOR employee_id = manager_id AND LEVEL <= 4"""
for query in (f"{body}{start}{connect}", f"{body}{connect}{start}"):
self.validate_identity(query, pretty, pretty=True)
diff --git a/tests/dialects/test_postgres.py b/tests/dialects/test_postgres.py
index 6a52ea2..6714de2 100644
--- a/tests/dialects/test_postgres.py
+++ b/tests/dialects/test_postgres.py
@@ -76,7 +76,10 @@ class TestPostgres(Validator):
self.validate_identity("SELECT CURRENT_USER")
self.validate_identity("SELECT * FROM ONLY t1")
self.validate_identity(
- "SELECT id, name FROM XMLTABLE('/root/user' PASSING xml_data COLUMNS id INT PATH '@id', name TEXT PATH 'name/text()') AS t"
+ "SELECT id, name FROM xml_data AS t, XMLTABLE('/root/user' PASSING t.xml COLUMNS id INT PATH '@id', name TEXT PATH 'name/text()') AS x"
+ )
+ self.validate_identity(
+ "SELECT id, value FROM xml_content AS t, XMLTABLE(XMLNAMESPACES('http://example.com/ns1' AS ns1, 'http://example.com/ns2' AS ns2), '/root/data' PASSING t.xml COLUMNS id INT PATH '@ns1:id', value TEXT PATH 'ns2:value/text()') AS x"
)
self.validate_identity(
"SELECT * FROM t WHERE some_column >= CURRENT_DATE + INTERVAL '1 day 1 hour' AND some_another_column IS TRUE"
@@ -830,6 +833,10 @@ class TestPostgres(Validator):
"/* + some comment */ SELECT b.foo, b.bar FROM baz AS b",
)
+ self.validate_identity(
+ "SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY a) FILTER(WHERE CAST(b AS BOOLEAN)) AS mean_value FROM (VALUES (0, 't')) AS fake_data(a, b)"
+ )
+
def test_ddl(self):
# Checks that user-defined types are parsed into DataType instead of Identifier
self.parse_one("CREATE TABLE t (a udt)").this.expressions[0].args["kind"].assert_is(
diff --git a/tests/dialects/test_presto.py b/tests/dialects/test_presto.py
index fa5c8c1..c84f000 100644
--- a/tests/dialects/test_presto.py
+++ b/tests/dialects/test_presto.py
@@ -204,14 +204,14 @@ class TestPresto(Validator):
},
)
self.validate_all(
- "STRPOS('ABC', 'A', 3)",
- read={
- "trino": "STRPOS('ABC', 'A', 3)",
- },
- write={
- "presto": "STRPOS('ABC', 'A', 3)",
- "trino": "STRPOS('ABC', 'A', 3)",
- "snowflake": "POSITION('A', 'ABC')",
+ "STRPOS(haystack, needle, occurrence)",
+ write={
+ "bigquery": "INSTR(haystack, needle, 1, occurrence)",
+ "oracle": "INSTR(haystack, needle, 1, occurrence)",
+ "presto": "STRPOS(haystack, needle, occurrence)",
+ "tableau": "FINDNTH(haystack, needle, occurrence)",
+ "trino": "STRPOS(haystack, needle, occurrence)",
+ "teradata": "INSTR(haystack, needle, 1, occurrence)",
},
)
diff --git a/tests/dialects/test_snowflake.py b/tests/dialects/test_snowflake.py
index 5c0cc01..cb38af7 100644
--- a/tests/dialects/test_snowflake.py
+++ b/tests/dialects/test_snowflake.py
@@ -36,7 +36,6 @@ class TestSnowflake(Validator):
self.validate_identity("SELECT CAST(obj AS OBJECT(x CHAR) RENAME FIELDS)")
self.validate_identity("SELECT CAST(obj AS OBJECT(x CHAR, y VARCHAR) ADD FIELDS)")
self.validate_identity("SELECT TO_TIMESTAMP(123.4)").selects[0].assert_is(exp.Anonymous)
- self.validate_identity("SELECT TO_TIME(x) FROM t")
self.validate_identity("SELECT TO_TIMESTAMP(x) FROM t")
self.validate_identity("SELECT TO_TIMESTAMP_NTZ(x) FROM t")
self.validate_identity("SELECT TO_TIMESTAMP_LTZ(x) FROM t")
@@ -106,6 +105,9 @@ class TestSnowflake(Validator):
"SELECT * FROM DATA AS DATA_L ASOF JOIN DATA AS DATA_R MATCH_CONDITION (DATA_L.VAL > DATA_R.VAL) ON DATA_L.ID = DATA_R.ID"
)
self.validate_identity(
+ """SELECT TO_TIMESTAMP('2025-01-16T14:45:30.123+0500', 'yyyy-mm-DD"T"hh24:mi:ss.ff3TZHTZM')"""
+ )
+ self.validate_identity(
"WITH t (SELECT 1 AS c) SELECT c FROM t",
"WITH t AS (SELECT 1 AS c) SELECT c FROM t",
)
@@ -295,6 +297,13 @@ class TestSnowflake(Validator):
)
self.validate_all(
+ "SELECT TO_TIMESTAMP('2025-01-16 14:45:30.123', 'yyyy-mm-DD hh24:mi:ss.ff6')",
+ write={
+ "": "SELECT STR_TO_TIME('2025-01-16 14:45:30.123', '%Y-%m-%d %H:%M:%S.%f')",
+ "snowflake": "SELECT TO_TIMESTAMP('2025-01-16 14:45:30.123', 'yyyy-mm-DD hh24:mi:ss.ff6')",
+ },
+ )
+ self.validate_all(
"ARRAY_CONSTRUCT_COMPACT(1, null, 2)",
write={
"spark": "ARRAY_COMPACT(ARRAY(1, NULL, 2))",
@@ -721,13 +730,6 @@ class TestSnowflake(Validator):
},
)
self.validate_all(
- "SELECT TO_TIME('12:05:00')",
- write={
- "bigquery": "SELECT CAST('12:05:00' AS TIME)",
- "snowflake": "SELECT CAST('12:05:00' AS TIME)",
- },
- )
- self.validate_all(
"SELECT TO_TIMESTAMP('04/05/2013 01:02:03', 'mm/DD/yyyy hh24:mi:ss')",
read={
"bigquery": "SELECT PARSE_TIMESTAMP('%m/%d/%Y %H:%M:%S', '04/05/2013 01:02:03')",
@@ -1286,6 +1288,37 @@ class TestSnowflake(Validator):
},
)
+ self.validate_identity("SELECT TO_TIME(x) FROM t")
+ self.validate_all(
+ "SELECT TO_TIME('12:05:00')",
+ write={
+ "bigquery": "SELECT CAST('12:05:00' AS TIME)",
+ "snowflake": "SELECT CAST('12:05:00' AS TIME)",
+ "duckdb": "SELECT CAST('12:05:00' AS TIME)",
+ },
+ )
+ self.validate_all(
+ "SELECT TO_TIME(CONVERT_TIMEZONE('UTC', 'US/Pacific', '2024-08-06 09:10:00.000')) AS pst_time",
+ write={
+ "snowflake": "SELECT TO_TIME(CONVERT_TIMEZONE('UTC', 'US/Pacific', '2024-08-06 09:10:00.000')) AS pst_time",
+ "duckdb": "SELECT CAST(CAST('2024-08-06 09:10:00.000' AS TIMESTAMP) AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific' AS TIME) AS pst_time",
+ },
+ )
+ self.validate_all(
+ "SELECT TO_TIME('11.15.00', 'hh24.mi.ss')",
+ write={
+ "snowflake": "SELECT TO_TIME('11.15.00', 'hh24.mi.ss')",
+ "duckdb": "SELECT CAST(STRPTIME('11.15.00', '%H.%M.%S') AS TIME)",
+ },
+ )
+ self.validate_all(
+ "SELECT TRY_TO_TIME('11.15.00', 'hh24.mi.ss')",
+ write={
+ "snowflake": "SELECT TRY_TO_TIME('11.15.00', 'hh24.mi.ss')",
+ "duckdb": "SELECT CAST(STRPTIME('11.15.00', '%H.%M.%S') AS TIME)",
+ },
+ )
+
def test_semi_structured_types(self):
self.validate_identity("SELECT CAST(a AS VARIANT)")
self.validate_identity("SELECT CAST(a AS ARRAY)")
diff --git a/tests/dialects/test_sqlite.py b/tests/dialects/test_sqlite.py
index 1a4f5c3..066828a 100644
--- a/tests/dialects/test_sqlite.py
+++ b/tests/dialects/test_sqlite.py
@@ -7,6 +7,7 @@ class TestSQLite(Validator):
dialect = "sqlite"
def test_sqlite(self):
+ self.validate_identity("UNHEX(a, b)")
self.validate_identity("SELECT DATE()")
self.validate_identity("SELECT DATE('now', 'start of month', '+1 month', '-1 day')")
self.validate_identity("SELECT DATETIME(1092941466, 'unixepoch')")
diff --git a/tests/dialects/test_trino.py b/tests/dialects/test_trino.py
index 3b22f0d..44ff1ea 100644
--- a/tests/dialects/test_trino.py
+++ b/tests/dialects/test_trino.py
@@ -9,6 +9,13 @@ class TestTrino(Validator):
self.validate_identity("JSON_QUERY(content, 'lax $.HY.*')")
self.validate_identity("JSON_QUERY(content, 'strict $.HY.*' WITH UNCONDITIONAL WRAPPER)")
self.validate_identity("JSON_QUERY(content, 'strict $.HY.*' WITHOUT CONDITIONAL WRAPPER)")
+ self.validate_identity("JSON_QUERY(description, 'strict $.comment' KEEP QUOTES)")
+ self.validate_identity(
+ "JSON_QUERY(description, 'strict $.comment' OMIT QUOTES ON SCALAR STRING)"
+ )
+ self.validate_identity(
+ "JSON_QUERY(content, 'strict $.HY.*' WITH UNCONDITIONAL WRAPPER KEEP QUOTES)"
+ )
def test_listagg(self):
self.validate_identity(
diff --git a/tests/dialects/test_tsql.py b/tests/dialects/test_tsql.py
index e98ac10..dc35610 100644
--- a/tests/dialects/test_tsql.py
+++ b/tests/dialects/test_tsql.py
@@ -184,7 +184,7 @@ class TestTSQL(Validator):
"tsql": "CREATE TABLE #mytemptable (a INTEGER)",
"snowflake": "CREATE TEMPORARY TABLE mytemptable (a INT)",
"duckdb": "CREATE TEMPORARY TABLE mytemptable (a INT)",
- "oracle": "CREATE GLOBAL TEMPORARY TABLE mytemptable (a NUMBER)",
+ "oracle": "CREATE GLOBAL TEMPORARY TABLE mytemptable (a INT)",
"hive": "CREATE TEMPORARY TABLE mytemptable (a INT)",
"spark2": "CREATE TEMPORARY TABLE mytemptable (a INT) USING PARQUET",
"spark": "CREATE TEMPORARY TABLE mytemptable (a INT) USING PARQUET",
@@ -436,6 +436,13 @@ class TestTSQL(Validator):
"'a' + 'b'",
)
+ self.validate_identity(
+ "CREATE TABLE db.t1 (a INTEGER, b VARCHAR(50), CONSTRAINT c PRIMARY KEY (a DESC))",
+ )
+ self.validate_identity(
+ "CREATE TABLE db.t1 (a INTEGER, b INTEGER, CONSTRAINT c PRIMARY KEY (a DESC, b))"
+ )
+
def test_option(self):
possible_options = [
"HASH GROUP",
@@ -836,6 +843,7 @@ class TestTSQL(Validator):
f"UNIQUE {clustered_keyword} ([internal_id] ASC))",
)
+ self.validate_identity("CREATE SCHEMA testSchema")
self.validate_identity("CREATE VIEW t AS WITH cte AS (SELECT 1 AS c) SELECT c FROM cte")
self.validate_identity(
"ALTER TABLE tbl SET SYSTEM_VERSIONING=ON(HISTORY_TABLE=db.tbl, DATA_CONSISTENCY_CHECK=OFF, HISTORY_RETENTION_PERIOD=5 DAYS)"