1
0
Fork 0

Adding upstream version 16.2.1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-13 16:00:14 +01:00
parent 577b79f5a7
commit d61627452f
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
106 changed files with 41940 additions and 40162 deletions

View file

@ -1278,7 +1278,7 @@ class TestFunctions(unittest.TestCase):
col = SF.concat(SF.col("cola"), SF.col("colb"))
self.assertEqual("CONCAT(cola, colb)", col.sql())
col_single = SF.concat("cola")
self.assertEqual("cola", col_single.sql())
self.assertEqual("CONCAT(cola)", col_single.sql())
def test_array_position(self):
col_str = SF.array_position("cola", SF.col("colb"))

View file

@ -6,6 +6,9 @@ class TestBigQuery(Validator):
dialect = "bigquery"
def test_bigquery(self):
self.validate_identity("DATE(2016, 12, 25)")
self.validate_identity("DATE(CAST('2016-12-25 23:59:59' AS DATETIME))")
self.validate_identity("SELECT foo IN UNNEST(bar) AS bla")
self.validate_identity("SELECT * FROM x-0.a")
self.validate_identity("SELECT * FROM pivot CROSS JOIN foo")
self.validate_identity("SAFE_CAST(x AS STRING)")
@ -27,6 +30,9 @@ class TestBigQuery(Validator):
self.validate_identity("SELECT * FROM q UNPIVOT(values FOR quarter IN (b, c))")
self.validate_identity("""CREATE TABLE x (a STRUCT<values ARRAY<INT64>>)""")
self.validate_identity("""CREATE TABLE x (a STRUCT<b STRING OPTIONS (description='b')>)""")
self.validate_identity(
"DATE(CAST('2016-12-25 05:30:00+07' AS DATETIME), 'America/Los_Angeles')"
)
self.validate_identity(
"""CREATE TABLE x (a STRING OPTIONS (description='x')) OPTIONS (table_expiration_days=1)"""
)
@ -37,6 +43,19 @@ class TestBigQuery(Validator):
"CREATE TABLE IF NOT EXISTS foo AS SELECT * FROM bla EXCEPT DISTINCT (SELECT * FROM bar) LIMIT 0"
)
self.validate_all("SELECT SPLIT(foo)", write={"bigquery": "SELECT SPLIT(foo, ',')"})
self.validate_all(
"cast(x as date format 'MM/DD/YYYY')",
write={
"bigquery": "PARSE_DATE('%m/%d/%Y', x)",
},
)
self.validate_all(
"cast(x as time format 'YYYY.MM.DD HH:MI:SSTZH')",
write={
"bigquery": "PARSE_TIMESTAMP('%Y.%m.%d %I:%M:%S%z', x)",
},
)
self.validate_all("SELECT 1 AS hash", write={"bigquery": "SELECT 1 AS `hash`"})
self.validate_all('x <> ""', write={"bigquery": "x <> ''"})
self.validate_all('x <> """"""', write={"bigquery": "x <> ''"})
@ -55,11 +74,12 @@ class TestBigQuery(Validator):
"SELECT * FROM `my-project.my-dataset.my-table`",
write={"bigquery": "SELECT * FROM `my-project`.`my-dataset`.`my-table`"},
)
self.validate_all("CAST(x AS DATETIME)", read={"": "x::timestamp"})
self.validate_identity("CAST(x AS TIMESTAMP)")
self.validate_all("LEAST(x, y)", read={"sqlite": "MIN(x, y)"})
self.validate_all("CAST(x AS CHAR)", write={"bigquery": "CAST(x AS STRING)"})
self.validate_all("CAST(x AS NCHAR)", write={"bigquery": "CAST(x AS STRING)"})
self.validate_all("CAST(x AS NVARCHAR)", write={"bigquery": "CAST(x AS STRING)"})
self.validate_all("CAST(x AS TIMESTAMP)", write={"bigquery": "CAST(x AS DATETIME)"})
self.validate_all("CAST(x AS TIMESTAMPTZ)", write={"bigquery": "CAST(x AS TIMESTAMP)"})
self.validate_all("CAST(x AS RECORD)", write={"bigquery": "CAST(x AS STRUCT)"})
self.validate_all(
@ -418,9 +438,11 @@ class TestBigQuery(Validator):
self.validate_all(
"SELECT REGEXP_EXTRACT(abc, 'pattern(group)') FROM table",
write={
"bigquery": "SELECT REGEXP_EXTRACT(abc, 'pattern(group)') FROM table",
"duckdb": "SELECT REGEXP_EXTRACT(abc, 'pattern(group)', 1) FROM table",
},
)
self.validate_identity("REGEXP_EXTRACT(`foo`, 'bar: (.+?)', 1, 1)")
self.validate_identity("BEGIN A B C D E F")
self.validate_identity("BEGIN TRANSACTION")
self.validate_identity("COMMIT TRANSACTION")

View file

@ -45,7 +45,21 @@ class TestClickhouse(Validator):
self.validate_identity(
"CREATE MATERIALIZED VIEW test_view ON CLUSTER cl1 (id UInt8) ENGINE=AggregatingMergeTree() ORDER BY tuple() AS SELECT * FROM test_data"
)
self.validate_identity(
"CREATE MATERIALIZED VIEW test_view ON CLUSTER cl1 (id UInt8) TO table1 AS SELECT * FROM test_data"
)
self.validate_identity(
"CREATE MATERIALIZED VIEW test_view (id UInt8) TO db.table1 AS SELECT * FROM test_data"
)
self.validate_all(
"CONCAT(CASE WHEN COALESCE(a, '') IS NULL THEN COALESCE(a, '') ELSE CAST(COALESCE(a, '') AS TEXT) END, CASE WHEN COALESCE(b, '') IS NULL THEN COALESCE(b, '') ELSE CAST(COALESCE(b, '') AS TEXT) END)",
read={"postgres": "CONCAT(a, b)"},
)
self.validate_all(
"CONCAT(CASE WHEN a IS NULL THEN a ELSE CAST(a AS TEXT) END, CASE WHEN b IS NULL THEN b ELSE CAST(b AS TEXT) END)",
read={"mysql": "CONCAT(a, b)"},
)
self.validate_all(
r"'Enum8(\'Sunday\' = 0)'", write={"clickhouse": "'Enum8(''Sunday'' = 0)'"}
)

View file

@ -1084,6 +1084,14 @@ class TestDialect(Validator):
self.validate_identity("some.column LIKE 'foo' + another.column + 'bar'")
self.validate_all("LIKE(x, 'z')", write={"": "'z' LIKE x"})
self.validate_all(
"CONCAT(a, b, c)",
write={
"": "CONCAT(a, b, c)",
"redshift": "a || b || c",
"sqlite": "a || b || c",
},
)
self.validate_all(
"x ILIKE '%y'",
read={
@ -1177,10 +1185,21 @@ class TestDialect(Validator):
self.validate_all(
"CONCAT(a)",
write={
"mysql": "a",
"clickhouse": "a",
"presto": "a",
"trino": "a",
"tsql": "a",
},
)
self.validate_all(
"COALESCE(a, '')",
read={
"drill": "CONCAT(a)",
"duckdb": "CONCAT(a)",
"postgres": "CONCAT(a)",
"tsql": "CONCAT(a)",
},
)
self.validate_all(
"IF(x > 1, 1, 0)",
write={
@ -1276,7 +1295,7 @@ class TestDialect(Validator):
def test_limit(self):
self.validate_all(
"SELECT * FROM data LIMIT 10, 20",
write={"sqlite": "SELECT * FROM data LIMIT 10 OFFSET 20"},
write={"sqlite": "SELECT * FROM data LIMIT 20 OFFSET 10"},
)
self.validate_all(
"SELECT x FROM y LIMIT 10",

View file

@ -9,6 +9,20 @@ class TestDuckDB(Validator):
self.validate_identity("SELECT CURRENT_DATE")
self.validate_identity("SELECT CURRENT_TIMESTAMP")
self.validate_all(
"SELECT CAST('2020-01-01' AS DATE) + INTERVAL (-1) DAY",
read={"mysql": "SELECT DATE '2020-01-01' + INTERVAL -1 DAY"},
)
self.validate_all(
"SELECT INTERVAL '1 quarter'",
write={"duckdb": "SELECT (90 * INTERVAL '1' day)"},
)
self.validate_all(
"SELECT ((DATE_TRUNC('DAY', CAST(CAST(DATE_TRUNC('DAY', CURRENT_TIMESTAMP) AS DATE) AS TIMESTAMP) + INTERVAL (0 - MOD((DAYOFWEEK(CAST(CAST(DATE_TRUNC('DAY', CURRENT_TIMESTAMP) AS DATE) AS TIMESTAMP)) % 7) - 1 + 7, 7)) day) + (7 * INTERVAL (-5) day))) AS t1",
read={
"presto": "SELECT ((DATE_ADD('week', -5, DATE_TRUNC('DAY', DATE_ADD('day', (0 - MOD((DAY_OF_WEEK(CAST(CAST(DATE_TRUNC('DAY', NOW()) AS DATE) AS TIMESTAMP)) % 7) - 1 + 7, 7)), CAST(CAST(DATE_TRUNC('DAY', NOW()) AS DATE) AS TIMESTAMP)))))) AS t1",
},
)
self.validate_all(
"EPOCH(x)",
read={
@ -51,7 +65,7 @@ class TestDuckDB(Validator):
self.validate_all(
"STRPTIME(x, '%y-%-m')",
write={
"bigquery": "PARSE_TIMESTAMP('%y-%m', x)",
"bigquery": "PARSE_TIMESTAMP('%y-%-m', x)",
"duckdb": "STRPTIME(x, '%y-%-m')",
"presto": "DATE_PARSE(x, '%y-%c')",
"hive": "CAST(FROM_UNIXTIME(UNIX_TIMESTAMP(x, 'yy-M')) AS TIMESTAMP)",
@ -70,7 +84,7 @@ class TestDuckDB(Validator):
self.validate_all(
"STRPTIME(x, '%-m/%-d/%y %-I:%M %p')",
write={
"bigquery": "PARSE_TIMESTAMP('%m/%d/%y %I:%M %p', x)",
"bigquery": "PARSE_TIMESTAMP('%-m/%-d/%y %-I:%M %p', x)",
"duckdb": "STRPTIME(x, '%-m/%-d/%y %-I:%M %p')",
"presto": "DATE_PARSE(x, '%c/%e/%y %l:%i %p')",
"hive": "CAST(FROM_UNIXTIME(UNIX_TIMESTAMP(x, 'M/d/yy h:mm a')) AS TIMESTAMP)",

View file

@ -45,6 +45,8 @@ class TestMySQL(Validator):
)
def test_identity(self):
self.validate_identity("CAST(x AS ENUM('a', 'b'))")
self.validate_identity("CAST(x AS SET('a', 'b'))")
self.validate_identity("SELECT CURRENT_TIMESTAMP(6)")
self.validate_identity("x ->> '$.name'")
self.validate_identity("SELECT CAST(`a`.`b` AS INT) FROM foo")

View file

@ -26,8 +26,8 @@ class TestOracle(Validator):
self.validate_all(
"NVL(NULL, 1)",
write={
"": "COALESCE(NULL, 1)",
"oracle": "NVL(NULL, 1)",
"": "IFNULL(NULL, 1)",
},
)
self.validate_all(

View file

@ -1,3 +1,5 @@
from unittest import mock
from sqlglot import ParseError, exp, parse_one, transpile
from tests.dialects.test_dialect import Validator
@ -85,6 +87,39 @@ class TestPostgres(Validator):
read="postgres",
)
def test_unnest(self):
self.validate_identity(
"SELECT * FROM UNNEST(ARRAY[1, 2], ARRAY['foo', 'bar', 'baz']) AS x(a, b)"
)
self.validate_all(
"SELECT UNNEST(c) FROM t",
write={
"hive": "SELECT EXPLODE(c) FROM t",
"postgres": "SELECT UNNEST(c) FROM t",
"presto": "SELECT col FROM t CROSS JOIN UNNEST(c) AS _u(col)",
},
)
self.validate_all(
"SELECT UNNEST(ARRAY[1])",
write={
"hive": "SELECT EXPLODE(ARRAY(1))",
"postgres": "SELECT UNNEST(ARRAY[1])",
"presto": "SELECT col FROM UNNEST(ARRAY[1]) AS _u(col)",
},
)
@mock.patch("sqlglot.helper.logger")
def test_array_offset(self, mock_logger):
self.validate_all(
"SELECT col[1]",
write={
"hive": "SELECT col[0]",
"postgres": "SELECT col[1]",
"presto": "SELECT col[1]",
},
)
def test_postgres(self):
self.validate_identity("CAST(x AS INT4RANGE)")
self.validate_identity("CAST(x AS INT4MULTIRANGE)")
@ -540,3 +575,24 @@ class TestPostgres(Validator):
"SELECT a, LOGICAL_OR(b) FROM table GROUP BY a",
write={"postgres": "SELECT a, BOOL_OR(b) FROM table GROUP BY a"},
)
def test_string_concat(self):
self.validate_all(
"CONCAT(a, b)",
write={
"": "CONCAT(COALESCE(a, ''), COALESCE(b, ''))",
"duckdb": "CONCAT(COALESCE(a, ''), COALESCE(b, ''))",
"postgres": "CONCAT(COALESCE(a, ''), COALESCE(b, ''))",
"presto": "CONCAT(CAST(COALESCE(a, '') AS VARCHAR), CAST(COALESCE(b, '') AS VARCHAR))",
},
)
self.validate_all(
"a || b",
write={
"": "a || b",
"clickhouse": "CONCAT(CAST(a AS TEXT), CAST(b AS TEXT))",
"duckdb": "a || b",
"postgres": "a || b",
"presto": "CONCAT(CAST(a AS VARCHAR), CAST(b AS VARCHAR))",
},
)

View file

@ -440,6 +440,8 @@ class TestPresto(Validator):
)
def test_presto(self):
self.validate_identity("SELECT * FROM x OFFSET 1 LIMIT 1")
self.validate_identity("SELECT * FROM x OFFSET 1 FETCH FIRST 1 ROWS ONLY")
self.validate_identity("SELECT BOOL_OR(a > 10) FROM asd AS T(a)")
self.validate_identity("SELECT * FROM (VALUES (1))")
self.validate_identity("START TRANSACTION READ WRITE, ISOLATION LEVEL SERIALIZABLE")

View file

@ -30,6 +30,10 @@ class TestSnowflake(Validator):
self.validate_identity("SELECT CONVERT_TIMEZONE('UTC', 'America/Los_Angeles', col)")
self.validate_all("CAST(x AS CHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all(
"SELECT * FROM (VALUES (0) foo(bar))",
write={"snowflake": "SELECT * FROM (VALUES (0)) AS foo(bar)"},
)
self.validate_all("CAST(x AS CHARACTER VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all("CAST(x AS NCHAR VARYING)", write={"snowflake": "CAST(x AS VARCHAR)"})
self.validate_all(
@ -274,8 +278,8 @@ class TestSnowflake(Validator):
"SELECT TO_TIMESTAMP('2013-04-05 01:02:03')",
write={
"bigquery": "SELECT PARSE_TIMESTAMP('%Y-%m-%d %H:%M:%S', '2013-04-05 01:02:03')",
"snowflake": "SELECT TO_TIMESTAMP('2013-04-05 01:02:03', 'yyyy-mm-dd hh24:mi:ss')",
"spark": "SELECT TO_TIMESTAMP('2013-04-05 01:02:03', 'yyyy-MM-d HH:mm:ss')",
"snowflake": "SELECT TO_TIMESTAMP('2013-04-05 01:02:03', 'yyyy-mm-DD hh24:mi:ss')",
"spark": "SELECT TO_TIMESTAMP('2013-04-05 01:02:03', 'yyyy-MM-dd HH:mm:ss')",
},
)
self.validate_all(

View file

@ -138,11 +138,15 @@ class TestTeradata(Validator):
def test_cast(self):
self.validate_all(
"CAST('1992-01' AS DATE FORMAT 'YYYY-DD')",
read={
"bigquery": "CAST('1992-01' AS DATE FORMAT 'YYYY-DD')",
},
write={
"teradata": "CAST('1992-01' AS DATE FORMAT 'YYYY-DD')",
"databricks": "DATE_FORMAT('1992-01', 'YYYY-DD')",
"mysql": "DATE_FORMAT('1992-01', 'YYYY-DD')",
"spark": "DATE_FORMAT('1992-01', 'YYYY-DD')",
"": "TIME_TO_STR('1992-01', 'YYYY-DD')",
"bigquery": "PARSE_DATE('%Y-%d', '1992-01')",
"databricks": "TO_DATE('1992-01', 'yyyy-dd')",
"mysql": "STR_TO_DATE('1992-01', '%Y-%d')",
"spark": "TO_DATE('1992-01', 'yyyy-dd')",
"": "STR_TO_DATE('1992-01', '%Y-%d')",
},
)

View file

@ -1,7 +1,11 @@
SUM(1)
SUM(CASE WHEN x > 1 THEN 1 ELSE 0 END) / y
1
(1)
1.
(1.)
1.0
(1.0)
1E2
1E+2
1E-2
@ -69,6 +73,8 @@ a.B()
a['x'].C()
int.x
map.x
SELECT update
SELECT x.update
SELECT call.x
a.b.INT(1.234)
INT(x / 100)
@ -155,6 +161,7 @@ DATE(x) = DATE(y)
TIMESTAMP(DATE(x))
TIMESTAMP_TRUNC(COALESCE(time_field, CURRENT_TIMESTAMP()), DAY)
COUNT(DISTINCT CASE WHEN DATE_TRUNC(DATE(time_field), isoweek) = DATE_TRUNC(DATE(time_field2), isoweek) THEN report_id ELSE NULL END)
COUNT(a, b)
x[y - 1]
CASE WHEN SUM(x) > 3 THEN 1 END OVER (PARTITION BY x)
SUM(ROW() OVER (PARTITION BY x))
@ -224,6 +231,7 @@ SELECT SUM(x IGNORE NULLS) AS x
SELECT COUNT(x RESPECT NULLS)
SELECT TRUNCATE(a, b)
SELECT ARRAY_AGG(DISTINCT x IGNORE NULLS ORDER BY a, b DESC LIMIT 10) AS x
SELECT ARRAY_AGG(DISTINCT x IGNORE NULLS ORDER BY a, b DESC LIMIT 1, 10) AS x
SELECT ARRAY_AGG(STRUCT(x, x AS y) ORDER BY z DESC) AS x
SELECT LAST_VALUE(x IGNORE NULLS) OVER y AS x
SELECT LAG(x) OVER (ORDER BY y) AS x
@ -601,6 +609,7 @@ CREATE FUNCTION a.b.c()
CREATE INDEX abc ON t (a)
CREATE INDEX abc ON t (a, b, b)
CREATE INDEX abc ON t (a NULLS LAST)
CREATE INDEX pointloc ON points USING GIST(BOX(location, location))
CREATE UNIQUE INDEX abc ON t (a, b, b)
CREATE UNIQUE INDEX IF NOT EXISTS my_idx ON tbl (a, b)
CREATE SCHEMA x
@ -671,6 +680,7 @@ INSERT INTO x VALUES (1, 'a', 2.0), (1, 'a', 3.0), (X(), y[1], z.x)
INSERT INTO y (a, b, c) SELECT a, b, c FROM x
INSERT INTO y (SELECT 1) UNION (SELECT 2)
INSERT INTO result_table (WITH test AS (SELECT * FROM source_table) SELECT * FROM test)
INSERT INTO "tests_user" ("username", "first_name", "last_name") VALUES ('fiara', 'Fiara', 'Ironhide') RETURNING "tests_user"."id"
INSERT OVERWRITE TABLE x IF EXISTS SELECT * FROM y
INSERT OVERWRITE TABLE a.b IF EXISTS SELECT * FROM y
INSERT OVERWRITE DIRECTORY 'x' SELECT 1
@ -805,6 +815,7 @@ PRAGMA schema.synchronous = 2
PRAGMA schema.synchronous = FULL
PRAGMA schema.memory_limit = '1GB'
JSON_OBJECT()
JSON_OBJECT(*)
JSON_OBJECT('key1': 1, 'key2': TRUE)
JSON_OBJECT('id': '5', 'fld1': 'bla', 'fld2': 'bar')
JSON_OBJECT('x': NULL, 'y': 1 NULL ON NULL)
@ -820,3 +831,7 @@ SELECT PERCENTILE_CONT(x, 0.5 RESPECT NULLS) OVER ()
SELECT PERCENTILE_CONT(x, 0.5 IGNORE NULLS) OVER ()
WITH my_cte AS (SELECT 'a' AS desc) SELECT desc AS description FROM my_cte
WITH my_cte AS (SELECT 'a' AS asc) SELECT asc AS description FROM my_cte
SELECT * FROM case
SELECT * FROM schema.case
SELECT * FROM current_date
SELECT * FROM schema.current_date

View file

@ -1,5 +1,5 @@
SELECT * FROM x AS x, y AS y2;
SELECT * FROM (SELECT * FROM x AS x) AS x, (SELECT * FROM y AS y) AS y2;
SELECT * FROM (SELECT * FROM x AS x) AS x, (SELECT * FROM y AS y2) AS y2;
SELECT * FROM x AS x WHERE x = 1;
SELECT * FROM x AS x WHERE x = 1;
@ -17,7 +17,7 @@ WITH y AS (SELECT *) SELECT * FROM x AS x;
WITH y AS (SELECT *) SELECT * FROM x AS x;
WITH y AS (SELECT * FROM y AS y2 CROSS JOIN x AS z2) SELECT * FROM x AS x CROSS JOIN y as y;
WITH y AS (SELECT * FROM (SELECT * FROM y AS y) AS y2 CROSS JOIN (SELECT * FROM x AS x) AS z2) SELECT * FROM (SELECT * FROM x AS x) AS x CROSS JOIN y AS y;
WITH y AS (SELECT * FROM (SELECT * FROM y AS y2) AS y2 CROSS JOIN (SELECT * FROM x AS z2) AS z2) SELECT * FROM (SELECT * FROM x AS x) AS x CROSS JOIN y AS y;
SELECT * FROM x AS x CROSS JOIN xx AS y;
SELECT * FROM (SELECT * FROM x AS x) AS x CROSS JOIN xx AS y;

View file

@ -101,10 +101,10 @@ SELECT
"x"."a" AS "a",
SUM("y"."b") AS "sum_b"
FROM "x" AS "x"
JOIN "y" AS "y"
ON "x"."b" = "y"."b"
LEFT JOIN "_u_0" AS "_u_0"
ON "x"."b" = "_u_0"."_u_1"
JOIN "y" AS "y"
ON "x"."b" = "y"."b"
WHERE
"_u_0"."_col_0" >= 0 AND "x"."a" > 1
GROUP BY
@ -210,10 +210,10 @@ SELECT
"n"."b" AS "b",
"o"."b" AS "b"
FROM "n"
FULL JOIN "o"
ON "n"."a" = "o"."a"
JOIN "n" AS "n2"
ON "n"."a" = "n2"."a"
FULL JOIN "o"
ON "n"."a" = "o"."a"
WHERE
"o"."b" > 0;
@ -619,3 +619,30 @@ WITH "foO" AS (
SELECT
"foO"."x" AS "x"
FROM "foO" AS "foO";
# title: lateral subquery
# execute: false
# dialect: postgres
SELECT u.user_id, l.log_date
FROM users u
CROSS JOIN LATERAL (
SELECT l.log_date
FROM logs l
WHERE l.user_id = u.user_id AND l.log_date <= 100
ORDER BY l.log_date DESC NULLS LAST
LIMIT 1
) l;
SELECT
"u"."user_id" AS "user_id",
"l"."log_date" AS "log_date"
FROM "users" AS "u"
CROSS JOIN LATERAL (
SELECT
"l"."log_date"
FROM "logs" AS "l"
WHERE
"l"."log_date" <= 100 AND "l"."user_id" = "u"."user_id"
ORDER BY
"l"."log_date" DESC NULLS LAST
LIMIT 1
) AS "l";

View file

@ -25,8 +25,8 @@ SELECT x.a AS a FROM (SELECT x.a FROM x AS x WHERE x.a = 1 AND x.b = 1) AS x JOI
SELECT x.a FROM x AS x JOIN (SELECT y.a FROM y AS y) AS y ON y.a = 1 AND x.a = y.a;
SELECT x.a FROM x AS x JOIN (SELECT y.a FROM y AS y WHERE y.a = 1) AS y ON x.a = y.a AND TRUE;
SELECT x.a AS a FROM x AS x JOIN (SELECT * FROM y AS y) AS y ON y.a = 1 WHERE x.a = 1 AND x.b = 1 AND y.a = x;
SELECT x.a AS a FROM x AS x JOIN (SELECT * FROM y AS y WHERE y.a = 1) AS y ON y.a = x AND TRUE WHERE x.a = 1 AND x.b = 1 AND TRUE;
SELECT x.a AS a FROM x AS x JOIN (SELECT * FROM y AS y) AS y ON y.a = 1 WHERE x.a = 1 AND x.b = 1 AND y.a = x.a;
SELECT x.a AS a FROM x AS x JOIN (SELECT * FROM y AS y WHERE y.a = 1) AS y ON y.a = x.a AND TRUE WHERE x.a = 1 AND x.b = 1 AND TRUE;
SELECT x.a AS a FROM x AS x CROSS JOIN (SELECT * FROM y AS y) AS y WHERE x.a = 1 AND x.b = 1 AND y.a = x.a AND y.a = 1;
SELECT x.a AS a FROM x AS x JOIN (SELECT * FROM y AS y WHERE y.a = 1) AS y ON y.a = x.a AND TRUE WHERE x.a = 1 AND x.b = 1 AND TRUE AND TRUE;

View file

@ -296,6 +296,10 @@ SELECT x.b AS b FROM x AS x;
SELECT x.b FROM x JOIN y USING (b);
SELECT x.b AS b FROM x AS x JOIN y AS y ON x.b = y.b;
# execute: false
WITH cte AS (SELECT a.b.c.d.f.g FROM tbl1) SELECT g FROM (SELECT g FROM tbl2) tbl2 JOIN cte USING(g);
WITH cte AS (SELECT tbl1.a.b.c.d.f.g AS g FROM tbl1 AS tbl1) SELECT COALESCE(tbl2.g, cte.g) AS g FROM (SELECT tbl2.g AS g FROM tbl2 AS tbl2) AS tbl2 JOIN cte ON tbl2.g = cte.g;
SELECT x.b FROM x JOIN y USING (b) JOIN z USING (b);
SELECT x.b AS b FROM x AS x JOIN y AS y ON x.b = y.b JOIN z AS z ON x.b = z.b;

File diff suppressed because it is too large Load diff

View file

@ -117,12 +117,12 @@ WITH "region_2" AS (
MIN("partsupp"."ps_supplycost") AS "_col_0",
"partsupp"."ps_partkey" AS "_u_1"
FROM "partsupp_2" AS "partsupp"
CROSS JOIN "region_2" AS "region"
JOIN "nation" AS "nation"
ON "nation"."n_regionkey" = "region"."r_regionkey"
JOIN "supplier" AS "supplier"
ON "supplier"."s_suppkey" = "partsupp"."ps_suppkey"
JOIN "nation" AS "nation"
ON "supplier"."s_nationkey" = "nation"."n_nationkey"
AND "supplier"."s_suppkey" = "partsupp"."ps_suppkey"
JOIN "region_2" AS "region"
ON "nation"."n_regionkey" = "region"."r_regionkey"
GROUP BY
"partsupp"."ps_partkey"
)
@ -137,6 +137,8 @@ SELECT
"supplier"."s_comment" AS "s_comment"
FROM "part" AS "part"
CROSS JOIN "region_2" AS "region"
LEFT JOIN "_u_0" AS "_u_0"
ON "part"."p_partkey" = "_u_0"."_u_1"
JOIN "nation" AS "nation"
ON "nation"."n_regionkey" = "region"."r_regionkey"
JOIN "partsupp_2" AS "partsupp"
@ -144,8 +146,6 @@ JOIN "partsupp_2" AS "partsupp"
JOIN "supplier" AS "supplier"
ON "supplier"."s_nationkey" = "nation"."n_nationkey"
AND "supplier"."s_suppkey" = "partsupp"."ps_suppkey"
LEFT JOIN "_u_0" AS "_u_0"
ON "part"."p_partkey" = "_u_0"."_u_1"
WHERE
"part"."p_size" = 15
AND "part"."p_type" LIKE '%BRASS'
@ -294,16 +294,15 @@ JOIN "orders" AS "orders"
ON "customer"."c_custkey" = "orders"."o_custkey"
AND CAST("orders"."o_orderdate" AS DATE) < CAST('1995-01-01' AS DATE)
AND CAST("orders"."o_orderdate" AS DATE) >= CAST('1994-01-01' AS DATE)
JOIN "region" AS "region"
ON "region"."r_name" = 'ASIA'
JOIN "nation" AS "nation"
ON "nation"."n_regionkey" = "region"."r_regionkey"
JOIN "supplier" AS "supplier"
ON "customer"."c_nationkey" = "supplier"."s_nationkey"
AND "supplier"."s_nationkey" = "nation"."n_nationkey"
JOIN "lineitem" AS "lineitem"
ON "lineitem"."l_orderkey" = "orders"."o_orderkey"
AND "lineitem"."l_suppkey" = "supplier"."s_suppkey"
JOIN "nation" AS "nation"
ON "supplier"."s_nationkey" = "nation"."n_nationkey"
JOIN "region" AS "region"
ON "nation"."n_regionkey" = "region"."r_regionkey" AND "region"."r_name" = 'ASIA'
GROUP BY
"nation"."n_name"
ORDER BY
@ -373,14 +372,6 @@ order by
supp_nation,
cust_nation,
l_year;
WITH "n1" AS (
SELECT
"nation"."n_nationkey" AS "n_nationkey",
"nation"."n_name" AS "n_name"
FROM "nation" AS "nation"
WHERE
"nation"."n_name" = 'FRANCE' OR "nation"."n_name" = 'GERMANY'
)
SELECT
"n1"."n_name" AS "supp_nation",
"n2"."n_name" AS "cust_nation",
@ -393,20 +384,26 @@ JOIN "lineitem" AS "lineitem"
ON "supplier"."s_suppkey" = "lineitem"."l_suppkey"
AND CAST("lineitem"."l_shipdate" AS DATE) <= CAST('1996-12-31' AS DATE)
AND CAST("lineitem"."l_shipdate" AS DATE) >= CAST('1995-01-01' AS DATE)
JOIN "orders" AS "orders"
ON "orders"."o_orderkey" = "lineitem"."l_orderkey"
JOIN "customer" AS "customer"
ON "customer"."c_custkey" = "orders"."o_custkey"
JOIN "n1" AS "n1"
ON "supplier"."s_nationkey" = "n1"."n_nationkey"
JOIN "n1" AS "n2"
ON "customer"."c_nationkey" = "n2"."n_nationkey"
AND (
JOIN "nation" AS "n1"
ON (
"n1"."n_name" = 'FRANCE' OR "n1"."n_name" = 'GERMANY'
)
AND "supplier"."s_nationkey" = "n1"."n_nationkey"
JOIN "nation" AS "n2"
ON (
"n1"."n_name" = 'FRANCE' OR "n2"."n_name" = 'FRANCE'
)
AND (
"n1"."n_name" = 'GERMANY' OR "n2"."n_name" = 'GERMANY'
)
AND (
"n2"."n_name" = 'FRANCE' OR "n2"."n_name" = 'GERMANY'
)
JOIN "customer" AS "customer"
ON "customer"."c_nationkey" = "n2"."n_nationkey"
JOIN "orders" AS "orders"
ON "customer"."c_custkey" = "orders"."o_custkey"
AND "orders"."o_orderkey" = "lineitem"."l_orderkey"
GROUP BY
"n1"."n_name",
"n2"."n_name",
@ -460,7 +457,7 @@ SELECT
EXTRACT(year FROM CAST("orders"."o_orderdate" AS DATE)) AS "o_year",
SUM(
CASE
WHEN "nation_2"."n_name" = 'BRAZIL'
WHEN "n2"."n_name" = 'BRAZIL'
THEN "lineitem"."l_extendedprice" * (
1 - "lineitem"."l_discount"
)
@ -472,21 +469,21 @@ SELECT
FROM "part" AS "part"
JOIN "region" AS "region"
ON "region"."r_name" = 'AMERICA'
JOIN "nation" AS "nation"
ON "nation"."n_regionkey" = "region"."r_regionkey"
JOIN "customer" AS "customer"
ON "customer"."c_nationkey" = "nation"."n_nationkey"
JOIN "orders" AS "orders"
ON "orders"."o_custkey" = "customer"."c_custkey"
AND CAST("orders"."o_orderdate" AS DATE) <= CAST('1996-12-31' AS DATE)
AND CAST("orders"."o_orderdate" AS DATE) >= CAST('1995-01-01' AS DATE)
JOIN "lineitem" AS "lineitem"
ON "lineitem"."l_orderkey" = "orders"."o_orderkey"
AND "part"."p_partkey" = "lineitem"."l_partkey"
ON "part"."p_partkey" = "lineitem"."l_partkey"
JOIN "nation" AS "n1"
ON "n1"."n_regionkey" = "region"."r_regionkey"
JOIN "customer" AS "customer"
ON "customer"."c_nationkey" = "n1"."n_nationkey"
JOIN "supplier" AS "supplier"
ON "supplier"."s_suppkey" = "lineitem"."l_suppkey"
JOIN "nation" AS "nation_2"
ON "supplier"."s_nationkey" = "nation_2"."n_nationkey"
JOIN "nation" AS "n2"
ON "supplier"."s_nationkey" = "n2"."n_nationkey"
JOIN "orders" AS "orders"
ON "lineitem"."l_orderkey" = "orders"."o_orderkey"
AND "orders"."o_custkey" = "customer"."c_custkey"
AND CAST("orders"."o_orderdate" AS DATE) <= CAST('1996-12-31' AS DATE)
AND CAST("orders"."o_orderdate" AS DATE) >= CAST('1995-01-01' AS DATE)
WHERE
"part"."p_type" = 'ECONOMY ANODIZED STEEL'
GROUP BY
@ -540,13 +537,13 @@ SELECT
FROM "part" AS "part"
JOIN "lineitem" AS "lineitem"
ON "part"."p_partkey" = "lineitem"."l_partkey"
JOIN "supplier" AS "supplier"
ON "supplier"."s_suppkey" = "lineitem"."l_suppkey"
JOIN "orders" AS "orders"
ON "orders"."o_orderkey" = "lineitem"."l_orderkey"
JOIN "partsupp" AS "partsupp"
ON "partsupp"."ps_partkey" = "lineitem"."l_partkey"
AND "partsupp"."ps_suppkey" = "lineitem"."l_suppkey"
JOIN "orders" AS "orders"
ON "orders"."o_orderkey" = "lineitem"."l_orderkey"
JOIN "supplier" AS "supplier"
ON "supplier"."s_suppkey" = "lineitem"."l_suppkey"
JOIN "nation" AS "nation"
ON "supplier"."s_nationkey" = "nation"."n_nationkey"
WHERE
@ -606,14 +603,14 @@ SELECT
"customer"."c_phone" AS "c_phone",
"customer"."c_comment" AS "c_comment"
FROM "customer" AS "customer"
JOIN "nation" AS "nation"
ON "customer"."c_nationkey" = "nation"."n_nationkey"
JOIN "orders" AS "orders"
ON "customer"."c_custkey" = "orders"."o_custkey"
AND CAST("orders"."o_orderdate" AS DATE) < CAST('1994-01-01' AS DATE)
AND CAST("orders"."o_orderdate" AS DATE) >= CAST('1993-10-01' AS DATE)
JOIN "lineitem" AS "lineitem"
ON "lineitem"."l_orderkey" = "orders"."o_orderkey" AND "lineitem"."l_returnflag" = 'R'
JOIN "nation" AS "nation"
ON "customer"."c_nationkey" = "nation"."n_nationkey"
GROUP BY
"customer"."c_custkey",
"customer"."c_name",
@ -681,11 +678,11 @@ SELECT
"partsupp"."ps_partkey" AS "ps_partkey",
SUM("partsupp"."ps_supplycost" * "partsupp"."ps_availqty") AS "value"
FROM "partsupp" AS "partsupp"
CROSS JOIN "_u_0" AS "_u_0"
JOIN "supplier_2" AS "supplier"
ON "partsupp"."ps_suppkey" = "supplier"."s_suppkey"
JOIN "nation_2" AS "nation"
ON "supplier"."s_nationkey" = "nation"."n_nationkey"
CROSS JOIN "_u_0" AS "_u_0"
GROUP BY
"partsupp"."ps_partkey"
HAVING
@ -950,13 +947,13 @@ SELECT
"part"."p_size" AS "p_size",
COUNT(DISTINCT "partsupp"."ps_suppkey") AS "supplier_cnt"
FROM "partsupp" AS "partsupp"
LEFT JOIN "_u_0" AS "_u_0"
ON "partsupp"."ps_suppkey" = "_u_0"."s_suppkey"
JOIN "part" AS "part"
ON "part"."p_brand" <> 'Brand#45'
AND "part"."p_partkey" = "partsupp"."ps_partkey"
AND "part"."p_size" IN (49, 14, 23, 45, 19, 3, 36, 9)
AND NOT "part"."p_type" LIKE 'MEDIUM POLISHED%'
LEFT JOIN "_u_0" AS "_u_0"
ON "partsupp"."ps_suppkey" = "_u_0"."s_suppkey"
WHERE
"_u_0"."s_suppkey" IS NULL
GROUP BY
@ -1066,10 +1063,10 @@ SELECT
FROM "customer" AS "customer"
JOIN "orders" AS "orders"
ON "customer"."c_custkey" = "orders"."o_custkey"
JOIN "lineitem" AS "lineitem"
ON "orders"."o_orderkey" = "lineitem"."l_orderkey"
LEFT JOIN "_u_0" AS "_u_0"
ON "orders"."o_orderkey" = "_u_0"."l_orderkey"
JOIN "lineitem" AS "lineitem"
ON "orders"."o_orderkey" = "lineitem"."l_orderkey"
WHERE
NOT "_u_0"."l_orderkey" IS NULL
GROUP BY
@ -1260,10 +1257,10 @@ SELECT
"supplier"."s_name" AS "s_name",
"supplier"."s_address" AS "s_address"
FROM "supplier" AS "supplier"
JOIN "nation" AS "nation"
ON "nation"."n_name" = 'CANADA' AND "supplier"."s_nationkey" = "nation"."n_nationkey"
LEFT JOIN "_u_4" AS "_u_4"
ON "supplier"."s_suppkey" = "_u_4"."ps_suppkey"
JOIN "nation" AS "nation"
ON "nation"."n_name" = 'CANADA' AND "supplier"."s_nationkey" = "nation"."n_nationkey"
WHERE
NOT "_u_4"."ps_suppkey" IS NULL
ORDER BY
@ -1334,24 +1331,24 @@ SELECT
"supplier"."s_name" AS "s_name",
COUNT(*) AS "numwait"
FROM "supplier" AS "supplier"
JOIN "lineitem" AS "lineitem"
ON "lineitem"."l_receiptdate" > "lineitem"."l_commitdate"
AND "supplier"."s_suppkey" = "lineitem"."l_suppkey"
JOIN "orders" AS "orders"
ON "orders"."o_orderkey" = "lineitem"."l_orderkey" AND "orders"."o_orderstatus" = 'F'
JOIN "lineitem" AS "l1"
ON "l1"."l_receiptdate" > "l1"."l_commitdate"
AND "supplier"."s_suppkey" = "l1"."l_suppkey"
JOIN "nation" AS "nation"
ON "nation"."n_name" = 'SAUDI ARABIA'
AND "supplier"."s_nationkey" = "nation"."n_nationkey"
LEFT JOIN "_u_0" AS "_u_0"
ON "_u_0"."l_orderkey" = "lineitem"."l_orderkey"
ON "_u_0"."l_orderkey" = "l1"."l_orderkey"
LEFT JOIN "_u_2" AS "_u_2"
ON "_u_2"."l_orderkey" = "lineitem"."l_orderkey"
ON "_u_2"."l_orderkey" = "l1"."l_orderkey"
JOIN "orders" AS "orders"
ON "orders"."o_orderkey" = "l1"."l_orderkey" AND "orders"."o_orderstatus" = 'F'
WHERE
(
"_u_2"."l_orderkey" IS NULL
OR NOT ARRAY_ANY("_u_2"."_u_3", "_x" -> "_x" <> "lineitem"."l_suppkey")
OR NOT ARRAY_ANY("_u_2"."_u_3", "_x" -> "_x" <> "l1"."l_suppkey")
)
AND ARRAY_ANY("_u_0"."_u_1", "_x" -> "_x" <> "lineitem"."l_suppkey")
AND ARRAY_ANY("_u_0"."_u_1", "_x" -> "_x" <> "l1"."l_suppkey")
AND NOT "_u_0"."l_orderkey" IS NULL
GROUP BY
"supplier"."s_name"
@ -1430,3 +1427,4 @@ GROUP BY
SUBSTRING("customer"."c_phone", 1, 2)
ORDER BY
"cntrycode";

View file

@ -127,6 +127,16 @@ class TestBuild(unittest.TestCase):
"SELECT x FROM tbl WHERE x > 0 FOR SHARE",
"postgres",
),
(
lambda: select("x").from_("tbl").hint("repartition(100)"),
"SELECT /*+ REPARTITION(100) */ x FROM tbl",
"spark",
),
(
lambda: select("x").from_("tbl").hint("coalesce(3)", "broadcast(x)"),
"SELECT /*+ COALESCE(3), BROADCAST(x) */ x FROM tbl",
"spark",
),
(
lambda: select("x", "y").from_("tbl").group_by("x"),
"SELECT x, y FROM tbl GROUP BY x",

View file

@ -1,6 +1,7 @@
import datetime
import unittest
from datetime import date
from multiprocessing import Pool
import duckdb
import pandas as pd
@ -76,13 +77,21 @@ class TestExecutor(unittest.TestCase):
)
return expression
for i, (sql, _) in enumerate(self.sqls):
with self.subTest(f"tpch-h {i + 1}"):
a = self.cached_execute(sql)
sql = parse_one(sql).transform(to_csv).sql(pretty=True)
table = execute(sql, TPCH_SCHEMA)
b = pd.DataFrame(table.rows, columns=table.columns)
assert_frame_equal(a, b, check_dtype=False, check_index_type=False)
with Pool() as pool:
for i, table in enumerate(
pool.starmap(
execute,
(
(parse_one(sql).transform(to_csv).sql(pretty=True), TPCH_SCHEMA)
for sql, _ in self.sqls
),
)
):
with self.subTest(f"tpch-h {i + 1}"):
sql, _ = self.sqls[i]
a = self.cached_execute(sql)
b = pd.DataFrame(table.rows, columns=table.columns)
assert_frame_equal(a, b, check_dtype=False, check_index_type=False)
def test_execute_callable(self):
tables = {
@ -496,6 +505,7 @@ class TestExecutor(unittest.TestCase):
("SELECT 1", ["1"], [(1,)]),
("SELECT 1 + 2 AS x", ["x"], [(3,)]),
("SELECT CONCAT('a', 'b') AS x", ["x"], [("ab",)]),
("SELECT CONCAT('a', 1) AS x", ["x"], [("a1",)]),
("SELECT 1 AS x, 2 AS y", ["x", "y"], [(1, 2)]),
("SELECT 'foo' LIMIT 1", ["foo"], [("foo",)]),
(

View file

@ -534,6 +534,7 @@ class TestExpressions(unittest.TestCase):
self.assertIsInstance(parse_one("HLL(a)"), exp.Hll)
self.assertIsInstance(parse_one("ARRAY(time, foo)"), exp.Array)
self.assertIsInstance(parse_one("STANDARD_HASH('hello', 'sha256')"), exp.StandardHash)
self.assertIsInstance(parse_one("DATE(foo)"), exp.Date)
def test_column(self):
column = parse_one("a.b.c.d")
@ -590,7 +591,7 @@ class TestExpressions(unittest.TestCase):
unit = parse_one("timestamp_trunc(current_timestamp, week(thursday))")
self.assertIsNotNone(unit.find(exp.CurrentTimestamp))
week = unit.find(exp.Week)
self.assertEqual(week.this, exp.Var(this="thursday"))
self.assertEqual(week.this, exp.var("thursday"))
def test_identifier(self):
self.assertTrue(exp.to_identifier('"x"').quoted)
@ -601,7 +602,7 @@ class TestExpressions(unittest.TestCase):
def test_function_normalizer(self):
self.assertEqual(parse_one("HELLO()").sql(normalize_functions="lower"), "hello()")
self.assertEqual(parse_one("hello()").sql(normalize_functions="upper"), "HELLO()")
self.assertEqual(parse_one("heLLO()").sql(normalize_functions=None), "heLLO()")
self.assertEqual(parse_one("heLLO()").sql(normalize_functions=False), "heLLO()")
self.assertEqual(parse_one("SUM(x)").sql(normalize_functions="lower"), "sum(x)")
self.assertEqual(parse_one("sum(x)").sql(normalize_functions="upper"), "SUM(x)")
@ -786,7 +787,7 @@ FROM foo""",
self.assertEqual(exp.DataType.build("DECIMAL").sql(), "DECIMAL")
self.assertEqual(exp.DataType.build("BOOLEAN").sql(), "BOOLEAN")
self.assertEqual(exp.DataType.build("JSON").sql(), "JSON")
self.assertEqual(exp.DataType.build("JSONB").sql(), "JSONB")
self.assertEqual(exp.DataType.build("JSONB", dialect="postgres").sql(), "JSONB")
self.assertEqual(exp.DataType.build("INTERVAL").sql(), "INTERVAL")
self.assertEqual(exp.DataType.build("TIME").sql(), "TIME")
self.assertEqual(exp.DataType.build("TIMESTAMP").sql(), "TIMESTAMP")
@ -801,22 +802,17 @@ FROM foo""",
self.assertEqual(exp.DataType.build("GEOMETRY").sql(), "GEOMETRY")
self.assertEqual(exp.DataType.build("STRUCT").sql(), "STRUCT")
self.assertEqual(exp.DataType.build("NULLABLE").sql(), "NULLABLE")
self.assertEqual(exp.DataType.build("HLLSKETCH").sql(), "HLLSKETCH")
self.assertEqual(exp.DataType.build("HSTORE").sql(), "HSTORE")
self.assertEqual(exp.DataType.build("SUPER").sql(), "SUPER")
self.assertEqual(exp.DataType.build("SERIAL").sql(), "SERIAL")
self.assertEqual(exp.DataType.build("SMALLSERIAL").sql(), "SMALLSERIAL")
self.assertEqual(exp.DataType.build("BIGSERIAL").sql(), "BIGSERIAL")
self.assertEqual(exp.DataType.build("XML").sql(), "XML")
self.assertEqual(exp.DataType.build("UNIQUEIDENTIFIER").sql(), "UNIQUEIDENTIFIER")
self.assertEqual(exp.DataType.build("MONEY").sql(), "MONEY")
self.assertEqual(exp.DataType.build("SMALLMONEY").sql(), "SMALLMONEY")
self.assertEqual(exp.DataType.build("ROWVERSION").sql(), "ROWVERSION")
self.assertEqual(exp.DataType.build("IMAGE").sql(), "IMAGE")
self.assertEqual(exp.DataType.build("VARIANT").sql(), "VARIANT")
self.assertEqual(exp.DataType.build("OBJECT").sql(), "OBJECT")
self.assertEqual(exp.DataType.build("HLLSKETCH", dialect="redshift").sql(), "HLLSKETCH")
self.assertEqual(exp.DataType.build("HSTORE", dialect="postgres").sql(), "HSTORE")
self.assertEqual(exp.DataType.build("NULL").sql(), "NULL")
self.assertEqual(exp.DataType.build("NULL", dialect="bigquery").sql(), "NULL")
self.assertEqual(exp.DataType.build("UNKNOWN").sql(), "UNKNOWN")
self.assertEqual(exp.DataType.build("UNKNOWN", dialect="bigquery").sql(), "UNKNOWN")
self.assertEqual(exp.DataType.build("UNKNOWN", dialect="snowflake").sql(), "UNKNOWN")
self.assertEqual(exp.DataType.build("TIMESTAMP", dialect="bigquery").sql(), "TIMESTAMPTZ")
self.assertEqual(
exp.DataType.build("struct<x int>", dialect="spark").sql(), "STRUCT<x INT>"
)
def test_rename_table(self):
self.assertEqual(

View file

@ -6,17 +6,16 @@ from sqlglot.helper import name_sequence, tsort
class TestHelper(unittest.TestCase):
def test_tsort(self):
self.assertEqual(tsort({"a": []}), ["a"])
self.assertEqual(tsort({"a": ["b", "b"]}), ["b", "a"])
self.assertEqual(tsort({"a": ["b"]}), ["b", "a"])
self.assertEqual(tsort({"a": ["c"], "b": [], "c": []}), ["c", "a", "b"])
self.assertEqual(tsort({"a": set()}), ["a"])
self.assertEqual(tsort({"a": {"b"}}), ["b", "a"])
self.assertEqual(tsort({"a": {"c"}, "b": set(), "c": set()}), ["b", "c", "a"])
self.assertEqual(
tsort(
{
"a": ["b", "c"],
"b": ["c"],
"c": [],
"d": ["a"],
"a": {"b", "c"},
"b": {"c"},
"c": set(),
"d": {"a"},
}
),
["c", "b", "a", "d"],
@ -25,9 +24,9 @@ class TestHelper(unittest.TestCase):
with self.assertRaises(ValueError):
tsort(
{
"a": ["b", "c"],
"b": ["a"],
"c": [],
"a": {"b", "c"},
"b": {"a"},
"c": set(),
}
)

View file

@ -198,6 +198,15 @@ class TestOptimizer(unittest.TestCase):
self.check_file("normalize", normalize)
def test_qualify_columns(self):
self.assertEqual(
optimizer.qualify_columns.qualify_columns(
parse_one("WITH x AS (SELECT a FROM db.y) SELECT z FROM db.x"),
schema={"db": {"x": {"z": "int"}, "y": {"a": "int"}}},
infer_schema=False,
).sql(),
"WITH x AS (SELECT y.a AS a FROM db.y) SELECT x.z AS z FROM db.x",
)
self.assertEqual(
optimizer.qualify_columns.qualify_columns(
parse_one("select y from x"),
@ -544,9 +553,10 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
def test_function_annotation(self):
schema = {"x": {"cola": "VARCHAR", "colb": "CHAR"}}
sql = "SELECT x.cola || TRIM(x.colb) AS col FROM x AS x"
sql = "SELECT x.cola || TRIM(x.colb) AS col, DATE(x.colb) FROM x AS x"
concat_expr_alias = annotate_types(parse_one(sql), schema=schema).expressions[0]
expression = annotate_types(parse_one(sql), schema=schema)
concat_expr_alias = expression.expressions[0]
self.assertEqual(concat_expr_alias.type.this, exp.DataType.Type.VARCHAR)
concat_expr = concat_expr_alias.this
@ -555,6 +565,9 @@ FROM READ_CSV('tests/fixtures/optimizer/tpc-h/nation.csv.gz', 'delimiter', '|')
self.assertEqual(concat_expr.right.type.this, exp.DataType.Type.VARCHAR) # TRIM(x.colb)
self.assertEqual(concat_expr.right.this.type.this, exp.DataType.Type.CHAR) # x.colb
date_expr = expression.expressions[1]
self.assertEqual(date_expr.type.this, exp.DataType.Type.DATE)
sql = "SELECT CASE WHEN 1=1 THEN x.cola ELSE x.colb END AS col FROM x AS x"
case_expr_alias = annotate_types(parse_one(sql), schema=schema).expressions[0]

View file

@ -81,6 +81,11 @@ class TestParser(unittest.TestCase):
def test_float(self):
self.assertEqual(parse_one(".2"), parse_one("0.2"))
def test_unnest_projection(self):
expr = parse_one("SELECT foo IN UNNEST(bla) AS bar")
self.assertIsInstance(expr.selects[0], exp.Alias)
self.assertEqual(expr.selects[0].output_name, "bar")
def test_unary_plus(self):
self.assertEqual(parse_one("+15"), exp.Literal.number(15))

View file

@ -1,5 +1,6 @@
import unittest
from sqlglot.dialects import BigQuery
from sqlglot.tokens import Tokenizer, TokenType
@ -68,7 +69,8 @@ x"""
Tokenizer().tokenize("select /*")
def test_jinja(self):
tokenizer = Tokenizer()
# Check that {#, #} are treated as token delimiters, even though BigQuery overrides COMMENTS
tokenizer = BigQuery.Tokenizer()
tokens = tokenizer.tokenize(
"""

View file

@ -280,6 +280,11 @@ FROM v""",
"select * from t where ((condition = 1)/*test*/)",
"SELECT * FROM t WHERE ((condition = 1) /* test */)",
)
self.validate(
"SELECT 1 // hi this is a comment",
"SELECT 1 /* hi this is a comment */",
read="snowflake",
)
def test_types(self):
self.validate("INT 1", "CAST(1 AS INT)")

View file

@ -2,11 +2,89 @@ import time
from sqlglot.optimizer import optimize
INPUT = ""
OUTPUT = ""
NUM = 99
SCHEMA = {}
KIND = "DS"
INPUT = "/home/toby/dev/tpch/{i}.sql"
OUTPUT = "/home/toby/dev/sqlglot/tests/fixtures/optimizer/tpc-h/tpc-h.sql"
NUM = 22
SCHEMA = {
"lineitem": {
"l_orderkey": "bigint",
"l_partkey": "bigint",
"l_suppkey": "bigint",
"l_linenumber": "bigint",
"l_quantity": "double",
"l_extendedprice": "double",
"l_discount": "double",
"l_tax": "double",
"l_returnflag": "string",
"l_linestatus": "string",
"l_shipdate": "string",
"l_commitdate": "string",
"l_receiptdate": "string",
"l_shipinstruct": "string",
"l_shipmode": "string",
"l_comment": "string",
},
"orders": {
"o_orderkey": "bigint",
"o_custkey": "bigint",
"o_orderstatus": "string",
"o_totalprice": "double",
"o_orderdate": "string",
"o_orderpriority": "string",
"o_clerk": "string",
"o_shippriority": "int",
"o_comment": "string",
},
"customer": {
"c_custkey": "bigint",
"c_name": "string",
"c_address": "string",
"c_nationkey": "bigint",
"c_phone": "string",
"c_acctbal": "double",
"c_mktsegment": "string",
"c_comment": "string",
},
"part": {
"p_partkey": "bigint",
"p_name": "string",
"p_mfgr": "string",
"p_brand": "string",
"p_type": "string",
"p_size": "int",
"p_container": "string",
"p_retailprice": "double",
"p_comment": "string",
},
"supplier": {
"s_suppkey": "bigint",
"s_name": "string",
"s_address": "string",
"s_nationkey": "bigint",
"s_phone": "string",
"s_acctbal": "double",
"s_comment": "string",
},
"partsupp": {
"ps_partkey": "bigint",
"ps_suppkey": "bigint",
"ps_availqty": "int",
"ps_supplycost": "double",
"ps_comment": "string",
},
"nation": {
"n_nationkey": "bigint",
"n_name": "string",
"n_regionkey": "bigint",
"n_comment": "string",
},
"region": {
"r_regionkey": "bigint",
"r_name": "string",
"r_comment": "string",
},
}
KIND = "H"
with open(OUTPUT, "w", encoding="UTF-8") as fixture:
for i in range(NUM):
@ -17,7 +95,7 @@ with open(OUTPUT, "w", encoding="UTF-8") as fixture:
for line in file.read().split(";")[0].split("\n")
if not line.startswith("--")
)
original = original.replace("`", '"')
original = original.replace("`", '"').strip()
now = time.time()
try:
optimized = optimize(original, schema=SCHEMA)