should be it
This commit is contained in:
27
external/duckdb/test/optimizer/pushdown/distinct_from_pushdown.test
vendored
Normal file
27
external/duckdb/test/optimizer/pushdown/distinct_from_pushdown.test
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# name: test/optimizer/pushdown/distinct_from_pushdown.test
|
||||
# description: Test DISTINCT FROM pushed down into scans
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
create table test as select 'tst' as tst;
|
||||
|
||||
query I
|
||||
select * from test where tst is not distinct from 'a' or tst is not distinct from 'b';
|
||||
----
|
||||
|
||||
query I
|
||||
select * from test where tst is distinct from 'a' or tst is distinct from 'b';
|
||||
----
|
||||
tst
|
||||
|
||||
statement ok
|
||||
create table test2 as select 42 as tst;
|
||||
|
||||
query I
|
||||
select * from test2 where tst is not distinct from 12 or tst is not distinct from 13;
|
||||
----
|
||||
|
||||
query I
|
||||
select * from test2 where tst is distinct from 12 or tst is distinct from 13
|
||||
----
|
||||
42
|
||||
65
external/duckdb/test/optimizer/pushdown/filter_cannot_pushdown.test
vendored
Normal file
65
external/duckdb/test/optimizer/pushdown/filter_cannot_pushdown.test
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
# name: test/optimizer/pushdown/filter_cannot_pushdown.test
|
||||
# description: Test Filter Can Not Push Down
|
||||
# group: [pushdown]
|
||||
|
||||
# test some expressions which have side effects can not push down
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output = OPTIMIZED_ONLY;
|
||||
|
||||
query II
|
||||
explain select rnd from (select random()) as t(rnd) where rnd < 0.5;
|
||||
----
|
||||
logical_opt <REGEX>:.*rnd < 0.5.*
|
||||
|
||||
query II
|
||||
explain select * from (select rnd from (select random()) as t(rnd) where rnd < 0.5);
|
||||
----
|
||||
logical_opt <REGEX>:.*rnd < 0.5.*
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t(a integer, b integer, c integer);
|
||||
|
||||
query II
|
||||
explain select rnd, a from (select random() as rnd, a from t) where rnd < 0.3 and a > 1;
|
||||
----
|
||||
logical_opt <REGEX>:.*rnd < 0.3.*
|
||||
|
||||
query II
|
||||
explain select * from (select rnd, a from (select random() as rnd, a from t) where rnd < 0.3 and a > 1);
|
||||
----
|
||||
logical_opt <REGEX>:.*rnd < 0.3.*
|
||||
|
||||
query II
|
||||
explain select rnd, a from (select random() as rnd, a from t) where rnd < 0.3 and a > 1;
|
||||
----
|
||||
logical_opt <!REGEX>:.*a > 1.*
|
||||
|
||||
query II
|
||||
explain select rnd, a from (select random(), 2 as 'a') as t(rnd, a) where rnd < 1 and a > 0;
|
||||
----
|
||||
logical_opt <REGEX>:.*rnd < 1.0.*
|
||||
|
||||
statement ok
|
||||
create table t1 as select range as a, random() as b from range(10);
|
||||
|
||||
query II
|
||||
explain select a, b from (select random(), a, b from t1) as t(rnd, a, b) where rnd < 1 and a > 0;
|
||||
----
|
||||
logical_opt <REGEX>:.*rnd < 1.0.*
|
||||
|
||||
loop i 1 100
|
||||
|
||||
query I
|
||||
WITH combined_results AS (
|
||||
SELECT rnd > 0.5 as result FROM (SELECT random()) AS t(rnd) WHERE rnd < 0.5
|
||||
UNION ALL
|
||||
SELECT false
|
||||
)
|
||||
SELECT result
|
||||
FROM combined_results
|
||||
GROUP BY result;
|
||||
----
|
||||
False
|
||||
|
||||
endloop
|
||||
15
external/duckdb/test/optimizer/pushdown/issue_16104.test
vendored
Normal file
15
external/duckdb/test/optimizer/pushdown/issue_16104.test
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# name: test/optimizer/pushdown/issue_16104.test
|
||||
# description: Test expressions in filter preserve the order in Push Down
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output = OPTIMIZED_ONLY;
|
||||
|
||||
statement ok
|
||||
WITH random_data AS (
|
||||
SELECT random() * 2 AS col_double
|
||||
FROM generate_series(1, 100)
|
||||
)
|
||||
SELECT *
|
||||
FROM random_data
|
||||
WHERE abs(col_double) < 1 AND acos(col_double) > 0;
|
||||
18
external/duckdb/test/optimizer/pushdown/issue_16671.test
vendored
Normal file
18
external/duckdb/test/optimizer/pushdown/issue_16671.test
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# name: test/optimizer/pushdown/issue_16671.test
|
||||
# description: Test keeping alias in filter pushdown
|
||||
# group: [pushdown]
|
||||
|
||||
require json
|
||||
|
||||
statement ok
|
||||
set variable W to '{"a":[1,2], "b":[2,4]}';
|
||||
|
||||
query II
|
||||
from (values (1,2),(2,3),(3,1),(1,2),(2,3),(2,4), (3,2)) test (a,b)
|
||||
select *
|
||||
where (getvariable('W') -> '/'||alias(columns(getvariable('W').json_keys())))
|
||||
.json_contains(columns(getvariable('W').json_keys()));
|
||||
----
|
||||
1 2
|
||||
1 2
|
||||
2 4
|
||||
15
external/duckdb/test/optimizer/pushdown/issue_16863.test
vendored
Normal file
15
external/duckdb/test/optimizer/pushdown/issue_16863.test
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# name: test/optimizer/pushdown/issue_16863.test
|
||||
# description: Test right join filter lost in filter pushdown
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t1 (c1 DATE);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t1 (c1) VALUES ('2023-10-31');
|
||||
|
||||
query II
|
||||
SELECT t1.c1, (t1.c1 IS NULL)
|
||||
FROM t1 RIGHT JOIN (SELECT NULL AS col0 FROM t1) AS sub0 ON true
|
||||
WHERE (t1.c1 IS NULL);
|
||||
----
|
||||
35
external/duckdb/test/optimizer/pushdown/issue_17042.test
vendored
Normal file
35
external/duckdb/test/optimizer/pushdown/issue_17042.test
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# name: test/optimizer/pushdown/issue_17042.test
|
||||
# description: Test left join filter lost in filter pushdown
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
pragma explain_output = optimized_only
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t2(c1 INTEGER);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t0(c1 DOUBLE);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t0(c1) VALUES (0.1);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t2(c1) VALUES (2);
|
||||
|
||||
query II
|
||||
SELECT * FROM t2 LEFT JOIN t0 ON true WHERE ((t0.c1<t2.c1) IS NULL);
|
||||
----
|
||||
|
||||
statement ok
|
||||
INSERT INTO t2(c1) VALUES (NULL);
|
||||
|
||||
query II
|
||||
SELECT * FROM t2 LEFT JOIN t0 ON true WHERE ((t0.c1<t2.c1) IS NULL);
|
||||
----
|
||||
NULL 0.1
|
||||
|
||||
query II
|
||||
explain SELECT * FROM t2 LEFT JOIN t0 ON true WHERE (t0.c1 is distinct from t2.c1) and (t2.c1 > t0.c1);
|
||||
----
|
||||
logical_opt <REGEX>:.*INNER.*CAST\(c1 AS DOUBLE\) > c1.*CAST\(c1 AS DOUBLE\) IS.*DISTINCT FROM c1.*
|
||||
27
external/duckdb/test/optimizer/pushdown/issue_18202.test
vendored
Normal file
27
external/duckdb/test/optimizer/pushdown/issue_18202.test
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# name: test/optimizer/pushdown/issue_18202.test
|
||||
# description: Test join filter pushdown with join conditions reordered
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t0(c0 FLOAT , c1 CHAR);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t0 VALUES(0.001, 'WORLD');
|
||||
|
||||
statement ok
|
||||
CREATE VIEW v0(c0) AS SELECT 1522975040 FROM t0;
|
||||
|
||||
statement ok
|
||||
INSERT INTO t0 VALUES(3.14, 'ABCDE');
|
||||
|
||||
statement ok
|
||||
CREATE INDEX t0i0 ON t0(c1);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t0(c1, c0) VALUES('WORLD', 3.1415);
|
||||
|
||||
statement ok
|
||||
UPDATE t0 SET c1 = 'HELLO';
|
||||
|
||||
statement ok
|
||||
explain SELECT v0, c1 FROM t0 JOIN v0 ON((c1) < (CAST(v0.c0 AS CHAR))) WHERE (NOT((v0) = ((CASE WHEN t0.c0 THEN c1 END))));
|
||||
46
external/duckdb/test/optimizer/pushdown/issue_18603.test
vendored
Normal file
46
external/duckdb/test/optimizer/pushdown/issue_18603.test
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# name: test/optimizer/pushdown/issue_18603.test
|
||||
# description: Test filter pushdown with conflict comparison filters
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
pragma enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t0(c0 INT, c1 BOOLEAN);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t1(c0 INT);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t0(c0, c1) VALUES (0, 0);
|
||||
|
||||
statement ok
|
||||
INSERT INTO t1(c0) VALUES (1);
|
||||
|
||||
# test different order of filters
|
||||
query III
|
||||
SELECT * FROM t0 INNER JOIN t1 ON (t0.c1 > t0.c0) AND (t1.c0 > t0.c0) AND (t0.c0 < 7) AND (t0.c1 = t0.c0);
|
||||
----
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM t0 INNER JOIN t1 ON (t0.c1 > t0.c0) AND (t1.c0 > t0.c0) AND (t0.c0 < 7) AND (t0.c1 = t0.c0);
|
||||
----
|
||||
physical_plan <REGEX>:.*EMPTY_RESULT.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM t0 INNER JOIN t1 ON (t0.c1 > t0.c0) AND (t1.c0 > t0.c0) AND (t0.c0 < 7) AND (t0.c1 = t0.c0);
|
||||
----
|
||||
physical_plan <!REGEX>:.*c0 > c0.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM t0 INNER JOIN t1 ON (t0.c1 > t0.c0) AND (t1.c0 > t0.c0) AND (t0.c0 < 7) AND (t0.c1 = t0.c0);
|
||||
----
|
||||
physical_plan <!REGEX>:.*c0 < 7.*
|
||||
|
||||
query III
|
||||
SELECT * FROM t0 INNER JOIN t1 ON (t0.c1 = t0.c0) AND (t0.c1 > t0.c0) AND (t1.c0 > t0.c0) AND (t0.c0 < 7);
|
||||
----
|
||||
|
||||
query III
|
||||
SELECT * FROM t0 INNER JOIN t1 ON (t0.c1 = t0.c0) AND (t0.c0 < 7) AND (t0.c1 > t0.c0) AND (t1.c0 > t0.c0);
|
||||
----
|
||||
58
external/duckdb/test/optimizer/pushdown/issue_18653.test
vendored
Normal file
58
external/duckdb/test/optimizer/pushdown/issue_18653.test
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
# name: test/optimizer/pushdown/issue_18653.test
|
||||
# description: Performance issue with CROSS JOIN and LATERAL JOIN combined with unnest and json_each. Filter should be pushed down to reduce the joined rows
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
create table test_table as
|
||||
select s.i as id, [1, 2, 3]::bigint[] as values from generate_series(1, 1000000) as s(i);
|
||||
|
||||
statement ok
|
||||
create index test_table_id_idx on test_table(id);
|
||||
|
||||
query II
|
||||
explain analyze
|
||||
select id, value
|
||||
from test_table
|
||||
cross join unnest(values) as values(value) where id = 87100;
|
||||
----
|
||||
analyzed_plan <REGEX>:.*LEFT_DELIM_JOIN.*FILTER.*
|
||||
|
||||
query II
|
||||
select id, value
|
||||
from test_table
|
||||
cross join unnest(values) as values(value) where id = 87100;
|
||||
----
|
||||
87100 3
|
||||
87100 2
|
||||
87100 1
|
||||
|
||||
query II
|
||||
explain analyze
|
||||
select id, value
|
||||
from test_table t
|
||||
left join lateral unnest(t.values) as value on true
|
||||
where id = 87100;
|
||||
----
|
||||
analyzed_plan <REGEX>:.*LEFT_DELIM_JOIN.*FILTER.*
|
||||
|
||||
require json
|
||||
|
||||
statement ok
|
||||
create table test_table2 as
|
||||
select s.i as id, '{"key1": 1, "key2": 2, "key3": 3}'::JSON as values
|
||||
from generate_series(1, 1000000) as s(i);
|
||||
|
||||
statement ok
|
||||
create index test_table2_id_idx on test_table2(id);
|
||||
|
||||
query II
|
||||
explain analyze
|
||||
select t.id, key, value
|
||||
from test_table2 t
|
||||
cross join json_each(t.values) as kv(key, value)
|
||||
where t.id = 87100;
|
||||
----
|
||||
analyzed_plan <REGEX>:.*LEFT_DELIM_JOIN.*Filters:.*id=87100.*
|
||||
21
external/duckdb/test/optimizer/pushdown/join_filter_pushdown.test
vendored
Normal file
21
external/duckdb/test/optimizer/pushdown/join_filter_pushdown.test
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# name: test/optimizer/pushdown/join_filter_pushdown.test
|
||||
# description: Test sampling of larger relations
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t1 AS FROM VALUES
|
||||
('619d9199-bc25-41d7-803e-1fa801b4b952'::UUID, NULL::VARCHAR),
|
||||
('1ada8361-c20b-4e9f-9c8e-15689039cc75'::UUID, '91'::VARCHAR),
|
||||
('f5a8a7d8-6bc5-4337-a296-d52078156051'::UUID, NULL::VARCHAR) t(s, i);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t2 as from values
|
||||
('Int'),
|
||||
('91'),
|
||||
('13',),
|
||||
('sst',) t(v);
|
||||
|
||||
statement ok
|
||||
SELECT t1.s
|
||||
FROM t1
|
||||
LEFT JOIN t2 ON t1.i = t2.v;
|
||||
101
external/duckdb/test/optimizer/pushdown/no_mark_to_semi_if_mark_index_is_projected.test
vendored
Normal file
101
external/duckdb/test/optimizer/pushdown/no_mark_to_semi_if_mark_index_is_projected.test
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
# name: test/optimizer/pushdown/no_mark_to_semi_if_mark_index_is_projected.test
|
||||
# description: No mark to semi conversion if the mark join index is projected
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
CREATE OR REPLACE TABLE BaseData AS (
|
||||
SELECT
|
||||
'10' AS my_key,
|
||||
'20' AS parent_key,
|
||||
'30' AS payload,
|
||||
'40' as foo,
|
||||
'50' as foo2,
|
||||
'60' as foo3
|
||||
);
|
||||
|
||||
|
||||
# Original query
|
||||
query III
|
||||
WITH
|
||||
Example AS (
|
||||
SELECT
|
||||
c.my_key,
|
||||
(c.parent_key IN (SELECT my_key FROM BaseData)) AS parentExists,
|
||||
p.my_key IS NOT NULL AS parentExists2,
|
||||
FROM BaseData AS c
|
||||
LEFT JOIN BaseData AS p ON c.parent_key = p.my_key
|
||||
)
|
||||
SELECT *
|
||||
FROM Example
|
||||
WHERE parentExists
|
||||
----
|
||||
|
||||
# original query no CTE
|
||||
query III
|
||||
SELECT
|
||||
c.my_key,
|
||||
(c.parent_key IN (SELECT my_key FROM BaseData)) AS parentExists,
|
||||
p.my_key IS NOT NULL AS parentExists2,
|
||||
FROM BaseData AS c
|
||||
LEFT JOIN BaseData AS p ON c.parent_key = p.my_key
|
||||
WHERE parentExists;
|
||||
----
|
||||
|
||||
# original query but the CTE is a subquery
|
||||
query III
|
||||
SELECT *
|
||||
FROM (SELECT
|
||||
c.my_key,
|
||||
(c.parent_key IN (SELECT my_key FROM BaseData)) AS parentExists,
|
||||
p.my_key IS NOT NULL AS parentExists2,
|
||||
FROM BaseData AS c
|
||||
LEFT JOIN BaseData AS p ON c.parent_key = p.my_key
|
||||
)
|
||||
WHERE parentExists;
|
||||
----
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output='optimized_only'
|
||||
|
||||
query II
|
||||
EXPLAIN
|
||||
WITH Example AS (
|
||||
SELECT
|
||||
c.my_key,
|
||||
(c.parent_key IN (SELECT my_key FROM BaseData)) AS parentExists,
|
||||
p.my_key IS NOT NULL AS parentExists2,
|
||||
FROM BaseData AS c
|
||||
LEFT JOIN BaseData AS p ON c.parent_key = p.my_key
|
||||
)
|
||||
SELECT *
|
||||
FROM Example
|
||||
WHERE parentExists
|
||||
----
|
||||
logical_opt <REGEX>:.*MARK.*
|
||||
|
||||
query II
|
||||
EXPLAIN
|
||||
WITH Example AS (
|
||||
SELECT
|
||||
c.my_key,
|
||||
(c.parent_key IN (SELECT my_key FROM BaseData)) AS parentExists,
|
||||
p.my_key IS NOT NULL AS parentExists2,
|
||||
FROM BaseData AS c
|
||||
LEFT JOIN BaseData AS p ON c.parent_key = p.my_key
|
||||
)
|
||||
SELECT *
|
||||
FROM Example
|
||||
WHERE parentExists
|
||||
----
|
||||
logical_opt <!REGEX>:.*SEMI.*
|
||||
|
||||
statement ok
|
||||
create table t0 as select range a from range(300);
|
||||
|
||||
statement ok
|
||||
create table t2 as select range b from range(50000);
|
||||
|
||||
query I
|
||||
select sum(in_alias::INT) FROM (select a in (select b from t2) as in_alias from t0) where in_alias;
|
||||
----
|
||||
300
|
||||
66
external/duckdb/test/optimizer/pushdown/parquet_or_pushdown.test
vendored
Normal file
66
external/duckdb/test/optimizer/pushdown/parquet_or_pushdown.test
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# name: test/optimizer/pushdown/parquet_or_pushdown.test
|
||||
# description: Test Parquet With Pushing Down of OR Filters
|
||||
# group: [pushdown]
|
||||
|
||||
require parquet
|
||||
|
||||
# FIXME: re-enable when or pushdown is fixed
|
||||
mode skip
|
||||
|
||||
# Multiple column in the root OR node, don't push down
|
||||
query II
|
||||
EXPLAIN SELECT tbl.a, tbl.b FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a, b) WHERE a=1 OR b=false
|
||||
----
|
||||
physical_plan <!REGEX>:.*PARQUET_SCAN.*Filters:.*
|
||||
|
||||
|
||||
# Single column in the root OR node
|
||||
query II
|
||||
EXPLAIN SELECT tbl.a FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a) WHERE a=1 OR a=2
|
||||
----
|
||||
physical_plan <REGEX>:.*PARQUET_SCAN.*Filters: a=1 OR a=2.*
|
||||
|
||||
# Single column + root OR node with AND
|
||||
query II
|
||||
EXPLAIN SELECT tbl.a FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a) WHERE a=1 OR (a>3 AND a<5)
|
||||
----
|
||||
physical_plan <REGEX>:.*PARQUET_SCAN.*Filters: a=1 OR a>3 AND a<5|.*
|
||||
|
||||
|
||||
# Single column multiple ORs
|
||||
query II
|
||||
EXPLAIN SELECT tbl.a FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a) WHERE a=1 OR a>3 OR a<5
|
||||
----
|
||||
physical_plan <REGEX>:.*PARQUET_SCAN.*Filters: a=1 OR a>3 OR a<5|.*
|
||||
|
||||
|
||||
|
||||
# Testing not equal
|
||||
query II
|
||||
EXPLAIN SELECT tbl.a FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a) WHERE a!=1 OR a>3 OR a<2
|
||||
----
|
||||
physical_plan <REGEX>:.*PARQUET_SCAN.*Filters: a!=1 OR a>3 OR a<2|.*
|
||||
|
||||
|
||||
# Multiple OR filters connected with ANDs
|
||||
query II
|
||||
EXPLAIN SELECT tbl.a, tbl.b, tbl.c FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a,b,c) WHERE (a<2 OR a>3) AND (a=1 OR a=4) AND (b=false OR c=1);
|
||||
----
|
||||
physical_plan <REGEX>:.*PARQUET_SCAN.*Filters: a<2 OR a>3 AND a=1.*OR a=4.*
|
||||
|
||||
|
||||
# Testing the number of rows filtered (column "a" has eight values: 0 .. 7)
|
||||
statement ok
|
||||
PRAGMA enable_profiling
|
||||
|
||||
# should return 2 rows: 0 and 7
|
||||
query II
|
||||
EXPLAIN ANALYZE SELECT tbl.a FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a) WHERE a<1 OR a>6;
|
||||
----
|
||||
analyzed_plan <REGEX>:.*PARQUET_SCAN.*Filters: a<1 OR a>6.*2[ \t].*
|
||||
|
||||
# should return 1 row: 0
|
||||
query II
|
||||
EXPLAIN ANALYZE SELECT tbl.a FROM "data/parquet-testing/arrow/alltypes_plain.parquet" tbl(a) WHERE a<1 OR a>8;
|
||||
----
|
||||
analyzed_plan <REGEX>:.*PARQUET_SCAN.*Filters: a<1 OR a>8.*1[ \t].*
|
||||
42
external/duckdb/test/optimizer/pushdown/pushdown_after_statistics.test
vendored
Normal file
42
external/duckdb/test/optimizer/pushdown/pushdown_after_statistics.test
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# name: test/optimizer/pushdown/pushdown_after_statistics.test
|
||||
# description: Test Table Filter Push Down
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
set explain_output='optimized_only';
|
||||
|
||||
|
||||
statement ok
|
||||
create table big_probe as select range%3000 a, range%4000 b from range(100000);
|
||||
|
||||
statement ok
|
||||
create table into_semi as select range%300 c from range(10000);
|
||||
|
||||
statement ok
|
||||
create table into_get as select range d from range(100);
|
||||
|
||||
|
||||
# the IN filter becomes a mark join. We should keep it a mark join at this point
|
||||
query II
|
||||
explain select * from big_probe, into_semi, into_get where c in (1, 3, 5, 7, 10, 14, 16, 20, 22) and c = d and a = c;
|
||||
----
|
||||
logical_opt <REGEX>:.*MARK.*
|
||||
|
||||
|
||||
statement ok
|
||||
create table mark_join_build as select range e from range(200);
|
||||
|
||||
# Now the in filter is a semi join.
|
||||
query II
|
||||
explain select * from big_probe, into_semi, into_get where c in (select e from mark_join_build) and c = d and a = c;
|
||||
----
|
||||
logical_opt <REGEX>:.*SEMI.*
|
||||
|
||||
|
||||
statement ok
|
||||
select t1.a from big_probe t1
|
||||
where t1.a in
|
||||
(select t2.b
|
||||
from big_probe t2
|
||||
where t2.b in (1206, 1202, 1322, 1204, 1370)
|
||||
and t2.b not in (select t2_filter.a from big_probe t2_filter));
|
||||
181
external/duckdb/test/optimizer/pushdown/pushdown_filter_on_coalesced_equal_outer_join_keys.test
vendored
Normal file
181
external/duckdb/test/optimizer/pushdown/pushdown_filter_on_coalesced_equal_outer_join_keys.test
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
# name: test/optimizer/pushdown/pushdown_filter_on_coalesced_equal_outer_join_keys.test
|
||||
# description: Test pushdown of filters on coalesced join keys compared for equality in the join condition
|
||||
# group: [pushdown]
|
||||
|
||||
# enable query verification
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t1 AS FROM VALUES
|
||||
(1),
|
||||
(2),
|
||||
(NULL),
|
||||
(4) t(id);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t2 AS FROM VALUES
|
||||
(1),
|
||||
(3),
|
||||
(NULL),
|
||||
(4) t(id);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t3 AS FROM VALUES
|
||||
(1),
|
||||
(3),
|
||||
(NULL),
|
||||
(4) t(id);
|
||||
|
||||
query I
|
||||
SELECT id FROM t1 FULL OUTER JOIN t2 USING (id) WHERE id >=2 ORDER BY id
|
||||
----
|
||||
2
|
||||
3
|
||||
4
|
||||
|
||||
# should find all NULL rows correctly
|
||||
query I
|
||||
SELECT id FROM t1 FULL OUTER JOIN t2 USING (id) WHERE id IS NULL
|
||||
----
|
||||
NULL
|
||||
NULL
|
||||
|
||||
statement ok
|
||||
set explain_output='optimized_only';
|
||||
|
||||
# optimized plan is equivalent to plan with manually pushed down filter
|
||||
query II nosort single_join
|
||||
EXPLAIN SELECT id
|
||||
FROM (SELECT id FROM t1) FULL OUTER JOIN (SELECT id FROM t2) USING (id)
|
||||
WHERE id >= 2
|
||||
----
|
||||
|
||||
query II nosort single_join
|
||||
EXPLAIN SELECT id
|
||||
FROM (SELECT id FROM t1 WHERE id >= 2) FULL OUTER JOIN (SELECT id FROM t2 WHERE id >= 2) USING (id)
|
||||
----
|
||||
|
||||
# optimized plan is equivalent to plan with manually pushed down filter when using IS NULL as a filtering predicate
|
||||
query II nosort single_join_isnull_filter
|
||||
EXPLAIN SELECT id
|
||||
FROM (SELECT id FROM t1) FULL OUTER JOIN (SELECT id FROM t2) USING (id)
|
||||
WHERE id IS NULL
|
||||
----
|
||||
|
||||
query II nosort single_join_isnull_filter
|
||||
EXPLAIN SELECT id
|
||||
FROM (SELECT id FROM t1 WHERE id IS NULL) FULL OUTER JOIN (SELECT id FROM t2 WHERE id IS NULL) USING (id)
|
||||
----
|
||||
|
||||
# optimized plan is equivalent to plan with manually pushed down filter in the case of multiple joins
|
||||
query II nosort multiple_joins
|
||||
EXPLAIN SELECT id
|
||||
FROM (SELECT id FROM t1) FULL OUTER JOIN (SELECT id FROM t2) USING (id) FULL OUTER JOIN (SELECT id FROM t3) USING (id) WHERE id >= 2;
|
||||
----
|
||||
|
||||
query II nosort multiple_joins
|
||||
EXPLAIN SELECT id
|
||||
FROM (SELECT id FROM t1 WHERE id >= 2)
|
||||
FULL OUTER JOIN (SELECT id FROM t2 WHERE id >= 2) USING (id)
|
||||
FULL OUTER JOIN (SELECT id FROM t3 WHERE id >= 2) USING (id);
|
||||
----
|
||||
|
||||
# should pushdown filter with multiple occurrences of the same coalesced join keys
|
||||
query II nosort multiple_occurrences_of_the_same_coalesced_join_keys
|
||||
EXPLAIN
|
||||
SELECT id FROM (SELECT id FROM t1) FULL OUTER JOIN (SELECT id FROM t2) USING (id)
|
||||
WHERE id >= 2 OR id IN (1, 4) OR id IS NULL;
|
||||
----
|
||||
|
||||
query II nosort multiple_occurrences_of_the_same_coalesced_join_keys
|
||||
EXPLAIN SELECT id
|
||||
FROM (SELECT id FROM t1 WHERE id >= 2 OR id IN (1, 4) OR id IS NULL)
|
||||
FULL OUTER JOIN (SELECT id FROM t2 WHERE id >= 2 OR id IN (1, 4) OR id IS NULL)
|
||||
USING (id);
|
||||
----
|
||||
|
||||
# should pushdown filter containing different but equivalent coalesced join keys
|
||||
query II
|
||||
EXPLAIN SELECT t1.id, t2.id
|
||||
FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id
|
||||
WHERE COALESCE(t1.id, t2.id) >= 2 OR COALESCE(t2.id, t1.id) IS NULL;
|
||||
----
|
||||
logical_opt <REGEX>:.*SEQ_SCAN.*Filters.*\(id >= 2\) OR \(id IS NULL\).*
|
||||
|
||||
# should not pushdown a volatile filter
|
||||
query II
|
||||
EXPLAIN SELECT id
|
||||
FROM t1 FULL OUTER JOIN t2 USING (id)
|
||||
WHERE trunc(random() * id) >= 2
|
||||
----
|
||||
logical_opt <!REGEX>:.*SEQ_SCAN.*Filters.*
|
||||
|
||||
# coalescing right and left is optimized like coalescing left and right
|
||||
query II nosort left_right_coalesce
|
||||
EXPLAIN SELECT t1.id, t2.id
|
||||
FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id
|
||||
WHERE COALESCE(t1.id, t2.id) >= 2;
|
||||
----
|
||||
|
||||
query II nosort left_right_coalesce
|
||||
EXPLAIN SELECT t1.id, t2.id
|
||||
FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id
|
||||
WHERE COALESCE(t2.id, t1.id) >= 2;
|
||||
----
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t4 AS FROM VALUES
|
||||
(1, 20),
|
||||
(2, NULL),
|
||||
(3, 16)
|
||||
t(id, a);
|
||||
|
||||
statement ok
|
||||
CREATE TABLE t5 AS FROM VALUES
|
||||
(1, NULL),
|
||||
(1, 30)
|
||||
t(id, a);
|
||||
|
||||
# should not pushdown filter on coalesced keys that also depend on other columns
|
||||
query II
|
||||
EXPLAIN SELECT id FROM t1 FULL OUTER JOIN t4 USING (id) WHERE id = a;
|
||||
----
|
||||
logical_opt <!REGEX>:.*SEQ_SCAN.*Filters.*
|
||||
|
||||
# should not pushdown single filter containing coalesced keys from different join conditions
|
||||
query II
|
||||
EXPLAIN SELECT id FROM t4 FULL OUTER JOIN t5 USING (id, a) WHERE id IN (a, 1)
|
||||
----
|
||||
logical_opt <!REGEX>:.*SEQ_SCAN.*Filters.*
|
||||
|
||||
query II nosort nullif_func_join_keys
|
||||
EXPLAIN SELECT *
|
||||
FROM (SELECT id, a FROM t4 WHERE nullif(id, a) < 3) AS t4
|
||||
FULL OUTER JOIN (SELECT id, a FROM t5 WHERE nullif(id, a) < 3) AS t5
|
||||
ON nullif(t4.id, t4.a) = nullif(t5.id, t5.a)
|
||||
----
|
||||
|
||||
# should pushdown filter containing coalesced keys which are functions of the input table
|
||||
query II nosort nullif_func_join_keys
|
||||
EXPLAIN SELECT *
|
||||
FROM (SELECT id, a FROM t4) AS t4
|
||||
FULL OUTER JOIN (SELECT id, a FROM t5) AS t5
|
||||
ON nullif(t4.id, t4.a) = nullif(t5.id, t5.a)
|
||||
WHERE coalesce(nullif(t4.id, t4.a), nullif(t5.id, t5.a)) < 3;
|
||||
----
|
||||
|
||||
query II nosort list_func_join_keys
|
||||
EXPLAIN SELECT * FROM
|
||||
(SELECT id, a FROM t4) AS t4
|
||||
FULL OUTER JOIN (SELECT id, a FROM t5) AS t5
|
||||
ON [t4.id, t4.a] = [t5.id, t5.a]
|
||||
WHERE coalesce([t4.id, t4.a], [t5.id, t5.a])[0] < 4;
|
||||
----
|
||||
|
||||
query II nosort list_func_join_keys
|
||||
EXPLAIN SELECT * FROM
|
||||
(SELECT id, a FROM t4, WHERE [id, a][0] < 4) AS t4
|
||||
FULL OUTER JOIN (SELECT id, a FROM t5 WHERE [id, a][0] < 4) AS t5
|
||||
ON [t4.id, t4.a] = [t5.id, t5.a]
|
||||
----
|
||||
25
external/duckdb/test/optimizer/pushdown/pushdown_in_to_parquet.test
vendored
Normal file
25
external/duckdb/test/optimizer/pushdown/pushdown_in_to_parquet.test
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# name: test/optimizer/pushdown/pushdown_in_to_parquet.test
|
||||
# description: Parquet filter of IN with 1 argument can be converted to =
|
||||
# group: [pushdown]
|
||||
|
||||
require parquet
|
||||
|
||||
statement ok
|
||||
PRAGMA enable_verification
|
||||
|
||||
statement ok
|
||||
create table t1 as select range::VARCHAR a from range(1000);
|
||||
|
||||
statement ok
|
||||
copy t1 to '__TEST_DIR__/t1.parquet' (FORMAT PARQUET);
|
||||
|
||||
query II
|
||||
explain select * from '__TEST_DIR__/t1.parquet' where a in ('400');
|
||||
----
|
||||
physical_plan <!REGEX>:.*FILTER.*PARQUET_SCAN.*
|
||||
|
||||
query II
|
||||
explain select * from '__TEST_DIR__/t1.parquet' where a in ('400');
|
||||
----
|
||||
physical_plan <REGEX>:.*PARQUET_SCAN.*Filters:.*
|
||||
|
||||
31
external/duckdb/test/optimizer/pushdown/pushdown_unnest_into_cte.test
vendored
Normal file
31
external/duckdb/test/optimizer/pushdown/pushdown_unnest_into_cte.test
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# name: test/optimizer/pushdown/pushdown_unnest_into_cte.test
|
||||
# description: Parquet filter of IN with 1 argument can be converted to =
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tbl2 as SELECT i as id1, [i-3, i+1, i+2] as somelist FROM generate_series(1, 10_000) s(i);
|
||||
|
||||
statement ok
|
||||
pragma explain_output='OPTIMIZED_ONLY';
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT id1, element
|
||||
FROM (
|
||||
SELECT id1, UNNEST(somelist) AS element
|
||||
FROM tbl2
|
||||
) tmp
|
||||
WHERE id1=10;
|
||||
----
|
||||
logical_opt <REGEX>:.*UNNEST.*SEQ_SCAN.*Filters.*
|
||||
|
||||
|
||||
query II
|
||||
EXPLAIN WITH tmp AS (
|
||||
SELECT id1, generate_subscripts(somelist, 1) AS index, UNNEST(somelist) AS element
|
||||
FROM tbl2
|
||||
)
|
||||
SELECT id1, index, element
|
||||
FROM tmp
|
||||
WHERE id1=10;
|
||||
----
|
||||
logical_opt <REGEX>:.*UNNEST.*SEQ_SCAN.*Filters.*
|
||||
150
external/duckdb/test/optimizer/pushdown/pushdown_window_partition_filter.test
vendored
Normal file
150
external/duckdb/test/optimizer/pushdown/pushdown_window_partition_filter.test
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
# name: test/optimizer/pushdown/pushdown_window_partition_filter.test
|
||||
# description: Test pushdown of filters through window operators that are partitioned by.
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
create table t1 as from VALUES
|
||||
('A', 1),
|
||||
('B', 3),
|
||||
('C', 12),
|
||||
('A', 5),
|
||||
('B', 8),
|
||||
('C', 9),
|
||||
('A', 10),
|
||||
('B', 20),
|
||||
('C', 3)
|
||||
t(a, b);
|
||||
|
||||
statement ok
|
||||
pragma explain_output=OPTIMIZED_ONLY
|
||||
|
||||
statement ok
|
||||
create view window_with_filter as select a, b, LEAD(b) OVER (partition by a) as lead from t1 where a != 'C';
|
||||
|
||||
statement ok
|
||||
create view window_no_filter as select a, b, LEAD(b) OVER (partition by a) as lead from t1;
|
||||
|
||||
query III no_sort result_1
|
||||
select * from window_with_filter where a != 'C' order by all;
|
||||
----
|
||||
|
||||
query III no_sort result_1
|
||||
select * from window_no_filter where a != 'C' order by all;
|
||||
----
|
||||
|
||||
statement ok
|
||||
create table partition_and_rank_me as from values
|
||||
('A', 10, 'A', 'id'),
|
||||
('A', 20, 'A', 'id'),
|
||||
('A', 30, 'B', 'id'),
|
||||
('D', 40, 'B', 'id'),
|
||||
('D', 50, 'C', 'id'),
|
||||
('D', 60, 'C', 'id')
|
||||
t(a, b, c, d);
|
||||
|
||||
query IIII
|
||||
select a, c, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY d ORDER BY b)
|
||||
from partition_and_rank_me order by all
|
||||
----
|
||||
A A 30 1
|
||||
A A 30 2
|
||||
A B 70 3
|
||||
D B 70 4
|
||||
D C 110 5
|
||||
D C 110 6
|
||||
|
||||
# can't push down the filter c!='B', since the values of the rank() window function
|
||||
# are affected by the existence of the rows where c='B'
|
||||
query IIII
|
||||
select * from (
|
||||
select a, c, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY d ORDER BY b)
|
||||
from partition_and_rank_me
|
||||
) where c != 'B' order by all;
|
||||
----
|
||||
A A 30 1
|
||||
A A 30 2
|
||||
D C 110 5
|
||||
D C 110 6
|
||||
|
||||
# One filter clause is on the partitioned column but the filter clause is an AND conjunction, so we don't push that down.
|
||||
query IIII
|
||||
select * from (
|
||||
select a, c, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY c ORDER BY b)
|
||||
from partition_and_rank_me
|
||||
) where (c = 'B' AND a = 'D') order by all;
|
||||
----
|
||||
D B 70 2
|
||||
|
||||
# result of above query with pushdown
|
||||
query IIII
|
||||
select * from (
|
||||
select a, c, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY c ORDER BY b)
|
||||
from partition_and_rank_me where (c = 'B' AND a = 'D')
|
||||
) order by all;
|
||||
----
|
||||
D B 40 1
|
||||
|
||||
|
||||
# The filter is on the partitioned column, but is part of an OR conjunction, so we can push it down
|
||||
query IIII
|
||||
select * from (
|
||||
select a, c, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY c ORDER BY b)
|
||||
from partition_and_rank_me
|
||||
) where (c = 'B' OR a = 'D') order by all;
|
||||
----
|
||||
A B 70 1
|
||||
D B 70 2
|
||||
D C 110 1
|
||||
D C 110 2
|
||||
|
||||
# result of above query with pushdown
|
||||
query IIII
|
||||
select * from (
|
||||
select a, c, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY c ORDER BY b)
|
||||
from partition_and_rank_me
|
||||
where (c = 'B' OR a = 'D')
|
||||
) order by all;
|
||||
----
|
||||
A B 70 1
|
||||
D B 70 2
|
||||
D C 110 1
|
||||
D C 110 2
|
||||
|
||||
# The filter is a function expression, so we don't push it down
|
||||
query IIII
|
||||
select * from (
|
||||
select a, c, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY c ORDER BY b)
|
||||
from partition_and_rank_me
|
||||
) where (c || 'Z' = 'BZ') order by all;
|
||||
----
|
||||
A B 70 1
|
||||
D B 70 2
|
||||
|
||||
|
||||
# can't push down the filter c!='B', since the values of the rank() window function
|
||||
# are affected by the existence of the rows where c='B'
|
||||
query II
|
||||
explain select * from (select a, sum(b) OVER (PARTITION BY c), rank() OVER (PARTITION BY d ORDER BY b), c from partition_and_rank_me) where c != 'B' order by all;
|
||||
----
|
||||
logical_opt <REGEX>:.*FILTER.*WINDOW.*
|
||||
|
||||
query II
|
||||
explain select * from window_no_filter where a != 'C' order by a;
|
||||
----
|
||||
logical_opt <REGEX>:.*WINDOW.*Filters.*
|
||||
|
||||
statement ok
|
||||
create table t2 as select range a, range%50 b, range%25 c from range(500);
|
||||
|
||||
# second window expression is not paritioned on b, so filter expression cannot be
|
||||
# pushed down
|
||||
query II
|
||||
explain select * from (select a, b, c, sum(a) OVER (PARTITION BY b, c), sum(b) OVER (PARTITION BY a, c) from t2) where b > 25;
|
||||
----
|
||||
logical_opt <REGEX>:.*FILTER.*WINDOW.*
|
||||
|
||||
query II
|
||||
explain select * from (select a, b, c, sum(a) OVER (PARTITION BY b, c), sum(b) OVER (PARTITION BY a, c) from t2) where c = 20;
|
||||
----
|
||||
logical_opt <REGEX>:.*WINDOW.*c=20.*
|
||||
|
||||
217
external/duckdb/test/optimizer/pushdown/table_filter_pushdown.test
vendored
Normal file
217
external/duckdb/test/optimizer/pushdown/table_filter_pushdown.test
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
# name: test/optimizer/pushdown/table_filter_pushdown.test
|
||||
# description: Test Table Filter Push Down
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers(i integer, j integer, k integer)
|
||||
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (5, 5, 5), (10, 10, 10)
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output = OPTIMIZED_ONLY;
|
||||
|
||||
# complex filter cannot be entirely pushed down
|
||||
query II
|
||||
EXPLAIN SELECT k FROM integers where i+j > 10 and j = 5 and i = k+1
|
||||
----
|
||||
logical_opt <REGEX>:.*FILTER.*
|
||||
|
||||
# simple filter is pushed down: no filter remaining
|
||||
query II
|
||||
EXPLAIN SELECT k FROM integers where j=5
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
# complex filters are also pushed down
|
||||
query I
|
||||
SELECT k FROM integers where j::VARCHAR SIMILAR TO '[0-9]*'
|
||||
----
|
||||
5
|
||||
10
|
||||
|
||||
# multiple filters pushed down
|
||||
query II
|
||||
EXPLAIN SELECT k FROM integers where j = 5 and i = 10
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
# complex filter is pushed down: no filter remaining
|
||||
query II
|
||||
EXPLAIN SELECT k FROM integers where j::VARCHAR SIMILAR TO '[0-9]*'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
# we cannot push down expressions that can throw errors
|
||||
query I
|
||||
SELECT k FROM integers where j%50=j
|
||||
----
|
||||
5
|
||||
10
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT k FROM integers where j%50=j
|
||||
----
|
||||
logical_opt <REGEX>:.*FILTER.*
|
||||
|
||||
# test different data types
|
||||
foreach type <numeric>
|
||||
|
||||
statement ok
|
||||
CREATE TABLE tablinho_numbers(i ${type}, j ${type}, k ${type})
|
||||
|
||||
statement ok
|
||||
INSERT INTO tablinho_numbers VALUES (0, 0, 0), (1, 1, 1), (2, 2, 2)
|
||||
|
||||
# simple filters are pushed down
|
||||
query II
|
||||
EXPLAIN SELECT k FROM tablinho_numbers where j = 1
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT k FROM tablinho_numbers where j > 1
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT k FROM tablinho_numbers where j >= 1
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT k FROM tablinho_numbers where j < 1
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT k FROM tablinho_numbers where j <= 1
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
statement ok
|
||||
DROP TABLE tablinho_numbers
|
||||
|
||||
endloop
|
||||
|
||||
# pushdown string
|
||||
statement ok
|
||||
CREATE TABLE tablinho(i varchar)
|
||||
|
||||
statement ok
|
||||
INSERT INTO tablinho VALUES ('a'), ('bla'), ('c')
|
||||
|
||||
# simple filters are pushed down
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i = 'bla'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i > 'bla'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i >= 'bla'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i < 'bla'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i <= 'bla'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
# more complex filters can be pushed down as long as they only involve one column
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i like 'bl_a%'
|
||||
----
|
||||
logical_opt <REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i like '%bla'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT i FROM tablinho where i like '_bla'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
# test Q6 pushdown
|
||||
statement ok
|
||||
CREATE TABLE LINEITEM(L_ORDERKEY INTEGER NOT NULL, L_PARTKEY INTEGER NOT NULL,L_SUPPKEY INTEGER NOT NULL, L_LINENUMBER INTEGER NOT NULL,L_QUANTITY DECIMAL(15,2) NOT NULL,L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL, L_DISCOUNT DECIMAL(15,2) NOT NULL, L_TAX DECIMAL(15,2) NOT NULL,L_RETURNFLAG CHAR(1) NOT NULL, L_LINESTATUS CHAR(1) NOT NULL, L_SHIPDATE DATE NOT NULL, L_COMMITDATE DATE NOT NULL,L_RECEIPTDATE DATE NOT NULL, L_SHIPINSTRUCT CHAR(25) NOT NULL, L_SHIPMODE CHAR(10) NOT NULL, L_COMMENT VARCHAR(44) NOT NULL)
|
||||
|
||||
query II
|
||||
explain select sum(l_extendedprice * l_discount) as revenue from lineitem where l_shipdate >= '1994-01-01' and l_shipdate < '1995-01-01' and l_discount between 0.05 and 0.07 and l_quantity < 24
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
statement ok
|
||||
create temporary table t as select range a, range % 10 b, mod(range,10000) c, 5 d, 10000 e from range(100);
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output = PHYSICAL_ONLY;
|
||||
|
||||
query II
|
||||
explain select count(*) from t where b <=3 and b>=0;
|
||||
----
|
||||
physical_plan <REGEX>:.*b<=3.*
|
||||
|
||||
# test time pushdown
|
||||
|
||||
statement ok
|
||||
CREATE TABLE test_time (a TIME, b TIME, c TIME)
|
||||
|
||||
statement ok
|
||||
INSERT INTO test_time VALUES ('00:01:00','00:01:00','00:01:00'),('00:10:00','00:10:00','00:10:00'),('01:00:00','00:10:00','01:00:00'),(NULL,NULL,NULL)
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output = OPTIMIZED_ONLY;
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT count(*) from test_time where a ='00:01:00'
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
# test bool pushdown
|
||||
|
||||
statement ok
|
||||
CREATE TABLE test_bool (i bool, j bool)
|
||||
|
||||
statement ok
|
||||
INSERT INTO test_bool VALUES (TRUE,TRUE),(TRUE,FALSE),(FALSE,TRUE),(NULL,NULL)
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output = OPTIMIZED_ONLY;
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT i FROM test_bool where j = TRUE
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
# test now() pushdown
|
||||
|
||||
statement ok
|
||||
CREATE TABLE test_timestamps (ts TIMESTAMP);
|
||||
|
||||
statement ok
|
||||
INSERT INTO test_timestamps VALUES (NOW()::TIMESTAMP), (NOW()::TIMESTAMP - INTERVAL 10 YEARS);
|
||||
|
||||
statement ok
|
||||
PRAGMA explain_output = OPTIMIZED_ONLY;
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM test_timestamps where ts >= NOW()::TIMESTAMP - INTERVAL 1 YEAR;
|
||||
----
|
||||
logical_opt <!REGEX>:.*FILTER.*
|
||||
|
||||
query I
|
||||
SELECT COUNT(*) FROM test_timestamps where ts >= NOW()::TIMESTAMP - INTERVAL 1 YEAR;
|
||||
----
|
||||
1
|
||||
399
external/duckdb/test/optimizer/pushdown/table_or_pushdown.test
vendored
Normal file
399
external/duckdb/test/optimizer/pushdown/table_or_pushdown.test
vendored
Normal file
@@ -0,0 +1,399 @@
|
||||
# name: test/optimizer/pushdown/table_or_pushdown.test
|
||||
# description: Test Table OR Filter Push Down
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers AS SELECT a as a, a as b FROM generate_series(1, 5, 1) tbl(a)
|
||||
|
||||
#### test OR filters with multiple columns in the root OR, e.g., a=1 OR b=2
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a=1 OR b=2 AND (a>3 OR b<5)
|
||||
----
|
||||
physical_plan <!REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a=1 OR b=2 AND (a>3 OR b<5)
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
|
||||
|
||||
#### test OR filters with AND that triggers a stop early condition
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a=1 OR a=2 AND (a>3 OR b<5)
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters: a=1 OR a=2[ ]*|.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a=1 OR a=2 AND (a>3 OR b<5)
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
|
||||
|
||||
#### test OR filters with AND in the same column
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a=1 OR (a>3 AND a<5)
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters: a=1 OR a>3 AND a<5|.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a=1 OR (a>3 AND a<5)
|
||||
----
|
||||
1 1
|
||||
4 4
|
||||
|
||||
#### test only OR filters
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a=1 OR a>3 OR a<5
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters: a=1 OR a>3 OR a<5|.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a=1 OR a>3 OR a<5 ORDER by a
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
|
||||
######### Testing String ######################################################
|
||||
|
||||
statement ok
|
||||
CREATE TABLE strings(s VARCHAR)
|
||||
|
||||
statement ok
|
||||
INSERT INTO strings VALUES ('AAAAAAAAAAAAAAA11111'), ('AAAAAAAAAAAAAAA99999')
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM strings WHERE s>'AAAAAAAAAAAAAAA1'
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*s>'AAAAAAAAAAAAAAA1'.*
|
||||
|
||||
query I
|
||||
SELECT * FROM strings WHERE s>'AAAAAAAAAAAAAAA1'
|
||||
----
|
||||
AAAAAAAAAAAAAAA11111
|
||||
AAAAAAAAAAAAAAA99999
|
||||
|
||||
|
||||
#### test only OR filters
|
||||
query II
|
||||
EXPLAIN SELECT * FROM strings WHERE s>'AAAAAAAAAAAAAAA' OR s<'AAAAAAAAAAAAAAA99999A'
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*s>.*'AAAAAAAAAAAAAAA'|.*OR.*s<.*'AAAAAAAAAAAAAAA99999A'.*
|
||||
|
||||
query I
|
||||
SELECT * FROM strings WHERE s>'AAAAAAAAAAAAAAA' OR s<'AAAAAAAAAAAAAAA99999A'
|
||||
----
|
||||
AAAAAAAAAAAAAAA11111
|
||||
AAAAAAAAAAAAAAA99999
|
||||
|
||||
|
||||
statement ok
|
||||
INSERT INTO strings VALUES ('BBBB'), ('CCCC')
|
||||
|
||||
# testing string statistics
|
||||
query II
|
||||
EXPLAIN SELECT * FROM strings WHERE s!='111' OR s!='WWW'
|
||||
----
|
||||
physical_plan <!REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query I
|
||||
SELECT * FROM strings WHERE s!='111' OR s!='WWW' ORDER BY s
|
||||
----
|
||||
AAAAAAAAAAAAAAA11111
|
||||
AAAAAAAAAAAAAAA99999
|
||||
BBBB
|
||||
CCCC
|
||||
|
||||
|
||||
#### Testing not equal
|
||||
query II
|
||||
EXPLAIN SELECT * FROM strings WHERE s!='BBBB' or s>'BBBB'
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*s!=.*'BBBB'.*OR.*s>.*'BBBB'.*
|
||||
|
||||
|
||||
query I
|
||||
SELECT * FROM strings WHERE s!='BBBB' or s>'BBBB'
|
||||
----
|
||||
AAAAAAAAAAAAAAA11111
|
||||
AAAAAAAAAAAAAAA99999
|
||||
CCCC
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a!=1 OR a!=2
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*a!=1.*OR.*a!=2.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a!=1 OR a!=2 ORDER BY a
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
|
||||
#### Testing AND priority
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a>2 AND (a=3 OR a=5)
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*a>2.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a>2 AND (a=3 OR a=5) ORDER BY a
|
||||
----
|
||||
3 3
|
||||
5 5
|
||||
|
||||
######### Complex filters #####################################################
|
||||
|
||||
#### multiple OR filters connected with ANDs
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE (a<2 OR a>3) AND (a=1 OR a=4)
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*a<2.*OR.*a>3.*AND.*a=1.*OR.*a=4.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE (a<2 OR a>3) AND (a=1 OR a=4)
|
||||
----
|
||||
1 1
|
||||
4 4
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE (a<2 OR a>3) AND (a=1 OR a=4) AND (b=1 OR b<5)
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*a<2.*OR.*a>3.*AND.*a=1.*OR.*a=4.*b=1 OR b<5.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE (a<2 OR a>3) AND (a=1 OR a=4) AND (b=1 OR b<5)
|
||||
----
|
||||
1 1
|
||||
4 4
|
||||
|
||||
#### OR filters with functions: concat(...)
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE concat(a=1, b=1)='truetrue' OR a=2 ORDER by a
|
||||
----
|
||||
physical_plan <!REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE concat(a=1, b=1)='truetrue' OR a=2 ORDER by a
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
|
||||
#### LIKE operator
|
||||
query II
|
||||
EXPLAIN SELECT * FROM strings WHERE s>'BBBB' OR s LIKE '%AAAAAAAAAAAAAAA%' ORDER BY s
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query I
|
||||
SELECT * FROM strings WHERE s>'BBBB' OR s LIKE '%AAAAAAAAAAAAAAA%' ORDER BY s
|
||||
----
|
||||
AAAAAAAAAAAAAAA11111
|
||||
AAAAAAAAAAAAAAA99999
|
||||
CCCC
|
||||
|
||||
#### OR filters with CASE statement
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a=1 OR (CASE WHEN a=2 THEN true WHEN a=4 THEN true ELSE false END)
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a=1 OR (CASE WHEN a=2 THEN true WHEN a=4 THEN true ELSE false END)
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
4 4
|
||||
|
||||
#### multiple complex OR filters connected with ANDs
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE (a=1 OR a=4) AND (a=1 OR (CASE WHEN a%2=0 THEN true ELSE false END)) AND (concat(a=1, b=1)='truetrue' OR a=2) AND (a::CHAR LIKE '1' OR a=5)
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*a=1.*OR.*a=4.*|$
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE (a=1 OR a=4) AND (a=1 OR (CASE WHEN a%2=0 THEN true ELSE false END)) AND (concat(a=1, b=1)='truetrue' OR a=2) AND (a::CHAR LIKE '1' OR a=5)
|
||||
----
|
||||
1 1
|
||||
|
||||
#### OR filters with NULL
|
||||
statement ok
|
||||
INSERT INTO integers VALUES (NULL, NULL)
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a=1 OR a IS NULL ORDER BY a
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a=1 OR a IS NULL ORDER BY a
|
||||
----
|
||||
1 1
|
||||
NULL NULL
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a=1 OR a IS NOT NULL
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a=1 OR a IS NOT NULL
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
|
||||
# notequal and null
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a!=1 OR a IS NULL ORDER BY a
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a!=1 OR a IS NULL ORDER BY a
|
||||
----
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
NULL NULL
|
||||
|
||||
# notequal and not null
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a!=1 OR a IS NOT NULL ORDER BY a
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a!=1 OR a IS NOT NULL ORDER BY a
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a!=1 OR a>3 OR a<2 ORDER by a
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*a!=1.*OR.*a>3.*OR.*a.*<.*2.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a!=1 OR a>3 OR a<2 ORDER by a
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
|
||||
# test comparison with null in OR conjunctions uses ISNULL/ISNOTNULL table filter
|
||||
statement ok
|
||||
CREATE TABLE t0 as from values (1), (2), (2), (0), (NULL) t(c1);
|
||||
|
||||
# is distinct from NULL
|
||||
query I
|
||||
SELECT * FROM t0 WHERE ((t0.c1 IS DISTINCT FROM NULL) OR (NULL));
|
||||
----
|
||||
1
|
||||
2
|
||||
2
|
||||
0
|
||||
|
||||
# is not distinct from NULL
|
||||
query I
|
||||
SELECT * FROM t0 WHERE ((t0.c1 IS NOT DISTINCT FROM NULL) OR (NULL));
|
||||
----
|
||||
NULL
|
||||
|
||||
# = NULL in conjunction or
|
||||
query I
|
||||
SELECT * FROM t0 WHERE ((t0.c1 = NULL) OR (NULL));
|
||||
----
|
||||
|
||||
query I
|
||||
SELECT * FROM t0 WHERE ((t0.c1 != NULL) OR (NULL));
|
||||
----
|
||||
|
||||
statement ok
|
||||
SELECT * FROM t0 WHERE ((t0.c1 = NULL) OR (NOT NULL) OR (t0.c1 = 1));
|
||||
|
||||
query I
|
||||
select * from t0 where (NULL OR cast(t0.c1 as bool)) order by all;
|
||||
----
|
||||
1
|
||||
2
|
||||
2
|
||||
|
||||
|
||||
mode skip
|
||||
|
||||
#### numeric statistics
|
||||
# notequal and constant > max
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a!=10 OR a>3
|
||||
----
|
||||
physical_plan <!REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
## The predicate a!=10 is greater than the numeric_statistics::max implying that it is always true within an OR conjunction
|
||||
|
||||
mode unskip
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a!=10 OR a>3
|
||||
----
|
||||
1 1
|
||||
2 2
|
||||
3 3
|
||||
4 4
|
||||
5 5
|
||||
|
||||
# Testing the number of rows filtered (column "a" has five values: 1 .. 5)
|
||||
statement ok
|
||||
PRAGMA enable_profiling
|
||||
|
||||
mode skip
|
||||
|
||||
# should return 2 rows: 1 and 5
|
||||
query II
|
||||
EXPLAIN ANALYZE SELECT a FROM integers WHERE a<2 OR a>4
|
||||
----
|
||||
analyzed_plan <REGEX>:.*SEQ_SCAN.*Filters:.*a<2.*OR.*a>4.*2 Rows.*
|
||||
|
||||
# should return 1 row: 1
|
||||
query II
|
||||
EXPLAIN ANALYZE SELECT a FROM integers WHERE a<2 OR a>5
|
||||
----
|
||||
analyzed_plan <REGEX>:.*SEQ_SCAN.*Filters: a<2 OR a>5.*1 Rows.*
|
||||
|
||||
mode unskip
|
||||
|
||||
statement ok
|
||||
PRAGMA disable_profiling
|
||||
|
||||
# notequal and min == max && min == constant
|
||||
statement ok
|
||||
DROP TABLE integers
|
||||
|
||||
statement ok
|
||||
CREATE TABLE integers AS SELECT a as A, a as B FROM generate_series(1, 1, 1) tbl(a)
|
||||
|
||||
query II
|
||||
EXPLAIN SELECT * FROM integers WHERE a!=1 OR a<2
|
||||
----
|
||||
physical_plan <!REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
SELECT * FROM integers WHERE a!=1 OR a<3
|
||||
----
|
||||
1 1
|
||||
|
||||
25
external/duckdb/test/optimizer/pushdown/test_constant_or_null_pushdown.test
vendored
Normal file
25
external/duckdb/test/optimizer/pushdown/test_constant_or_null_pushdown.test
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# name: test/optimizer/pushdown/test_constant_or_null_pushdown.test
|
||||
# description: Test Table OR Filter Push Down
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
create table t1 (ts_stop TIMESTAMPTZ);
|
||||
|
||||
statement ok
|
||||
insert into t1 values (NULL), (NULL);
|
||||
|
||||
query II
|
||||
explain select count(*) from t1 where constant_or_null(true, COALESCE(ts_stop, '9999-09-09 07:09:09+00'::TIMESTAMPTZ), '2025-06-23 10:32:02.216+00'::TIMESTAMPTZ);
|
||||
----
|
||||
physical_plan <REGEX>:.*constant_or_null.*
|
||||
|
||||
statement ok
|
||||
create table t2 as select range%2 a, range b from range(100);
|
||||
|
||||
statement ok
|
||||
insert into t2 values (NULL, NULL), (NULL, NULL), (NULL, NULL);
|
||||
|
||||
query II
|
||||
explain select * from t2 where constant_or_null(true, a);
|
||||
----
|
||||
physical_plan <REGEX>:.*a IS NOT NULL.*
|
||||
61
external/duckdb/test/optimizer/pushdown/test_pushdown_cte_group_by_all.test
vendored
Normal file
61
external/duckdb/test/optimizer/pushdown/test_pushdown_cte_group_by_all.test
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
# name: test/optimizer/pushdown/test_pushdown_cte_group_by_all.test
|
||||
# description: If a CTE contains GROUP BY ALL then predicate pushdown on non-aggregated columns should occur
|
||||
# group: [pushdown]
|
||||
|
||||
statement ok
|
||||
create or replace table my_temp as
|
||||
from generate_series(99) t(i)
|
||||
select i, i % 10 as group_1;
|
||||
|
||||
statement ok
|
||||
pragma explain_output='optimized_only';
|
||||
|
||||
|
||||
query II
|
||||
explain
|
||||
with my_cte as (
|
||||
from my_temp
|
||||
select
|
||||
group_1,
|
||||
min(i) as min_i,
|
||||
max(i) as max_i
|
||||
group by ALL
|
||||
)
|
||||
from my_cte
|
||||
where
|
||||
group_1 = 2;
|
||||
----
|
||||
logical_opt <REGEX>:.*Filters:.*
|
||||
|
||||
|
||||
query II
|
||||
explain
|
||||
with my_cte as (
|
||||
from my_temp
|
||||
select
|
||||
group_1,
|
||||
min(i) as min_i,
|
||||
max(i) as max_i
|
||||
group by group_1
|
||||
)
|
||||
from my_cte
|
||||
where
|
||||
group_1 = 2;
|
||||
----
|
||||
logical_opt <REGEX>:.*Filters:.*
|
||||
|
||||
|
||||
query II
|
||||
explain
|
||||
with my_cte as (
|
||||
from my_temp
|
||||
select
|
||||
group_1,
|
||||
min(i) as min_i,
|
||||
max(i) as max_i
|
||||
group by group_1 having min_i > 1
|
||||
)
|
||||
from my_cte
|
||||
where group_1 = 2;
|
||||
----
|
||||
logical_opt <REGEX>:.*FILTER.*Filters:.*
|
||||
53
external/duckdb/test/optimizer/pushdown/test_pushdown_or.test_slow
vendored
Normal file
53
external/duckdb/test/optimizer/pushdown/test_pushdown_or.test_slow
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# name: test/optimizer/pushdown/test_pushdown_or.test_slow
|
||||
# group: [pushdown]
|
||||
|
||||
require tpch
|
||||
|
||||
statement ok
|
||||
create table t1 as select range a, range b from range(0,1000000) ;
|
||||
|
||||
statement ok
|
||||
create table t2(a int);
|
||||
|
||||
statement ok
|
||||
insert into t2 from range(10) t(a);
|
||||
|
||||
#statement ok
|
||||
#select * from t1 join t2 using (a);
|
||||
|
||||
query I
|
||||
select a from t1 where a = 30000 or a = 50000 or a = 500;
|
||||
----
|
||||
500
|
||||
30000
|
||||
50000
|
||||
|
||||
|
||||
statement ok
|
||||
call dbgen(sf=1);
|
||||
|
||||
query I
|
||||
select l_orderkey from lineitem where l_orderkey = 6 or l_orderkey = 5999971;
|
||||
----
|
||||
6
|
||||
5999971
|
||||
5999971
|
||||
5999971
|
||||
5999971
|
||||
5999971
|
||||
5999971
|
||||
|
||||
query II
|
||||
select l_orderkey, l_partkey from lineitem where l_orderkey = 6 or l_partkey = 4991;
|
||||
----
|
||||
6 139636
|
||||
403456 4991
|
||||
535522 4991
|
||||
981987 4991
|
||||
2593475 4991
|
||||
3237285 4991
|
||||
3695110 4991
|
||||
4093507 4991
|
||||
4437666 4991
|
||||
4734181 4991
|
||||
5552582 4991
|
||||
79
external/duckdb/test/optimizer/pushdown/timestamp_to_date_pushdown.test
vendored
Normal file
79
external/duckdb/test/optimizer/pushdown/timestamp_to_date_pushdown.test
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# name: test/optimizer/pushdown/timestamp_to_date_pushdown.test
|
||||
# description: Test Tpushdown of timestamp to date filters
|
||||
# group: [pushdown]
|
||||
|
||||
require icu
|
||||
|
||||
foreach timezone UTC ECT
|
||||
|
||||
statement ok
|
||||
set TimeZone='${timezone}';
|
||||
|
||||
statement ok
|
||||
create or replace table t1 (ts timestamp, i int);
|
||||
|
||||
statement ok
|
||||
insert into t1 select '2024-05-01 00:00:00'::timestamp, i from generate_series(1, 2000) g(i);
|
||||
|
||||
statement ok
|
||||
insert into t1 select '2024-05-02 00:00:00'::timestamp, i from generate_series(1, 1000) g(i);
|
||||
|
||||
statement ok
|
||||
insert into t1 select '2024-05-02 00:22:00'::timestamp, i from generate_series(1, 1000) g(i);
|
||||
|
||||
statement ok
|
||||
insert into t1 select '2024-05-03 00:00:00'::timestamp, i from generate_series(1, 2000) g(i);
|
||||
|
||||
query II
|
||||
explain select * from t1 where ts::date == '2024-05-02';
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
query II
|
||||
explain select * from t1 where '2024-05-02' == ts::date;
|
||||
----
|
||||
physical_plan <REGEX>:.*SEQ_SCAN.*Filters:.*
|
||||
|
||||
|
||||
statement ok
|
||||
pragma disable_optimizer;
|
||||
|
||||
query II nosort no_opt_result
|
||||
select * from t1 where ts::date == '2024-05-02';
|
||||
----
|
||||
|
||||
statement ok
|
||||
pragma enable_optimizer;
|
||||
|
||||
query II nosort no_opt_result
|
||||
select * from t1 where ts::date == '2024-05-02';
|
||||
----
|
||||
|
||||
# pattern is still recognized in conjunction
|
||||
query II
|
||||
explain select count(*) from t1 where ts::date == '2024-05-02' and i > 122880/2;
|
||||
----
|
||||
physical_plan <!REGEX>:.*FILTER.*SEQ_SCAN:.*
|
||||
|
||||
|
||||
query I
|
||||
select count(*) from t1 where ts::date == '2024-05-02' and i > 1000;
|
||||
----
|
||||
0
|
||||
|
||||
query I
|
||||
select count(*) from t1 where ts::date == '2024-05-02' and i <= 500;
|
||||
----
|
||||
1000
|
||||
|
||||
endloop
|
||||
|
||||
query I
|
||||
select count(*) from t1 where ts::date == '2024-05-01' and i <= 500;
|
||||
----
|
||||
500
|
||||
|
||||
query I
|
||||
select count(*) from t1 where ts::date == '2024-05-03';
|
||||
----
|
||||
2000
|
||||
Reference in New Issue
Block a user