should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,120 @@
# name: test/sql/join/asof/test_asof_join.test
# description: Test As-Of join useage
# group: [asof]
# Use doubles for readable infinities
statement ok
CREATE TABLE events0 (begin DOUBLE, value INTEGER);
statement ok
INSERT INTO events0 VALUES
(1, 0),
(3, 1),
(6, 2),
(8, 3)
;
# Prevent optimiser from removing true inequalities
statement ok
create table prices("when" timestamp, symbol int, price int);
statement ok
insert into prices values ('2020-01-01 00:00:00', 1, 42);
statement ok
create table trades("when" timestamp, symbol int);
statement ok
insert into trades values ('2020-01-01 00:00:03', 1);
# Compare NLJ optimisation to operator
foreach threshold 0 32
statement ok
PRAGMA asof_loop_join_threshold = ${threshold};
query III
SELECT t.*, p.price
FROM trades t ASOF JOIN prices p
ON t.symbol = p.symbol AND t.when >= p.when;
----
2020-01-01 00:00:03 1 42
# NLJ does not support IS NOT DISTINCT FROM
query II
EXPLAIN
SELECT t.*, p.price
FROM trades t ASOF JOIN prices p
ON t.symbol IS NOT DISTINCT FROM p.symbol AND t.when >= p.when;
----
physical_plan <!REGEX>:.*NESTED_LOOP_JOIN.*
# Ignore non-join conditions
query II
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF JOIN events0 e
ON 1 = 1 AND p.ts >= e.begin
ORDER BY p.ts ASC
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
query II
WITH samples AS (
SELECT col0 AS starts, col1 AS ends
FROM (VALUES
(5, 9),
(10, 13),
(14, 20),
(21, 23)
)
)
SELECT
s1.starts as s1_starts,
s2.starts as s2_starts,
FROM samples AS s1 ASOF JOIN samples as s2 ON s2.ends >= (s1.ends - 5)
WHERE s1_starts <> s2_starts
ORDER BY ALL
----
10 5
21 14
endloop
#
# Errors
#
# Invalid ASOF JOIN comparison
statement error
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF JOIN events0 e
ON p.ts <> e.begin
ORDER BY p.ts ASC
----
Binder Error: Missing ASOF JOIN inequality
# Missing ASOF JOIN inequality
statement error
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF JOIN events0 e
ON p.ts = e.begin
ORDER BY p.ts ASC
----
Binder Error: Missing ASOF JOIN inequality
# Multiple ASOF JOIN inequalities
statement error
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF JOIN events0 e
ON p.ts >= e.begin AND p.ts >= e.value
ORDER BY p.ts ASC
----
Binder Error: Multiple ASOF JOIN inequalities

View File

@@ -0,0 +1,64 @@
# name: test/sql/join/asof/test_asof_join.test_slow
# description: Coverage tests for AsOf Joins
# group: [asof]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
# Highly skewed data to trigger spin-waits
statement ok
CREATE TABLE build AS
SELECT
'1990-03-21 13:00:00'::TIMESTAMP + INTERVAL (range) MINUTE AS begin,
range % 4 AS key,
range AS value,
FROM range(0, 10000000);
statement ok
CREATE TABLE skewed_probe (begin TIMESTAMP, key INTEGER);
statement ok
INSERT INTO skewed_probe
SELECT
'1990-04-21 13:00:01'::TIMESTAMP + INTERVAL (range) MINUTE AS begin,
0::INTEGER AS key,
FROM range(0, 5);
statement ok
INSERT INTO skewed_probe
SELECT
'1990-05-21 13:00:01'::TIMESTAMP + INTERVAL (range) MINUTE AS begin,
1::INTEGER AS key,
FROM range(0, 10);
statement ok
INSERT INTO skewed_probe
SELECT
'1990-06-21 13:00:01'::TIMESTAMP + INTERVAL (range) MINUTE AS begin,
2::INTEGER AS key,
FROM range(0, 20);
statement ok
INSERT INTO skewed_probe
SELECT
'1990-03-21 13:00:01'::TIMESTAMP + INTERVAL (range) MINUTE AS begin,
3::INTEGER AS key,
FROM range(0, 10000000);
# Early finish to some left partition scans: Highly skewed data
query II
SELECT SUM(value), COUNT(*)
FROM skewed_probe ASOF JOIN build USING(key, begin);
----
49999983751397 10000032
# Blocked until all left scans are completed
query II
SELECT SUM(value), COUNT(*)
FROM skewed_probe ASOF RIGHT JOIN build USING(key, begin);
----
87499975015813 17500020

View File

@@ -0,0 +1,354 @@
# name: test/sql/join/asof/test_asof_join_doubles.test
# description: Test As-Of joins for floating point
# group: [asof]
#
# Inequality only
#
statement ok
PRAGMA asof_loop_join_threshold=0;
# Use doubles for readable infinities
statement ok
CREATE TABLE events0 (begin DOUBLE, value INTEGER);
statement ok
INSERT INTO events0 VALUES
(1, 0),
(3, 1),
(6, 2),
(8, 3)
;
# INNER Window version
query II nosort inner_inequality
SELECT p.ts, e.value
FROM
range(0,10) p(ts)
JOIN (
SELECT value, begin,
LEAD(begin, 1, 'infinity'::DOUBLE) OVER (ORDER BY begin ASC) AS end
FROM events0
) e
ON p.ts >= e.begin AND p.ts < e.end
ORDER BY p.ts ASC
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
# INNER ON inequality only
query II nosort inner_inequality
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF JOIN events0 e
ON p.ts >= e.begin
ORDER BY p.ts ASC
----
# INNER USING inequality only
query II nosort inner_inequality
SELECT p.begin, e.value
FROM range(0,10) p(begin) ASOF JOIN events0 e
USING (begin)
ORDER BY p.begin ASC
----
# LEFT Window version
query II nosort left_inequality
SELECT p.ts, e.value
FROM
range(0,10) p(ts)
LEFT JOIN (
SELECT value, begin,
LEAD(begin, 1, 'infinity'::DOUBLE) OVER (ORDER BY begin ASC) AS end
FROM events0
) e
ON p.ts >= e.begin AND p.ts < e.end
ORDER BY p.ts ASC NULLS FIRST
----
0 NULL
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
# LEFT ON inequality only
query II nosort left_inequality
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF LEFT JOIN events0 e
ON p.ts >= e.begin
ORDER BY p.ts ASC NULLS FIRST
----
# LEFT USING inequality only
query II nosort left_inequality
SELECT p.begin, e.value
FROM range(0,10) p(begin) ASOF LEFT JOIN events0 e
USING (begin)
ORDER BY p.begin ASC NULLS FIRST
----
# Add unmatched right event
statement ok
INSERT INTO events0 VALUES (10, 4);
# RIGHT Window version
query II nosort
SELECT p.ts, e.value
FROM
range(0,10) p(ts)
RIGHT JOIN (
SELECT value, begin,
LEAD(begin, 1, 'infinity'::DOUBLE) OVER (ORDER BY begin ASC) AS end
FROM events0
) e
ON p.ts >= e.begin AND p.ts < e.end
ORDER BY p.ts ASC NULLS LAST
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
NULL 4
# RIGHT ON inequality only
query II nosort
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF RIGHT JOIN events0 e
ON p.ts >= e.begin
ORDER BY p.ts ASC NULLS LAST
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
NULL 4
# RIGHT USING inequality only
query II nosort
SELECT p.begin, e.value
FROM range(0,10) p(begin) ASOF RIGHT JOIN events0 e
USING (begin)
ORDER BY p.begin ASC NULLS LAST
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
NULL 4
#
# With equality
#
statement ok
CREATE TABLE events (key INTEGER, begin DOUBLE, value INTEGER);
statement ok
INSERT INTO events VALUES
(1, 1, 0),
(1, 3, 1),
(1, 6, 2),
(1, 8, 3),
(2, 0, 10),
(2, 7, 20),
(2, 11, 30),
;
statement ok
CREATE TABLE probes AS
SELECT key, ts
FROM range(1,3) k(key) CROSS JOIN range(0,10) t(ts)
# INNER Window version
query III nosort inner_equality
SELECT p.key, p.ts, e.value
FROM
probes p
JOIN (
SELECT key, value, begin,
LEAD(begin, 1, 'infinity'::DOUBLE) OVER (PARTITION BY key ORDER BY begin ASC) AS end
FROM events
) e
ON p.key = e.key AND p.ts >= e.begin AND p.ts < e.end
ORDER BY 1, 2 ASC
----
1 1 0
1 2 0
1 3 1
1 4 1
1 5 1
1 6 2
1 7 2
1 8 3
1 9 3
2 0 10
2 1 10
2 2 10
2 3 10
2 4 10
2 5 10
2 6 10
2 7 20
2 8 20
2 9 20
# INNER ON with equality
query III nosort inner_equality
SELECT p.key, p.ts, e.value
FROM probes p ASOF JOIN events e
ON p.key = e.key AND p.ts >= e.begin
ORDER BY 1, 2 ASC
----
# INNER USING with equality
query III nosort inner_equality
SELECT p.key, p.begin, e.value
FROM
(SELECT key, ts AS begin FROM probes) p
ASOF JOIN
events e
USING (key, begin)
ORDER BY 1, 2 ASC
----
# LEFT Window version
query III nosort left_equality
SELECT p.key, p.ts, e.value
FROM
probes p
LEFT JOIN (
SELECT key, value, begin,
LEAD(begin, 1, 'infinity'::DOUBLE) OVER (PARTITION BY key ORDER BY begin ASC) AS end
FROM events
) e
ON p.key = e.key AND p.ts >= e.begin AND p.ts < e.end
ORDER BY 1, 2 ASC NULLS FIRST
----
1 0 NULL
1 1 0
1 2 0
1 3 1
1 4 1
1 5 1
1 6 2
1 7 2
1 8 3
1 9 3
2 0 10
2 1 10
2 2 10
2 3 10
2 4 10
2 5 10
2 6 10
2 7 20
2 8 20
2 9 20
# LEFT ON with equality
query III nosort left_equality
SELECT p.key, p.ts, e.value
FROM probes p ASOF LEFT JOIN events e
ON p.key = e.key AND p.ts >= e.begin
ORDER BY 1, 2, 3 ASC NULLS FIRST
----
# LEFT USING with equality
query III nosort left_equality
SELECT p.key, p.begin, e.value
FROM
(SELECT key, ts AS begin FROM probes) p
ASOF LEFT JOIN
events e
USING (key, begin)
ORDER BY 1, 2 ASC NULLS FIRST
----
# RIGHT Window version
query III nosort right_equality
SELECT p.key, p.ts, e.value
FROM
probes p
RIGHT JOIN (
SELECT key, value, begin,
LEAD(begin, 1, 'infinity'::DOUBLE) OVER (PARTITION BY key ORDER BY begin ASC) AS end
FROM events
) e
ON p.key = e.key AND p.ts >= e.begin AND p.ts < e.end
ORDER BY 1 ASC NULLS FIRST, 2
----
1 1 0
1 2 0
1 3 1
1 4 1
1 5 1
1 6 2
1 7 2
1 8 3
1 9 3
2 0 10
2 1 10
2 2 10
2 3 10
2 4 10
2 5 10
2 6 10
2 7 20
2 8 20
2 9 20
NULL NULL 30
# RIGHT ON with equality
query III nosort right_equality
SELECT p.key, p.ts, e.value
FROM probes p ASOF RIGHT JOIN events e
ON p.key = e.key AND p.ts >= e.begin
ORDER BY 1 ASC NULLS FIRST, 2
----
# RIGHT USING with equality
query III nosort right_equality
SELECT p.key, p.begin, e.value
FROM
(SELECT key, ts AS begin FROM probes) p
ASOF RIGHT JOIN
events e
USING (key, begin)
ORDER BY 1 ASC NULLS FIRST, 2
----
# INNER with empty RHS
query II
SELECT p.ts, e.value
FROM range(0,10) p(ts) ASOF JOIN (from events0 where value < 0) e
ON p.ts >= e.begin
ORDER BY p.ts ASC
----

View File

@@ -0,0 +1,236 @@
# name: test/sql/join/asof/test_asof_join_inequalities.test
# description: Test As-Of joins for greater than and less thans
# group: [asof]
# Join on a timestamp range
statement ok
CREATE TABLE events0 AS
SELECT '2023-03-21 13:00:00'::TIMESTAMP + INTERVAL (range) HOUR AS begin, range AS value
FROM range(0, 4);
statement ok
INSERT INTO events0 VALUES
(NULL, -10),
('infinity', 9),
('-infinity', -1)
;
statement ok
CREATE TABLE probe0 AS
SELECT *
FROM range('2023-03-21 12:00:00'::TIMESTAMP, '2023-03-21 22:00:00'::TIMESTAMP, INTERVAL 1 HOUR) p(begin)
;
statement ok
INSERT INTO probe0 VALUES
(NULL),
('infinity')
;
# Check results against IEJoin
foreach debug False True
statement ok
PRAGMA debug_asof_iejoin=${debug}
# Check NLJ results against both
foreach threshold 0 32
statement ok
PRAGMA asof_loop_join_threshold = ${threshold};
#
# Strictly Greater Than
#
# INNER
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF JOIN events0 e
ON p.begin > e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 -infinity -1
2023-03-21 13:00:00 -infinity -1
2023-03-21 14:00:00 2023-03-21 13:00:00 0
2023-03-21 15:00:00 2023-03-21 14:00:00 1
2023-03-21 16:00:00 2023-03-21 15:00:00 2
2023-03-21 17:00:00 2023-03-21 16:00:00 3
2023-03-21 18:00:00 2023-03-21 16:00:00 3
2023-03-21 19:00:00 2023-03-21 16:00:00 3
2023-03-21 20:00:00 2023-03-21 16:00:00 3
2023-03-21 21:00:00 2023-03-21 16:00:00 3
infinity 2023-03-21 16:00:00 3
# LEFT
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
ON p.begin > e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 -infinity -1
2023-03-21 13:00:00 -infinity -1
2023-03-21 14:00:00 2023-03-21 13:00:00 0
2023-03-21 15:00:00 2023-03-21 14:00:00 1
2023-03-21 16:00:00 2023-03-21 15:00:00 2
2023-03-21 17:00:00 2023-03-21 16:00:00 3
2023-03-21 18:00:00 2023-03-21 16:00:00 3
2023-03-21 19:00:00 2023-03-21 16:00:00 3
2023-03-21 20:00:00 2023-03-21 16:00:00 3
2023-03-21 21:00:00 2023-03-21 16:00:00 3
infinity 2023-03-21 16:00:00 3
NULL NULL NULL
# RIGHT
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
ON p.begin > e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 -infinity -1
2023-03-21 13:00:00 -infinity -1
2023-03-21 14:00:00 2023-03-21 13:00:00 0
2023-03-21 15:00:00 2023-03-21 14:00:00 1
2023-03-21 16:00:00 2023-03-21 15:00:00 2
2023-03-21 17:00:00 2023-03-21 16:00:00 3
2023-03-21 18:00:00 2023-03-21 16:00:00 3
2023-03-21 19:00:00 2023-03-21 16:00:00 3
2023-03-21 20:00:00 2023-03-21 16:00:00 3
2023-03-21 21:00:00 2023-03-21 16:00:00 3
infinity 2023-03-21 16:00:00 3
NULL infinity 9
NULL NULL -10
#
# Less Than or Equal
#
# INNER
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF JOIN events0 e
ON p.begin <= e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 2023-03-21 13:00:00 0
2023-03-21 13:00:00 2023-03-21 13:00:00 0
2023-03-21 14:00:00 2023-03-21 14:00:00 1
2023-03-21 15:00:00 2023-03-21 15:00:00 2
2023-03-21 16:00:00 2023-03-21 16:00:00 3
2023-03-21 17:00:00 infinity 9
2023-03-21 18:00:00 infinity 9
2023-03-21 19:00:00 infinity 9
2023-03-21 20:00:00 infinity 9
2023-03-21 21:00:00 infinity 9
infinity infinity 9
# LEFT
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
ON p.begin <= e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 2023-03-21 13:00:00 0
2023-03-21 13:00:00 2023-03-21 13:00:00 0
2023-03-21 14:00:00 2023-03-21 14:00:00 1
2023-03-21 15:00:00 2023-03-21 15:00:00 2
2023-03-21 16:00:00 2023-03-21 16:00:00 3
2023-03-21 17:00:00 infinity 9
2023-03-21 18:00:00 infinity 9
2023-03-21 19:00:00 infinity 9
2023-03-21 20:00:00 infinity 9
2023-03-21 21:00:00 infinity 9
infinity infinity 9
NULL NULL NULL
# RIGHT
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
ON p.begin <= e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 2023-03-21 13:00:00 0
2023-03-21 13:00:00 2023-03-21 13:00:00 0
2023-03-21 14:00:00 2023-03-21 14:00:00 1
2023-03-21 15:00:00 2023-03-21 15:00:00 2
2023-03-21 16:00:00 2023-03-21 16:00:00 3
2023-03-21 17:00:00 infinity 9
2023-03-21 18:00:00 infinity 9
2023-03-21 19:00:00 infinity 9
2023-03-21 20:00:00 infinity 9
2023-03-21 21:00:00 infinity 9
infinity infinity 9
NULL -infinity -1
NULL NULL -10
#
# Strictly Less Than
#
# INNER
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF JOIN events0 e
ON p.begin < e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 2023-03-21 13:00:00 0
2023-03-21 13:00:00 2023-03-21 14:00:00 1
2023-03-21 14:00:00 2023-03-21 15:00:00 2
2023-03-21 15:00:00 2023-03-21 16:00:00 3
2023-03-21 16:00:00 infinity 9
2023-03-21 17:00:00 infinity 9
2023-03-21 18:00:00 infinity 9
2023-03-21 19:00:00 infinity 9
2023-03-21 20:00:00 infinity 9
2023-03-21 21:00:00 infinity 9
# LEFT
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
ON p.begin < e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 2023-03-21 13:00:00 0
2023-03-21 13:00:00 2023-03-21 14:00:00 1
2023-03-21 14:00:00 2023-03-21 15:00:00 2
2023-03-21 15:00:00 2023-03-21 16:00:00 3
2023-03-21 16:00:00 infinity 9
2023-03-21 17:00:00 infinity 9
2023-03-21 18:00:00 infinity 9
2023-03-21 19:00:00 infinity 9
2023-03-21 20:00:00 infinity 9
2023-03-21 21:00:00 infinity 9
infinity NULL NULL
NULL NULL NULL
# RIGHT
query III
SELECT p.begin, e.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
ON p.begin < e.begin
ORDER BY ALL ASC
----
2023-03-21 12:00:00 2023-03-21 13:00:00 0
2023-03-21 13:00:00 2023-03-21 14:00:00 1
2023-03-21 14:00:00 2023-03-21 15:00:00 2
2023-03-21 15:00:00 2023-03-21 16:00:00 3
2023-03-21 16:00:00 infinity 9
2023-03-21 17:00:00 infinity 9
2023-03-21 18:00:00 infinity 9
2023-03-21 19:00:00 infinity 9
2023-03-21 20:00:00 infinity 9
2023-03-21 21:00:00 infinity 9
NULL -infinity -1
NULL NULL -10
endloop
endloop

View File

@@ -0,0 +1,138 @@
# name: test/sql/join/asof/test_asof_join_integers.test
# description: Test As-Of joins for integers
# group: [asof]
# Join on an integer range
statement ok
CREATE TABLE events0 (begin INTEGER, value INTEGER);
statement ok
INSERT INTO events0 VALUES
(NULL, -1),
(1, 0),
(3, 1),
(6, 2),
(8, 3),
(999999, 9)
;
statement ok
CREATE TABLE probe0 AS
SELECT range::INTEGER AS begin
FROM range(0,10)
;
# Compare NLJ optimisation to operator
foreach threshold 0 32
statement ok
PRAGMA asof_loop_join_threshold = ${threshold};
# INNER ON inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
query II
SELECT p.begin, e.value
FROM probe0 p ASOF JOIN events0 e
USING (begin)
ORDER BY p.begin ASC
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
# LEFT ON inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
0 NULL
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
query II
SELECT p.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
USING (begin)
ORDER BY p.begin ASC
----
0 NULL
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
# RIGHT ON inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
ON p.begin >= e.begin
ORDER BY ALL
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
NULL -1
NULL 9
# RIGHT USING inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
USING (begin)
ORDER BY ALL
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
NULL -1
NULL 9
endloop

View File

@@ -0,0 +1,29 @@
# name: test/sql/join/asof/test_asof_join_merge.test_slow
# description: Test merge queue and repartitioning
# group: [asof]
statement ok
PRAGMA memory_limit='400M'
statement ok
PRAGMA threads=4
statement ok
SET temp_directory='__TEST_DIR__/temp.tmp'
# Force PhysicalAsOfJoin
statement ok
PRAGMA asof_loop_join_threshold = 0;
query II
WITH build AS (
SELECT k, ('2021-01-01'::TIMESTAMP + INTERVAL (i) SECOND) AS t, i % 37 AS v
FROM range(3000000) t(i), range(2) tk(k)
), probe AS (
SELECT k, t
FROM range(2) tk(k),
range('2021-01-01 00:00:30'::TIMESTAMP, '2021-02-01 00:00:30'::TIMESTAMP, INTERVAL 1 HOUR) tt(t)
) SELECT SUM(v) AS v, COUNT(*) AS n
FROM probe ASOF JOIN build USING(k, t)
----
26790 1488

View File

@@ -0,0 +1,165 @@
# name: test/sql/join/asof/test_asof_join_missing.test_slow
# description: Test As-Of join with missing matches
# group: [asof]
statement ok
PRAGMA enable_verification
# These test stress several aspects of the matching:
# * Probe inequality less than the minimum (no match)
# * Probe equality missing (no match)
# * More than 64 valid probe entries (mask => SV construction)
# * First radix bin empty.
# * First payload bin empty
# * Multiple scanned payload blocks
statement ok
PRAGMA asof_loop_join_threshold=0;
# Check results against IEJoin
foreach debug False True
statement ok
PRAGMA debug_asof_iejoin=${debug}
# 10 dates, 5 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,10) vals(v), range(0,5) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
108
# Coverage: Missing right side bin
query II
WITH build AS (
SELECT k * 2 as k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,10) vals(v), range(0,5) keys(k)
), probe AS (
SELECT k / 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v), COUNT(*)
FROM probe ASOF JOIN build USING(k, t);
----
108 27
# 20 dates, 5 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,20) vals(v), range(0,5) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
513
# 30 dates, 5 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,30) vals(v), range(0,5) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
1218
# 50 dates, 5 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,50) vals(v), range(0,5) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
3528
# 100 dates, 5 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,100) vals(v), range(0,5) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
14553
# 100 dates, 50 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,100) vals(v), range(0,50) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
121275
# 1000 dates, 5 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,1000) vals(v), range(0,5) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
1495503
# 1000 dates, 50 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,1000) vals(v), range(0,50) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
12462525
# 10000 dates, 50 keys
query I
WITH build AS (
SELECT k, '2001-01-01 00:00:00'::TIMESTAMP + INTERVAL (v) MINUTE AS t, v
FROM range(0,10000) vals(v), range(0,50) keys(k)
), probe AS (
SELECT k * 2 AS k, t - INTERVAL (30) SECOND AS t
FROM build
)
SELECT SUM(v)
FROM probe ASOF JOIN build USING(k, t);
----
1249625025
endloop

View File

@@ -0,0 +1,114 @@
# name: test/sql/join/asof/test_asof_join_predicates.test
# description: Test As-Of join NLJ rewrite for non-comparison predicates
# group: [asof]
statement ok
PRAGMA enable_verification;
# Issue 18309
statement ok
CREATE TABLE tt1 (i INTEGER, j VARCHAR);
statement ok
INSERT INTO tt1 VALUES
(2, 'A'),
(4, 'B'),
(5, 'A');
statement ok
CREATE TABLE tt2 (i INTEGER, j VARCHAR, k VARCHAR);
statement ok
INSERT INTO tt2 VALUES
(1, 'A', 'I'),
(3, 'B', 'II');
query II
explain
SELECT tt1.i, tt2.k
FROM tt1
ASOF JOIN tt2 ON
tt1.j = tt2.j AND tt1.i >= tt2.i
ORDER BY tt1.i;
----
physical_plan <REGEX>:.*NESTED_LOOP_JOIN.*
query II
SELECT tt1.i, tt2.k
FROM tt1
ASOF JOIN tt2 ON
(tt1.j = tt2.j OR tt1.j = tt2.j) AND tt1.i >= tt2.i
ORDER BY tt1.i;
----
2 I
4 II
5 I
# Issue 19027
statement ok
create table l (id integer, date timestamp, item varchar);
statement ok
insert into l values
(0, '2025-01-01', 'A');
statement ok
create table r (id integer, date timestamp, item varchar, valuei double);
statement ok
insert into r values
(0, '2025-01-01', 'A', 8.0),
(0, '2025-01-01', 'B', 12.0);
query II
explain
select
l.id,
l.date,
l.item as litem,
r.item as ritem,
valuei
from l
asof left join r
on l.id = r.id and l.date >= r.date
and (l.item = r.item or l.item = '*');
----
physical_plan <REGEX>:.*NESTED_LOOP_JOIN.*
query IIIII
select
l.id,
l.date,
l.item as litem,
r.item as ritem,
valuei
from l
asof left join r
on l.id = r.id and l.date >= r.date
and (l.item = r.item or l.item = '*');
----
0 2025-01-01 00:00:00 A A 8.0
# Issue 19251
statement ok
create temp table tbl1 as
select unnest(range(1000)) % 10 as x, '2022-01-01'::timestamp + to_days(unnest(range(1000))) as ts;
statement ok
create temp table tbl2 as
select unnest(range(1000)) % 10 as x, '2022-01-01'::timestamp + to_hours(unnest(range(1000))) as ts;
query II
explain
from tbl1 asof join
tbl2 on tbl1.x = tbl2.x
and tbl1.ts >= tbl2.ts
and (tbl1.ts - tbl2.ts) < interval '1' hours;
----
physical_plan <REGEX>:.*NESTED_LOOP_JOIN.*
statement ok
from tbl1 asof join
tbl2 on tbl1.x = tbl2.x
and tbl1.ts >= tbl2.ts
and (tbl1.ts - tbl2.ts) < interval '1' hours;

View File

@@ -0,0 +1,201 @@
# name: test/sql/join/asof/test_asof_join_pushdown.test
# description: Test predicate pushdown for ASOF joins
# group: [asof]
statement ok
CREATE OR REPLACE TABLE right_pushdown(time INTEGER, value FLOAT);
statement ok
INSERT INTO right_pushdown VALUES
(0, 0),
(1, NULL),
;
statement ok
CREATE TABLE issue13899(seq_no INT, amount DECIMAL(10,2));
statement ok
INSERT INTO issue13899 VALUES
(1,1.00),
(2,null),
(3,null),
(4,null),
(5,2.00),
(6,null),
(7,null),
(8,3.00),
(9,null),
(10,null),
(11,5.00);
# Compare NLJ optimisation to operator
foreach threshold 0 32
statement ok
PRAGMA asof_loop_join_threshold = ${threshold};
query IIII
SELECT
d1.time,
d2.time,
d1.value,
d2.value
FROM right_pushdown d1
ASOF JOIN (
SELECT * FROM right_pushdown WHERE value is not NULL
) d2
ON d1.time >= d2.time
ORDER BY ALL;
----
0 0 0.0 0.0
1 0 NULL 0.0
query IIII
SELECT
d1.time,
d2.time,
d1.value,
d2.value
FROM right_pushdown d1
ASOF LEFT JOIN (
SELECT * FROM right_pushdown WHERE value is not NULL
) d2
ON d1.time >= d2.time
ORDER BY ALL;
----
0 0 0.0 0.0
1 0 NULL 0.0
statement ok
CREATE OR REPLACE TABLE issue12215 AS
SELECT col0 AS starts, col1 AS ends
FROM (VALUES
(5, 9),
(10, 13),
(14, 20),
(21, 23)
);
query II
SELECT
s1.starts as s1_starts,
s2.starts as s2_starts,
FROM issue12215 AS s1
ASOF JOIN issue12215 as s2
ON s2.ends >= (s1.ends - 5)
WHERE s1_starts <> s2_starts
ORDER BY ALL
----
10 5
21 14
query II
WITH t as (
SELECT
t1.col0 AS left_val,
t2.col0 AS right_val,
FROM
(VALUES (0), (5), (10), (15)) AS t1
ASOF JOIN (VALUES (1), (6), (11), (16)) AS t2
ON t2.col0 > t1.col0
)
SELECT *
FROM t
WHERE right_val BETWEEN 3 AND 12
ORDER BY ALL
----
5 6
10 11
query II
WITH t as (
SELECT
t1.col0 AS left_val,
t2.col0 AS right_val,
FROM
(VALUES (0), (5), (10), (15)) AS t1
ASOF LEFT JOIN (VALUES (1), (6), (11), (16)) AS t2
ON t2.col0 > t1.col0
)
SELECT *
FROM t
WHERE right_val BETWEEN 3 AND 12
ORDER BY ALL
----
5 6
10 11
query III
select
a.seq_no,
a.amount,
b.amount
from issue13899 as a
asof join issue13899 as b
on a.seq_no>=b.seq_no
and b.amount is not null
ORDER BY 1
----
1 1.00 1.00
2 NULL 1.00
3 NULL 1.00
4 NULL 1.00
5 2.00 2.00
6 NULL 2.00
7 NULL 2.00
8 3.00 3.00
9 NULL 3.00
10 NULL 3.00
11 5.00 5.00
endloop
query IIII
WITH t1 AS (
FROM (VALUES (1,2),(2,4)) t1(id, value)
),
t2 AS (
FROM (VALUES (1,3)) t2(id, value)
)
FROM t1
ASOF LEFT JOIN t2
ON t1.id <= t2.id
ORDER BY 1
----
1 2 1 3
2 4 NULL NULL
query IIII
WITH t1 AS (
FROM (VALUES (1,2),(2,4)) t1(id, value)
),
t2 AS (
FROM (VALUES (1,3)) t2(id, value)
)
FROM t1
ASOF LEFT JOIN t2
ON t1.id >= t2.id AND t1.id = 1
ORDER BY 1
----
1 2 1 3
2 4 NULL NULL
statement error
WITH t1 AS (
FROM VALUES
(1::INT, '2020-01-01 00:00:00'::TIMESTAMP),
(2, '2020-01-02 00:00:00')
AS t1(a, b)
), t2 AS (
FROM VALUES
(1::INT, '2020-01-01 00:01:00'::TIMESTAMP),
(2, '2020-01-02 00:00:00')
t2(c, d)
)
SELECT *
FROM t1
ASOF JOIN t2
ON t1=b == t2.d
AND t1.b >= t2.d - INTERVAL '1' SECOND;
----
Unimplemented type for cast

View File

@@ -0,0 +1,41 @@
# name: test/sql/join/asof/test_asof_join_subquery.test
# description: Test As-Of correlated subqueries
# group: [asof]
statement ok
CREATE TABLE events (begin DOUBLE, value INTEGER);
statement ok
INSERT INTO events VALUES
(1, 0),
(3, 1),
(6, 2),
(8, 3)
;
# Compare NLJ optimisation to operator
foreach threshold 0 32
statement ok
PRAGMA asof_loop_join_threshold = ${threshold};
query II
SELECT begin, value IN (
SELECT e1.value
FROM (
SELECT *
FROM events e1
WHERE e1.value = events.value) e1
ASOF JOIN
range(1, 10) tbl(begin)
USING (begin)
)
FROM events
ORDER BY ALL;
----
1.0 true
3.0 true
6.0 true
8.0 true
endloop

View File

@@ -0,0 +1,232 @@
# name: test/sql/join/asof/test_asof_join_timestamps.test
# description: Test As-Of joins for timestamps
# group: [asof]
# Join on a timestamp range
statement ok
CREATE TABLE events0 AS
SELECT '2023-03-21 13:00:00'::TIMESTAMP + INTERVAL (range) HOUR AS begin, range AS value
FROM range(0, 4);
# Could we add some tests where we have NULL values in the tables?
# Could we add some tests where we have infinity values (e.g. NaN, or infinity::timestamp) in the tables?
statement ok
INSERT INTO events0 VALUES
(NULL, -1),
('infinity', 9)
;
statement ok
CREATE TABLE probe0 AS
SELECT *
FROM range('2023-03-21 12:00:00'::TIMESTAMP, '2023-03-21 22:00:00'::TIMESTAMP, INTERVAL 1 HOUR) p(begin)
;
statement ok
INSERT INTO probe0 VALUES
(NULL),
('infinity')
;
statement ok
CREATE TABLE asof_nulls (
time TIMESTAMP,
value FLOAT
);
statement ok
INSERT INTO asof_nulls (time, value) VALUES ('2025-07-15 00:00:00', 42);
statement ok
INSERT INTO asof_nulls (time, value) VALUES ('2025-07-15 01:00:00', null);
# Compare NLJ optimisation to operator
foreach threshold 0 32
statement ok
PRAGMA asof_loop_join_threshold = ${threshold};
# INNER ON inequality only
query II nosort
SELECT p.begin, e.value
FROM probe0 p ASOF JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
2023-03-21 13:00:00 0
2023-03-21 14:00:00 1
2023-03-21 15:00:00 2
2023-03-21 16:00:00 3
2023-03-21 17:00:00 3
2023-03-21 18:00:00 3
2023-03-21 19:00:00 3
2023-03-21 20:00:00 3
2023-03-21 21:00:00 3
infinity 9
# INNER USING inequality only
query II nosort
SELECT p.begin, e.value
FROM probe0 p ASOF JOIN events0 e
USING (begin)
ORDER BY p.begin ASC
----
2023-03-21 13:00:00 0
2023-03-21 14:00:00 1
2023-03-21 15:00:00 2
2023-03-21 16:00:00 3
2023-03-21 17:00:00 3
2023-03-21 18:00:00 3
2023-03-21 19:00:00 3
2023-03-21 20:00:00 3
2023-03-21 21:00:00 3
infinity 9
# LEFT ON inequality only
query II nosort
SELECT p.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
2023-03-21 12:00:00 NULL
2023-03-21 13:00:00 0
2023-03-21 14:00:00 1
2023-03-21 15:00:00 2
2023-03-21 16:00:00 3
2023-03-21 17:00:00 3
2023-03-21 18:00:00 3
2023-03-21 19:00:00 3
2023-03-21 20:00:00 3
2023-03-21 21:00:00 3
infinity 9
NULL NULL
# LEFT USING inequality only
query II nosort left_inequality
SELECT p.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
USING (begin)
ORDER BY p.begin ASC
----
2023-03-21 12:00:00 NULL
2023-03-21 13:00:00 0
2023-03-21 14:00:00 1
2023-03-21 15:00:00 2
2023-03-21 16:00:00 3
2023-03-21 17:00:00 3
2023-03-21 18:00:00 3
2023-03-21 19:00:00 3
2023-03-21 20:00:00 3
2023-03-21 21:00:00 3
infinity 9
NULL NULL
# RIGHT ON inequality only
query II nosort
SELECT p.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
ON p.begin >= e.begin
ORDER BY ALL
----
2023-03-21 13:00:00 0
2023-03-21 14:00:00 1
2023-03-21 15:00:00 2
2023-03-21 16:00:00 3
2023-03-21 17:00:00 3
2023-03-21 18:00:00 3
2023-03-21 19:00:00 3
2023-03-21 20:00:00 3
2023-03-21 21:00:00 3
infinity 9
NULL -1
# RIGHT USING inequality only
query II nosort
SELECT p.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
USING (begin)
ORDER BY ALL
----
2023-03-21 13:00:00 0
2023-03-21 14:00:00 1
2023-03-21 15:00:00 2
2023-03-21 16:00:00 3
2023-03-21 17:00:00 3
2023-03-21 18:00:00 3
2023-03-21 19:00:00 3
2023-03-21 20:00:00 3
2023-03-21 21:00:00 3
infinity 9
NULL -1
#
# Coverage
#
# rhs_sink.count == 0
query II
SELECT p.begin, e.value
FROM probe0 p ASOF LEFT JOIN (SELECT * FROM events0 WHERE log(value + 5) > 10) e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
2023-03-21 12:00:00 NULL
2023-03-21 13:00:00 NULL
2023-03-21 14:00:00 NULL
2023-03-21 15:00:00 NULL
2023-03-21 16:00:00 NULL
2023-03-21 17:00:00 NULL
2023-03-21 18:00:00 NULL
2023-03-21 19:00:00 NULL
2023-03-21 20:00:00 NULL
2023-03-21 21:00:00 NULL
infinity NULL
NULL NULL
# EmptyResultIfRHSIsEmpty
query II
SELECT p.begin, e.value
FROM probe0 p ASOF RIGHT JOIN (SELECT * FROM events0 WHERE log(value + 5) > 10) e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
# SEMI JOIN
query I
SELECT p.begin
FROM probe0 p ASOF SEMI JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
2023-03-21 13:00:00
2023-03-21 14:00:00
2023-03-21 15:00:00
2023-03-21 16:00:00
2023-03-21 17:00:00
2023-03-21 18:00:00
2023-03-21 19:00:00
2023-03-21 20:00:00
2023-03-21 21:00:00
infinity
# ANTI JOIN
query I
SELECT p.begin
FROM probe0 p ASOF ANTI JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
2023-03-21 12:00:00
NULL
# Return NULLs
query II
SELECT time_series.time, asof_nulls.value
FROM (VALUES ('2025-07-15 02:00:00'::TIMESTAMP)) as time_series(time)
ASOF LEFT JOIN asof_nulls ON asof_nulls.time <= time_series.time;
----
2025-07-15 02:00:00 NULL
endloop

View File

@@ -0,0 +1,25 @@
# name: test/sql/join/asof/test_asof_join_tpch.test_slow
# description: AsOf Join using floating point keys in TPC-H
# group: [asof]
require tpch
statement ok
CALL dbgen(sf=0.1, suffix='_normal');
statement ok
CREATE TABLE lineitem_dbl AS SELECT * REPLACE (l_orderkey::DOUBLE + 0.25 AS l_orderkey) FROM lineitem_normal;
statement ok
CREATE TABLE orders_dbl AS SELECT * REPLACE (o_orderkey::DOUBLE AS o_orderkey) FROM orders_normal;
query I
SELECT COUNT(*) from lineitem_normal join orders_normal on (l_orderkey=o_orderkey);
----
600572
query I
SELECT COUNT(*)
FROM lineitem_dbl ASOF JOIN orders_dbl ON (l_orderkey >= o_orderkey);
----
600572

View File

@@ -0,0 +1,138 @@
# name: test/sql/join/asof/test_asof_join_varchar.test
# description: Test As-Of joins for strings
# group: [asof]
# Join on a string range
statement ok
CREATE TABLE events0 (begin VARCHAR, value INTEGER);
statement ok
INSERT INTO events0 VALUES
(NULL, -1),
(1, 0),
(3, 1),
(6, 2),
(8, 3),
('infinity', 9)
;
statement ok
CREATE TABLE probe0 AS
SELECT range::VARCHAR AS begin
FROM range(0,10)
;
# Compare NLJ optimisation to operator
foreach threshold 0 32
statement ok
PRAGMA asof_loop_join_threshold = ${threshold};
# INNER ON inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
query II
SELECT p.begin, e.value
FROM probe0 p ASOF JOIN events0 e
USING (begin)
ORDER BY p.begin ASC
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
# LEFT ON inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
ON p.begin >= e.begin
ORDER BY p.begin ASC
----
0 NULL
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
query II
SELECT p.begin, e.value
FROM probe0 p ASOF LEFT JOIN events0 e
USING (begin)
ORDER BY p.begin ASC
----
0 NULL
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
# RIGHT ON inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
ON p.begin >= e.begin
ORDER BY ALL
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
NULL -1
NULL 9
# RIGHT USING inequality only
query II
SELECT p.begin, e.value
FROM probe0 p ASOF RIGHT JOIN events0 e
USING (begin)
ORDER BY ALL
----
1 0
2 0
3 1
4 1
5 1
6 2
7 2
8 3
9 3
NULL -1
NULL 9
endloop

View File

@@ -0,0 +1,31 @@
# name: test/sql/join/cross_product/test_cross_product.test
# description: Test cross products
# group: [cross_product]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test VALUES (11, 1), (12, 2);
query IIII
SELECT * FROM test t1, test t2 ORDER BY 1, 2, 3, 4;
----
11 1 11 1
11 1 12 2
12 2 11 1
12 2 12 2
# big cross product
query I
SELECT COUNT(*) FROM test t1, range(2000) t2
----
4000
query I
SELECT COUNT(*) FROM range(2000) t1, test t2
----
4000

View File

@@ -0,0 +1,31 @@
# name: test/sql/join/cross_product/test_cross_product_parallelism.test_slow
# description: Test cross product with parallelism
# group: [cross_product]
statement ok
PRAGMA enable_verification
statement ok
PRAGMA threads=4
statement ok
PRAGMA verify_parallelism
statement ok
CREATE TABLE integers AS SELECT * FROM range(0, 5000) tbl(i)
# test if order remains the same
query I
SELECT count(*) FROM integers i1, integers i2
----
25000000
query II
SELECT MIN(i1.i), MAX(i2.i) FROM integers i1, integers i2
----
0 4999
query II
SELECT MAX(i1.i), MIN(i2.i) FROM integers i1, integers i2
----
4999 0

View File

@@ -0,0 +1,126 @@
# name: test/sql/join/empty_joins.test
# description: Test joins with empty inputs
# group: [join]
statement ok
CREATE TABLE integers AS SELECT i FROM range(10) tbl(i)
statement ok
CREATE TABLE integers2 AS SELECT i FROM range(10) tbl(i)
statement ok
CREATE VIEW integers_empty AS SELECT * FROM integers WHERE rowid>100
statement ok
CREATE VIEW integers2_empty AS SELECT * FROM integers WHERE rowid>100
statement ok
CREATE VIEW empty_join AS SELECT * FROM integers JOIN integers2_empty USING (i)
# empty LHS
query I
SELECT COUNT(*) FROM integers_empty JOIN integers2 USING (i)
----
0
query I
SELECT COUNT(*) FROM integers_empty JOIN integers2 ON (integers_empty.i>integers2.i)
----
0
query I
SELECT COUNT(*) FROM integers_empty JOIN integers2 ON (integers_empty.i<>integers2.i)
----
0
query I
SELECT COUNT(*) FROM integers_empty JOIN integers2 ON (integers_empty.i<>integers2.i OR integers_empty.i+1<>integers2.i)
----
0
query I
SELECT * FROM integers_empty JOIN integers2 USING (i)
----
query I
SELECT COUNT(*) FROM integers_empty LEFT JOIN integers2 USING (i)
----
0
query I
SELECT * FROM integers_empty LEFT JOIN integers2 USING (i)
----
query I
SELECT COUNT(*) FROM integers_empty RIGHT JOIN integers2 USING (i)
----
10
query I
SELECT COUNT(*) FROM integers_empty FULL OUTER JOIN integers2 USING (i)
----
10
# empty RHS
query I
SELECT COUNT(*) FROM integers JOIN integers2_empty USING (i)
----
0
query I
SELECT * FROM integers JOIN integers2_empty USING (i)
----
query I
SELECT COUNT(*) FROM integers LEFT JOIN integers2_empty USING (i)
----
10
query I
SELECT COUNT(*) FROM integers RIGHT JOIN integers2_empty USING (i)
----
0
query I
SELECT * FROM integers RIGHT JOIN integers2_empty USING (i)
----
query I
SELECT COUNT(*) FROM integers FULL OUTER JOIN integers2_empty USING (i)
----
10
query II
SELECT integers.*, integers2_empty.* FROM integers FULL OUTER JOIN integers2_empty USING (i)
----
0 NULL
1 NULL
2 NULL
3 NULL
4 NULL
5 NULL
6 NULL
7 NULL
8 NULL
9 NULL
# nested empty
query I
SELECT COUNT(*) FROM integers JOIN empty_join USING (i)
----
0
query I
SELECT COUNT(*) FROM integers LEFT JOIN empty_join USING (i)
----
10
query I
SELECT COUNT(*) FROM integers RIGHT JOIN empty_join USING (i)
----
0
query I
SELECT COUNT(*) FROM integers FULL OUTER JOIN empty_join USING (i)
----
10

View File

@@ -0,0 +1,51 @@
# name: test/sql/join/external/external_join_many_duplicates.test_slow
# description: Test external join with many duplicates in build side
# group: [external]
# runs out of memory occassionally on 32-bit machines
require 64bit
statement ok
pragma verify_external
statement ok
pragma verify_parallelism
statement ok
create table test1 as select concat(range::VARCHAR, 'x', repeat('7', 1)) i from range(100, 132)
statement ok
create table test2 as select concat(range::VARCHAR, 'x', repeat('7', 1)) i from range(100, 132)
statement ok
insert into test2 select range::VARCHAR i from range(1000000000000, 1000000100000)
query T
select count(*) from test1 join test2 using (i)
----
32
# 10M build side with many useless duplicates (stress tests the compare-and-swap pointer table construction)
statement ok
create sequence seq1 start 1000;
statement ok
create table t1 as select case
when range % 10000 = 0 then nextval('seq1')
else range % 1000 end as i
from range(10000000)
# 100M probe side
statement ok
create sequence seq2 start 1000;
statement ok
create table t2 as select case
when range % 100000 = 0 then nextval('seq2')
else range end as i
from range(100000000, 200000000)
query T
select count(*) from t1 join t2 using (i)
----
1000

View File

@@ -0,0 +1,36 @@
# name: test/sql/join/external/many_external_joins.test_slow
# description: Test many external joins (TemporaryMemoryManager)
# group: [external]
load __TEST_DIR__/many_external_joins.db
statement ok
CREATE TABLE tbl AS
SELECT range i,
range j
FROM range(10000000);
statement ok
SET threads=4;
# each HT should be around 400mb
statement ok
SET memory_limit='500mb';
# disable the join order optimizer to be sure we probe all HTs in a single pipeline
statement ok
SET disabled_optimizers TO 'join_order,build_side_probe_side';
# we shouldn't run out of memory
query IIIII
SELECT max(i),
max(t1.j),
max(t2.j),
max(t3.j),
max(t4.j),
FROM tbl AS t1
JOIN tbl AS t2 USING (i)
JOIN tbl AS t3 USING (i)
JOIN tbl AS t4 USING (i);
----
9999999 9999999 9999999 9999999 9999999

View File

@@ -0,0 +1,76 @@
# name: test/sql/join/external/simple_external_join.test_slow
# description: Test simple external join
# group: [external]
load __TEST_DIR__/simple_external_join.db
statement ok
create table t1 (i varchar)
statement ok
create table t2 (j varchar)
# Create tables with large string values so that strings aren't inlined
# The tables have some overlapping values to keep the join result small
statement ok
insert into t1 select concat(range::VARCHAR, repeat('0', 50)) i from range(1000000)
statement ok
insert into t2 select concat(range::VARCHAR, repeat('0', 50)) j from range(900000, 5000000)
# we want tight memory settings for the external joins
statement ok
pragma verify_parallelism
# with 1 thread we can do a tighter memory limit
statement ok
pragma threads=1
statement ok
pragma memory_limit='100mb'
query I
select count(*) from t1, t2 where i = j
----
100000
# now with more threads
statement ok
pragma threads=4
query I
select count(*) from t1, t2 where i = j
----
100000
# now trigger repartitioning
statement ok
pragma debug_force_external=true
# we need more memory for repartitioning
statement ok
pragma memory_limit='250mb'
query I
select count(*) from t1, t2 where i = j
----
100000
statement ok
pragma debug_force_external=false
# higher memory limit for this because the strings are so large
statement ok
pragma memory_limit='200mb'
# add some strings that are longer than Storage::BLOCK_SIZE
statement ok
insert into t1 select concat(range::VARCHAR, repeat('0', 300000)) i from range(10)
statement ok
insert into t2 select concat(range::VARCHAR, repeat('0', 300000)) i from range(99, -1, -1)
query T
select count(*) from t1, t2 where i = j
----
100010

View File

@@ -0,0 +1,37 @@
# name: test/sql/join/external/tpch_all_tables.test_slow
# description: Join all tables in TPC-H together under a tight memory limit
# group: [external]
load __TEST_DIR__/tpch_all_tables.db
require tpch
statement ok
CALL dbgen(sf=1)
statement ok
SET threads=4;
statement ok
SET memory_limit='1GB';
query IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
SELECT min(COLUMNS(*))
FROM customer c,
lineitem l,
nation n,
orders o,
part p,
partsupp ps,
region r,
supplier s
WHERE c.c_custkey = o.o_custkey
AND n.n_nationkey = c.c_nationkey
AND o.o_orderkey = l.l_orderkey
AND p.p_partkey = ps.ps_partkey
AND ps.ps_partkey = l.l_partkey
AND ps.ps_suppkey = l.l_suppkey
AND r.r_regionkey = n.n_regionkey
AND s.s_suppkey = ps.ps_suppkey
----
1 Customer#000000001 2Ksa,hc rgy7p 0 10-100-106-1617 -999.98 AUTOMOBILE Tiresias about the quickly express ideas detect quickly regular dependencies. even requests wake across the 1 1 1 1 1.00 901.00 0.00 0.00 A F 1992-01-02 1992-01-31 1992-01-04 COLLECT COD AIR Tiresias 0 ALGERIA 0 beans after the carefully regular accounts r 1 1 F 857.71 1992-01-01 1-URGENT Clerk#000000001 0 Tiresias about the quickly express ideas detect quickly regular depen 1 almond antique blue royal burnished Manufacturer#1 Brand#11 ECONOMY ANODIZED BRASS 1 JUMBO BAG 901.00 Tires 1 1 1 1.00 Tiresias about the carefully even packages detect quickly silent packages. ironic, pending ideas about the slyly unusual dolphins wake permanently package 0 AFRICA foxes boost furiously along the carefully dogged tithes. slyly regular orbits according to the special epit 1 Supplier#000000001 3TLxhVMgyjeZyud 0 10-102-116-6785 -998.22 Tiresias cajole final excuses. c

View File

@@ -0,0 +1,26 @@
# name: test/sql/join/full_outer/full_outer_join_cache.test
# description: Test full outer join with caches
# group: [full_outer]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE smalltable AS SELECT 1::INTEGER a;
# values 1...1024 10x
statement ok
CREATE TABLE bigtable AS SELECT a::INTEGER a FROM generate_series(0, 9999, 1) tbl(a), generate_series(0, 9, 1) tbl2(b);
query I
SELECT COUNT(*) FROM bigtable FULL OUTER JOIN smalltable USING (a)
----
100000
query I
SELECT COUNT(*) FROM bigtable RIGHT OUTER JOIN smalltable USING (a)
----
10

View File

@@ -0,0 +1,106 @@
# name: test/sql/join/full_outer/full_outer_join_union.test
# description: Test FULL OUTER JOIN with unions
# group: [full_outer]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER);
statement ok
INSERT INTO integers VALUES (1, 1), (3, 3);
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER);
statement ok
INSERT INTO integers2 VALUES (1, 10), (2, 20);
# equality join
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION ALL
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
ORDER BY i
----
NULL NULL 2 20
NULL NULL 2 20
1 1 1 10
1 1 1 10
3 3 NULL NULL
3 3 NULL NULL
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
ORDER BY i
----
NULL NULL 2 20
1 1 1 10
3 3 NULL NULL
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION
SELECT i+1, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION
SELECT i+2, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION
SELECT i+3, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION
SELECT i+4, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
ORDER BY 1,2,3,4
----
NULL NULL 2 20
1 1 1 10
2 1 1 10
3 1 1 10
3 3 NULL NULL
4 1 1 10
4 3 NULL NULL
5 1 1 10
5 3 NULL NULL
6 3 NULL NULL
7 3 NULL NULL
query IIII
SELECT DISTINCT * FROM (
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION ALL
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k) tbl
ORDER BY i
----
NULL NULL 2 20
1 1 1 10
3 3 NULL NULL
# many unions/full outer joins with views
statement ok
CREATE VIEW v1 AS
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
UNION ALL
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
query IIIIII
SELECT * FROM v1 FULL OUTER JOIN v1 v2 USING (i, j) ORDER BY 1, 2, 3, 4, 5, 6
----
NULL NULL NULL NULL 2 20
NULL NULL NULL NULL 2 20
NULL NULL 2 20 NULL NULL
NULL NULL 2 20 NULL NULL
1 1 1 10 1 10
1 1 1 10 1 10
1 1 1 10 1 10
1 1 1 10 1 10
3 3 NULL NULL NULL NULL
3 3 NULL NULL NULL NULL
3 3 NULL NULL NULL NULL
3 3 NULL NULL NULL NULL

View File

@@ -0,0 +1,57 @@
# name: test/sql/join/full_outer/test_full_outer_join.test
# description: Test FULL OUTER JOIN
# group: [full_outer]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
INSERT INTO integers VALUES (1, 1), (3, 3)
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER)
statement ok
INSERT INTO integers2 VALUES (1, 10), (2, 20)
# equality join
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k ORDER BY i
----
NULL NULL 2 20
1 1 1 10
3 3 NULL NULL
# equality join with additional non-equality predicate
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k AND integers.j > integers2.l ORDER BY 1, 2, 3, 4
----
NULL NULL 1 10
NULL NULL 2 20
1 1 NULL NULL
3 3 NULL NULL
# equality join with varchar values
query IIIT
SELECT i, j, k, l FROM integers FULL OUTER JOIN (SELECT k, l::VARCHAR AS l FROM integers2) integers2 ON integers.i=integers2.k ORDER BY 1, 2, 3, 4
----
NULL NULL 2 20
1 1 1 10
3 3 NULL NULL
# empty RHS
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN (SELECT * FROM integers2 WHERE 1=0) integers2 ON integers.i=integers2.k ORDER BY 1, 2, 3, 4
----
1 1 NULL NULL
3 3 NULL NULL

View File

@@ -0,0 +1,37 @@
# name: test/sql/join/full_outer/test_full_outer_join_complex.test
# description: Test complex FULL OUTER JOIN
# group: [full_outer]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
INSERT INTO integers VALUES (1, 1)
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER)
statement ok
INSERT INTO integers2 VALUES (1, 10)
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i+integers2.k+9<>integers.j+integers2.l ORDER BY 1, 2, 3, 4
----
NULL NULL 1 10
1 1 NULL NULL
# empty RHS
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN (SELECT * FROM integers2 WHERE 1=0) integers2 ON integers.i+integers2.k+9<>integers.j+integers2.l ORDER BY 1, 2, 3, 4
----
1 1 NULL NULL

View File

@@ -0,0 +1,37 @@
# name: test/sql/join/full_outer/test_full_outer_join_inequality.test
# description: Test inequality FULL OUTER JOIN
# group: [full_outer]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
INSERT INTO integers VALUES (1, 1)
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER)
statement ok
INSERT INTO integers2 VALUES (1, 10)
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i<>integers2.k ORDER BY 1, 2, 3, 4
----
NULL NULL 1 10
1 1 NULL NULL
# empty RHS
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN (SELECT * FROM integers2 WHERE 1=0) integers2 ON integers.i<>integers2.k ORDER BY 1, 2, 3, 4
----
1 1 NULL NULL

View File

@@ -0,0 +1,173 @@
# name: test/sql/join/full_outer/test_full_outer_join_issue_4252.test
# description: Test Issue: 4252
# group: [full_outer]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE test (x INT, y INT);
statement ok
INSERT INTO test VALUES (1, 1), (2, 2), (3, 3);
query II
SELECT * FROM (SELECT a2.x FROM (SELECT x FROM test WHERE x > 3) AS a1 FULL OUTER JOIN (SELECT x FROM test WHERE x = 1) AS a2 ON a1.x = a2.x) AS a3 FULL OUTER JOIN (SELECT 1 AS x) AS a4 ON a3.x = a4.x;
----
1 1
statement ok
CREATE TABLE df1(day DATE, value INTEGER, organization VARCHAR);
INSERT INTO df1 VALUES
('2022-01-01', 10, 'org1'),
('2022-01-05', 20, 'org2'),
('2022-01-10', 30, 'org3');
statement ok
CREATE TABLE df2(day DATE, value INTEGER, organization VARCHAR);
INSERT INTO df2 VALUES
('2022-01-01', 100, 'org1'),
('2022-09-01', 200, 'org2'),
('2022-03-01', 300, 'org3');
statement ok
CREATE TABLE df3(day DATE, value INTEGER, organization VARCHAR);
INSERT INTO df3 VALUES
('2022-01-02', 1000, 'org1'),
('2022-02-03', 2000, 'org2'),
('2022-04-01', 3000, 'org3');
query II
SELECT
coalesce(anon_1.month, anon_2.month) AS month,
coalesce(coalesce(CAST(anon_1.value AS REAL), 0.0) + coalesce(CAST(anon_2.value AS REAL), 0.0), 0.0) AS value
FROM (
SELECT coalesce(anon_3.month, anon_4.month) AS month,
coalesce(coalesce(CAST(anon_3.value AS REAL), 0.0) + coalesce(CAST(anon_4.value AS REAL), 0.0), 0.0) AS value
FROM (
SELECT month AS month, sum(anon_5.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df1
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
AND (organization ILIKE 'org4')
GROUP BY date_trunc('month', day)
) AS anon_5
GROUP BY GROUPING SETS((month))
) AS anon_3
FULL OUTER JOIN (
SELECT month AS month, sum(anon_6.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df2
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
GROUP BY date_trunc('month', day)
) AS anon_6
GROUP BY GROUPING SETS((month))
) AS anon_4 ON anon_3.month = anon_4.month
) AS anon_1
FULL OUTER JOIN (
SELECT month AS month, sum(anon_7.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df3
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
GROUP BY date_trunc('month', day)
) AS anon_7
GROUP BY GROUPING SETS((month))
) AS anon_2 ON anon_1.month = anon_2.month
----
2022-01-01 1100.0
query II
SELECT
coalesce(anon_1.month, anon_2.month) AS month,
coalesce(coalesce(CAST(anon_1.value AS REAL), 0.0) + coalesce(CAST(anon_2.value AS REAL), 0.0), 0.0) AS value
FROM (
SELECT coalesce(anon_3.month, anon_4.month) AS month,
coalesce(coalesce(CAST(anon_3.value AS REAL), 0.0) + coalesce(CAST(anon_4.value AS REAL), 0.0), 0.0) AS value
FROM (
SELECT month AS month, sum(anon_5.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df1
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
AND (organization ILIKE 'org1')
GROUP BY date_trunc('month', day)
) AS anon_5
GROUP BY GROUPING SETS((month))
) AS anon_3
FULL OUTER JOIN (
SELECT month AS month, sum(anon_6.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df2
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
GROUP BY date_trunc('month', day)
) AS anon_6
GROUP BY GROUPING SETS((month))
) AS anon_4 ON anon_3.month = anon_4.month
) AS anon_1
FULL OUTER JOIN (
SELECT month AS month, sum(anon_7.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df3
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
GROUP BY date_trunc('month', day)
) AS anon_7
GROUP BY GROUPING SETS((month))
) AS anon_2 ON anon_1.month = anon_2.month
----
2022-01-01 1110.0
query II
SELECT
coalesce(anon_1.month, anon_2.month) AS month,
coalesce(coalesce(CAST(anon_1.value AS REAL), 0.0) + coalesce(CAST(anon_2.value AS REAL), 0.0), 0.0) AS value
FROM (
SELECT coalesce(anon_3.month, anon_4.month) AS month,
coalesce(coalesce(CAST(anon_3.value AS REAL), 0.0) + coalesce(CAST(anon_4.value AS REAL), 0.0), 0.0) AS value
FROM (
SELECT month AS month, sum(anon_6.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df2
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
GROUP BY date_trunc('month', day)
) AS anon_6
GROUP BY GROUPING SETS((month))
) AS anon_3
FULL OUTER JOIN (
SELECT month AS month, sum(anon_5.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df1
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
AND (organization ILIKE 'org4')
GROUP BY date_trunc('month', day)
) AS anon_5
GROUP BY GROUPING SETS((month))
) AS anon_4 ON anon_3.month = anon_4.month
) AS anon_1
FULL OUTER JOIN (
SELECT month AS month, sum(anon_7.value) AS value
FROM (
SELECT date_trunc('month', day) AS month, coalesce(sum(value), 0.0) AS value
FROM df3
WHERE day >= CAST('2022-01-01 00:00:00' AS DATE)
AND day <= CAST('2022-01-31 00:00:00' AS DATE)
GROUP BY date_trunc('month', day)
) AS anon_7
GROUP BY GROUPING SETS((month))
) AS anon_2 ON anon_1.month = anon_2.month
----
2022-01-01 1100.0

View File

@@ -0,0 +1,65 @@
# name: test/sql/join/full_outer/test_full_outer_join_many_matches.test_slow
# description: Test FULL OUTER JOIN with many matches
# group: [full_outer]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
statement ok
PRAGMA verify_parallelism
statement ok
PRAGMA verify_external
statement ok
CREATE TABLE integers AS SELECT a i, 1 j FROM generate_series(0, 1999, 1) t1(a);
statement ok
CREATE TABLE integers2 AS SELECT a k, 2 l FROM generate_series(2000, 3999, 1) t1(a);
# equality join
query I
SELECT COUNT(*) FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k
----
4000
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.k ORDER BY 1, 2, 3, 4
----
16000 values hashing to 8b9eab043624ff470b00a981c1d588d9
# range join
query I
SELECT COUNT(*) FROM integers FULL OUTER JOIN integers2 ON integers.j>integers2.l
----
4000
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.j>integers2.l ORDER BY 1, 2, 3, 4
----
16000 values hashing to 8b9eab043624ff470b00a981c1d588d9
# inequality join
query I
SELECT COUNT(*) FROM integers FULL OUTER JOIN integers2 ON integers.j+1<>integers2.l;
----
4000
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.j+1<>integers2.l ORDER BY 1, 2, 3, 4
----
16000 values hashing to 8b9eab043624ff470b00a981c1d588d9
# complex join condition
query I
SELECT COUNT(*) FROM integers FULL OUTER JOIN integers2 ON integers.j+integers2.l<>3;
----
4000
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.j+integers2.l<>3 ORDER BY 1, 2, 3, 4
----
16000 values hashing to 8b9eab043624ff470b00a981c1d588d9

View File

@@ -0,0 +1,41 @@
# name: test/sql/join/full_outer/test_full_outer_join_parallel.test_slow
# description: Test full outer join with parallelism
# group: [full_outer]
statement ok
PRAGMA enable_verification
statement ok
PRAGMA threads=4
statement ok
PRAGMA verify_parallelism
statement ok
pragma verify_external
statement ok
CREATE TABLE integers AS SELECT * FROM range(75000) tbl(i);
statement ok
CREATE TABLE integers2 AS SELECT * FROM range(100000) tbl(i) WHERE i%2 != 0;
query I
SELECT COUNT(*) FROM integers JOIN integers2 ON integers.i=integers2.i
----
37500
query I
SELECT COUNT(*) FROM integers LEFT OUTER JOIN integers2 ON integers.i=integers2.i
----
75000
query I
SELECT COUNT(*) FROM integers RIGHT OUTER JOIN integers2 ON integers.i=integers2.i
----
50000
query I
SELECT COUNT(*) FROM integers FULL OUTER JOIN integers2 ON integers.i=integers2.i
----
87500

View File

@@ -0,0 +1,38 @@
# name: test/sql/join/full_outer/test_full_outer_join_range.test
# description: Test range FULL OUTER JOIN
# group: [full_outer]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
INSERT INTO integers VALUES (1, 1)
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER)
statement ok
INSERT INTO integers2 VALUES (1, 10)
# range join
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN integers2 ON integers.i<integers2.k ORDER BY 1, 2, 3, 4
----
NULL NULL 1 10
1 1 NULL NULL
# empty RHS
query IIII
SELECT i, j, k, l FROM integers FULL OUTER JOIN (SELECT * FROM integers2 WHERE 1=0) integers2 ON integers.i<integers2.k ORDER BY 1, 2, 3, 4
----
1 1 NULL NULL

View File

@@ -0,0 +1,570 @@
# name: test/sql/join/iejoin/iejoin_issue_6314.test_slow
# description: Issue #6314: Segmentation fault when joining on timestamp with BETWEEN
# group: [iejoin]
statement ok
SET merge_join_threshold=0
statement ok
create table ota as select timestamp '2019-04-25 14:10:00' + concat(15 * i, ' minutes')::interval as ts, (i * 5 % 100)::REAL AS val from generate_series(0,167136,1) t(i);
statement ok
CREATE TABLE flags("start" TIMESTAMP, "end" TIMESTAMP, source VARCHAR, "desc" VARCHAR);
statement ok
INSERT INTO flags VALUES('2019-04-27 06:57:07.210882','2019-05-03 11:47:17.59408','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-05-04 18:31:02.98257','2019-05-04 18:31:03.779477','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-05-06 05:39:26.004945','2019-05-06 05:39:26.239315','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-05-06 20:59:33.37157','2019-05-06 20:59:33.402848','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-05-06 21:14:39.389213','2019-05-06 21:14:39.389213','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-05-06 21:29:41.849197','2019-05-06 21:29:41.880455','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-05-06 23:15:11.014935','2019-05-08 07:04:17.679436','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-05-08 12:11:59.757938','2019-05-08 12:11:59.757938','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-05-10 18:10:50.543442','2019-05-17 03:24:07.564913','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-05-17 10:41:08.933154','2019-05-17 13:11:49.965971','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-05-18 09:40:48.393364','2019-05-22 06:23:59.900634','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-05-28 22:13:49.48383','2019-05-28 22:59:02.257043','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-05-28 23:29:10.768931','2019-05-30 16:09:22.471287','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-06-01 22:16:21.233545','2019-06-01 22:16:21.233545','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-06-03 15:34:27.135046','2019-06-09 04:45:09.435281','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-06-12 16:38:47.439035','2019-06-12 16:38:47.439035','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-06-17 02:38:42.389044','2019-06-18 20:50:36.829324','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-06-18 22:21:02.559667','2019-06-18 22:21:02.559667','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-06-19 18:43:23.96448','2019-07-09 19:57:32.802906','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-07-13 21:55:11.56286','2019-07-13 21:55:11.56286','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-07-16 00:54:34.577846','2019-07-27 11:54:57.069538','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-07-28 09:44:50.873531','2019-07-28 09:44:50.873531','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-07-29 04:30:55.210772','2019-07-29 04:30:55.210772','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-08-01 13:11:12.007762','2019-08-01 13:11:12.007762','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-08-01 20:53:00.104555','2019-08-10 12:22:04.507877','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-08-11 13:34:13.847871','2019-08-11 13:34:13.847871','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-08-12 03:11:45.616815','2019-08-16 12:04:04.771614','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-08-17 03:30:05.751071','2019-08-17 03:30:09.912299','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-08-17 10:18:52','2019-08-18 07:01:58.625201','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-08-18 07:09:41.725062','2019-08-18 07:09:41.725062','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-08-18 12:51:51.684778','2019-08-18 17:23:38.404315','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-08-18 17:27:33.87348','2019-08-19 12:48:02.813164','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-08-19 12:48:03.856232','2019-08-19 12:48:05.153111','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-08-19 13:03:05.546246','2019-08-19 13:03:07.014976','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-08-21 18:48:16.020933','2019-08-21 18:48:17.22906','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-08-21 22:04:12.155626','2019-08-24 20:54:10.580362','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-08-27 01:39:03.415172','2019-09-02 04:50:36.592331','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-02 08:09:54.450194','2019-09-02 08:09:54.450194','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-03 21:32:04.727393','2019-09-04 21:39:40.521211','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-05 01:09:51.078083','2019-09-05 15:59:02.204584','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-05 19:31:12.229758','2019-09-06 00:21:01.320128','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-07 06:39:57.02327','2019-09-07 11:46:21.22316','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-10 17:18:19.409298','2019-09-10 17:18:19.409298','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-11 22:11:24.748004','2019-09-11 22:11:24.748004','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-12 18:02:00.344891','2019-09-12 22:33:17.289047','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-16 08:26:23.586698','2019-09-16 15:13:18.378834','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-16 16:13:35.662604','2019-09-16 16:28:42.196364','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-16 16:43:44.276961','2019-09-16 20:29:47.941955','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-17 08:43:01.263386','2019-09-24 10:06:02.384592','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-24 13:06:51.610235','2019-09-24 13:06:51.610235','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-26 22:53:06.279389','2019-09-26 22:53:06.279389','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-27 23:45:10.455638','2019-09-28 01:45:41.915928','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-09-28 02:13:58.055097','2019-09-28 02:13:58.055097','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-09-28 05:31:47.220773','2019-09-28 05:31:47.220773','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-10-03 01:14:37.537529','2019-10-03 15:23:32','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-10-03 22:40:32','2019-10-03 22:40:32','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-10-09 15:03:43.289075','2019-10-14 17:43:43.628362','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-10-15 06:13:34.636141','2019-10-15 06:13:34.636141','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-10-16 08:37:10.770546','2019-10-17 18:40:28.77581','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-10-18 08:44:15.480474','2019-10-18 08:44:15.480474','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-10-19 02:04:31.517173','2019-10-28 01:24:39.438477','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-10-28 23:56:25.107861','2019-10-28 23:56:25.107861','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-10-30 21:21:25.340815','2019-11-28 14:04:27.737957','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2019-11-30 16:26:26.326418','2019-11-30 16:26:26.326418','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2019-12-02 03:24:55.442545','2020-01-01 05:06:22.828287','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-01 07:27:16.91793','2020-01-01 07:27:16.91793','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-01 08:21:57.443013','2020-01-02 09:26:22.480784','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-02 15:43:47.533201','2020-01-02 15:43:47.533201','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-03 00:59:06.971364','2020-01-04 16:05:59.965927','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-04 16:36:05.182976','2020-01-04 16:36:05.182976','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-04 22:22:05.185172','2020-01-05 07:08:38.487131','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-05 22:41:22.246919','2020-01-06 05:27:33.573642','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-06 06:12:41.794005','2020-01-06 12:13:45.006863','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-06 15:14:32','2020-01-06 15:44:22.120394','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-06 18:46:28.041729','2020-01-10 03:59:10.738719','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-10 13:10:34.79698','2020-01-10 13:10:34.79698','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-10 22:17:24.164384','2020-01-12 12:13:57.267754','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-13 03:33:05.485806','2020-01-13 03:33:05.485806','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-15 11:16:36.753327','2020-01-16 10:54:45.773417','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-16 11:35:55.106627','2020-01-16 11:35:55.106627','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-19 11:19:37.643996','2020-01-19 11:19:37.643996','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-20 12:24:24.969721','2020-01-20 12:24:24.969721','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-20 21:32:44.037711','2020-01-22 20:42:56.2408','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-01-23 10:32:58.520895','2020-01-24 03:16:26.692278','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-01-25 00:51:00.831728','2020-02-08 12:12:52.627855','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-02-08 14:48:40.089071','2020-02-08 16:03:54.498861','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-02-08 19:19:32.357072','2020-02-10 09:56:01.144206','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-02-10 11:26:18.500557','2020-02-10 11:26:18.500557','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-02-11 20:13:07.502813','2020-02-15 03:22:04.688344','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-02-15 21:35:30.422594','2020-02-15 21:35:30.422594','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-02-17 10:25:38','2020-03-09 03:09:52','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-03-09 18:25:52','2020-03-09 21:41:12','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-03-12 15:22:52','2020-03-15 04:48:32','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-03-16 06:59:56.26681','2020-03-16 06:59:56.26681','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-03-17 15:13:19.677282','2020-03-18 23:06:58.733077','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-03-21 00:03:09','2020-03-21 00:18:32','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-03-22 05:09:32','2020-04-30 14:47:32','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-04-30 21:38:25.38098','2020-04-30 21:38:25.38098','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-05-01 07:12:52','2020-05-01 22:57:02.230289','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-05-02 17:07:32','2020-05-02 17:07:32','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-05-05 16:25:30.373568','2020-06-07 21:39:38.313439','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-06-08 18:58:10.377347','2020-06-08 18:58:10.377347','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-06-09 15:37:00.810016','2020-07-10 12:34:10.196829','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-07-11 02:11:51.973322','2020-07-11 02:11:51.973322','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-07-23 20:11:20.543131','2020-07-27 01:05:09.67894','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-07-28 21:53:26.927383','2020-07-28 21:53:26.927383','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-07-29 08:52:32.951849','2020-07-31 07:44:09.401172','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-07-31 23:19:12.810416','2020-07-31 23:49:15.699364','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-08-01 01:14:16.073637','2020-09-12 02:34:29.675746','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-09-24 08:26:03.75682','2020-09-24 08:26:03.75682','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-09-25 23:33:02.184214','2020-11-08 21:19:55.639463','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-11-11 00:32:27.659817','2020-11-11 00:32:27.659817','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-11-11 11:53:28.539259','2020-11-12 12:52:03.847271','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-11-12 18:21:13.479285','2020-11-12 18:21:13.479285','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-11-15 07:59:17.818534','2020-12-20 20:04:42.477029','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2020-12-21 12:06:47.735826','2020-12-21 17:13:08.615317','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2020-12-25 01:43:20.82301','2021-01-14 12:38:40.256447','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-01-15 05:57:25.559778','2021-01-15 05:57:25.559778','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-01-15 17:08:49.239829','2021-03-04 18:05:06.5202','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-03-14 08:30:11.882031','2021-03-14 08:30:11.882031','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-03-14 19:34:35.48081','2021-03-14 19:34:35.48081','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-03-14 22:23:01.795492','2021-03-14 22:23:01.795492','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-03-19 05:18:59.392721','2021-04-17 17:00:28.56746','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-04-17 23:53:35.259154','2021-04-17 23:53:35.259154','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-04-19 11:43:30.867002','2021-04-19 11:43:30.867002','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-04-20 01:03:49.924386','2021-04-20 01:03:49.924386','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-04-21 20:38:53.726282','2021-05-27 03:12:22.242029','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-05-28 17:17:19.470759','2021-05-28 17:17:19.470759','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-05-29 03:51:39.812153','2021-07-03 17:56:45.710948','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-07-17 23:26:55.653867','2021-07-18 00:27:13.16734','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-07-20 19:46:11.260963','2021-08-14 23:02:07.889515','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-08-16 05:25:42.109359','2021-08-16 05:25:42.109359','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-08-17 13:55:39.394138','2021-12-08 09:37:20.089189','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2021-12-16 18:34:33.00649','2021-12-30 00:19:14.148858','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2021-12-31 13:43:59.460722','2022-01-01 15:02:51.580829','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-01-04 23:18:25.547204','2022-01-04 23:18:25.547204','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-01-11 17:02:04.353917','2022-01-11 17:02:04.353917','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-01-13 21:51:56.523581','2022-01-13 21:51:56.523581','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-02-03 08:43:22.323726','2022-02-12 00:49:09.124772','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-02-18 17:16:30.997815','2022-02-25 22:09:21.674881','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-03-05 09:08:58.713571','2022-03-05 09:08:58.713571','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-03-07 03:52:55.376109','2022-03-07 04:53:12.341127','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-03-27 07:54:31.78461','2022-04-10 20:02:46.477166','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-04-11 18:58:48.622832','2022-04-11 18:58:48.622832','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-04-23 00:44:15.138901','2022-05-04 22:45:57.516436','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-06-09 23:49:56.08389','2022-06-28 03:20:11.764959','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-07-05 12:24:17.554126','2022-07-24 12:10:50.921302','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-07-26 17:32:55.715266','2022-07-26 17:32:55.715266','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-09-12 01:05:19.825468','2022-09-15 09:12:55.833652','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-09-29 20:35:53.243062','2022-09-29 21:06:01.84773','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-11-01 23:59:37.478388','2022-12-04 15:01:19.792983','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-12-05 17:47:12.476835','2022-12-07 17:05:19.118935','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-12-09 14:25:41.405352','2022-12-09 14:25:41.405352','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2022-12-15 20:02:19.636018','2022-12-15 21:02:36.652083','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2022-12-27 12:59:35.191679','2022-12-29 01:19:07.640399','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2023-01-06 16:31:49.633328','2023-01-06 16:32:10.734747','legacy','2/11');
statement ok
INSERT INTO flags VALUES('2023-01-10 21:49:02.442825','2023-01-26 21:10:04.737504','legacy','2/0');
statement ok
INSERT INTO flags VALUES('2023-02-10 20:18:13.432147','2023-02-13 15:22:40.650655','legacy','2/11');
# INNER join
query II
EXPLAIN
SELECT ota.*, flags.desc as flag
FROM ota
INNER JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
----
physical_plan <REGEX>:.*IE_JOIN.*
statement ok
CREATE TABLE inner_join AS SELECT ota.*, flags.desc as flag
FROM ota
INNER JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
query III
SELECT COUNT(*), COUNT(ts), COUNT(flag) FROM inner_join
----
87775 87775 87775
# LEFT join
query II
EXPLAIN
SELECT ota.*, flags.desc as flag
FROM ota
LEFT JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
----
physical_plan <REGEX>:.*IE_JOIN.*
statement ok
CREATE TABLE left_join AS SELECT ota.*, flags.desc as flag
FROM ota
LEFT JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
query III
SELECT COUNT(*), COUNT(ts), COUNT(flag) FROM left_join
----
167137 167137 87775
# RIGHT join
query II
EXPLAIN
SELECT ota.*, flags.desc as flag
FROM ota
RIGHT JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
----
physical_plan <REGEX>:.*IE_JOIN.*
statement ok
CREATE TABLE right_join AS SELECT ota.*, flags.desc as flag
FROM ota
RIGHT JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
query III
SELECT COUNT(*), COUNT(ts), COUNT(flag) FROM right_join
----
87842 87775 87842
# FULL OUTER join
query II
EXPLAIN
SELECT ota.*, flags.desc as flag
FROM ota
FULL OUTER JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
----
physical_plan <REGEX>:.*IE_JOIN.*
statement ok
CREATE TABLE full_outer_join AS SELECT ota.*, flags.desc as flag
FROM ota
FULL OUTER JOIN flags ON ota.ts BETWEEN flags.start AND flags.end
ORDER BY ts;
query III
SELECT COUNT(*), COUNT(ts), COUNT(flag) FROM full_outer_join
----
167204 167137 87842

View File

@@ -0,0 +1,72 @@
# name: test/sql/join/iejoin/iejoin_issue_6861.test
# description: Issue #6861: Index out of bound for all-NULL case.
# group: [iejoin]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE test(x INT);
statement ok
SET merge_join_threshold=0
statement ok
SET nested_loop_join_threshold=0;
query II
SELECT *
FROM test AS a, test AS b
WHERE (a.x BETWEEN b.x AND b.x);
----
statement ok
INSERT INTO test(x) VALUES (1), (2), (3), (NULL), (NULL), (NULL);
statement ok
CREATE TABLE all_null AS SELECT * FROM test;
statement ok
UPDATE all_null SET x=(NULL);
query II
EXPLAIN
SELECT *
FROM all_null AS a, all_null AS b
WHERE (a.x BETWEEN b.x AND b.x);
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT *
FROM all_null AS a, all_null AS b
WHERE (a.x BETWEEN b.x AND b.x);
----
query II
EXPLAIN
SELECT *
FROM test AS a, all_null AS b
WHERE (a.x BETWEEN b.x AND b.x);
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT *
FROM test AS a, all_null AS b
WHERE (a.x BETWEEN b.x AND b.x);
----
query II
EXPLAIN
SELECT *
FROM all_null AS a, test AS b
WHERE (a.x BETWEEN b.x AND b.x);
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT *
FROM all_null AS a, test AS b
WHERE (a.x BETWEEN b.x AND b.x);
----

View File

@@ -0,0 +1,156 @@
# name: test/sql/join/iejoin/iejoin_issue_7278.test
# description: Issue #7278: Incorrect results (child pipeline / finish event scheduling
# group: [iejoin]
statement ok
pragma enable_verification
statement ok
SET merge_join_threshold=0
statement ok
create table calendar as
SELECT
start_ts,
start_ts + interval '12 hours' as end_ts,
date_part('year',start_ts)::bigint * 100 + date_part('week',start_ts)::bigint as yyyyww
FROM generate_series(TIMESTAMP '2023-01-01 06:00:00', TIMESTAMP '2023-06-01 00:00:00', INTERVAL '12 hours') tbl(start_ts)
;
statement ok
create table snapshot_data as
select
TIMESTAMP '2023-03-01 08:00:00' as snapshot_ts,
1 as snapshot_value
from generate_series(1,1000) t(i)
;
# IEJoin is disabled for CTEs for some reason
statement ok
create table cal_last_13 as(
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
);
query II
explain
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
----
physical_plan <REGEX>:.*IE_JOIN.*
query I
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
----
1000
statement ok
create or replace table cal_last_13 as (
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
union all
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
);
query II
explain
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
----
physical_plan <REGEX>:.*IE_JOIN.*
query I
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
----
2000
statement ok
create or replace table cal_last_13 as (
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
union all
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
union all
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
);
query II
explain
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
----
physical_plan <REGEX>:.*IE_JOIN.*
query I
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
----
3000
statement ok
create or replace table cal_last_13 as (
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
union all
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
union all
select * from calendar where yyyyww in (SELECT yyyyww
FROM calendar)
);
query II
explain
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
join cal_last_13 cal2
on data.snapshot_ts >= cal2.start_ts
and data.snapshot_ts <= cal2.end_ts
----
physical_plan <REGEX>:.*IE_JOIN.*
query I
select
count(*)
from snapshot_data data
join cal_last_13 cal
on data.snapshot_ts >= cal.start_ts
and data.snapshot_ts <= cal.end_ts
join cal_last_13 cal2
on data.snapshot_ts >= cal2.start_ts
and data.snapshot_ts <= cal2.end_ts
----
9000

View File

@@ -0,0 +1,58 @@
# name: test/sql/join/iejoin/iejoin_projection_maps.test
# description: Test IEJoin projection mapping
# group: [iejoin]
statement ok
PRAGMA threads=1
set seed 0.8765309
statement ok
CREATE TABLE df (id INTEGER, id2 INTEGER, id3 INTEGER, value_double DOUBLE, value as (value_double::DECIMAL(4,3)), one_min_value as ((1.0 - value_double)::DECIMAL(4,3)))
statement ok
INSERT INTO df
SELECT
(random() * 100)::INTEGER + 1 as id,
(random() * 10)::INTEGER + 1 as id2,
(random() * 5)::INTEGER + 1 as id3,
(ROUND(random(), 4)) as value_double,
FROM range(5000);
# Verify table contents
query IIIIII
SELECT SUM(id) AS id, SUM(id2) AS id2, SUM(id3) AS id3, SUM(value) AS sum_value, SUM(one_min_value) AS sum_one_min_value, sum_value + sum_one_min_value AS sum
FROM df
----
252652 29774 17657 2498.192 2502.191 5000.383
statement ok
PRAGMA enable_verification
# Test right_projection_map
foreach prefer False True
statement ok
PRAGMA prefer_range_joins=${prefer};
# mode output_hash
query I
SELECT id2, id3, id3_right, sum(value * value_right) as value
FROM (
SELECT df.*, df2.id3 as id3_right, df2.value as value_right
FROM df JOIN df as df2
ON (df.id = df2.id
AND df.id2 = df2.id2
AND df.id3 > df2.id3
AND df.id3 < df2.id3 + 30)
) tbl
GROUP BY ALL
ORDER BY ALL
----
660 values hashing to fe2237dbeb18fe3400d5323bcab26dd2
endloop
# Test left_projection_map
# (Once it can acutally happen...)

View File

@@ -0,0 +1,51 @@
# name: test/sql/join/iejoin/merge_join_switch.test
# description: Test switching between merge joins/IE joins/nested loop joins based on settings
# group: [iejoin]
statement ok
CREATE TABLE bigtbl AS FROM range(1000) t(i);
statement ok
CREATE TABLE smalltbl AS SELECT i AS low, i + 1 AS high FROM range(100) t(i);
statement ok
PRAGMA explain_output = 'PHYSICAL_ONLY';
statement ok
SET merge_join_threshold=0
query II
EXPLAIN SELECT COUNT(*) FROM bigtbl JOIN smalltbl ON (bigtbl.i BETWEEN low AND high)
----
physical_plan <REGEX>:.*IE_JOIN.*
statement ok
SET merge_join_threshold=1000
query II
EXPLAIN SELECT COUNT(*) FROM bigtbl JOIN smalltbl ON (bigtbl.i BETWEEN low AND high)
----
physical_plan <REGEX>:.*MERGE_JOIN.*
statement ok
SET nested_loop_join_threshold=1000
query II
EXPLAIN SELECT COUNT(*) FROM bigtbl JOIN smalltbl ON (bigtbl.i BETWEEN low AND high)
----
physical_plan <REGEX>:.*NESTED_LOOP_JOIN.*
statement ok
SET prefer_range_joins=true
query II
EXPLAIN
SELECT COUNT(*) FROM bigtbl JOIN smalltbl ON (bigtbl.i BETWEEN low AND high AND bigtbl.i IS NOT DISTINCT FROM high - low)
----
physical_plan <REGEX>:.*NESTED_LOOP_JOIN.*
# Execute to trigger the switch case
query I
SELECT COUNT(*) FROM bigtbl JOIN smalltbl ON (bigtbl.i BETWEEN low AND high AND bigtbl.i IS NOT DISTINCT FROM high - low)
----
2

View File

@@ -0,0 +1,5 @@
x,y
1,10
2,11
3,12
4,13
1 x y
2 1 10
3 2 11
4 3 12
5 4 13

View File

@@ -0,0 +1,5 @@
x,y
1,101
2,102
3,103
4,104
1 x y
2 1 101
3 2 102
4 3 103
5 4 104

View File

@@ -0,0 +1,109 @@
# name: test/sql/join/iejoin/predicate_expressions.test
# description: Predicate expressions should work with multiple chunks
# group: [iejoin]
statement ok
PRAGMA enable_verification
statement ok
SET merge_join_threshold=0
statement ok
PRAGMA explain_output = PHYSICAL_ONLY;
# Create a range of dates
statement ok
create table calendar as SELECT *
FROM range(DATE '2022-01-01', DATE '2024-02-01', INTERVAL '1' MONTH);
# Create an SCD2 dummy table with nullable end dates
statement ok
create table scd2 as
select
range as range_start,
case when date_part('year', range) < 2023 then range + interval 4 month - interval 1 day end as range_end,
n
from calendar
cross join generate_series(1, 85) as n
# Create an SCD2 dummy table with non-nullable end dates
statement ok
create table scd2_non_null as
select
range as range_start,
case when date_part('year', range) < 2023 then range + interval 4 month - interval 1 day else '2099-01-01' end as range_end,
n
from calendar
cross join generate_series(1, 85) as n
# Aggregate each table by using a range join
query II
explain
select
range,
count(*) as n
from scd2_non_null
inner join calendar
on range between range_start and ifnull(range_end,'2099-01-01')
group by range
order by range
----
physical_plan <REGEX>:.*IE_JOIN.*
query II nosort expected
select
range,
count(*) as n
from scd2_non_null
inner join calendar
on range between range_start and ifnull(range_end,'2099-01-01')
group by range
order by range
# First key should work
query II
explain
select
range,
count(*) as n
from scd2
inner join calendar
on range <= ifnull(range_end,'2099-01-01') and range_start <= range
group by range
order by range
----
physical_plan <REGEX>:.*IE_JOIN.*
query II nosort expected
select
range,
count(*) as n
from scd2
inner join calendar
on range <= ifnull(range_end,'2099-01-01') and range_start <= range
group by range
order by range
# Second key should work
query II
explain
select
range,
count(*) as n
from scd2
inner join calendar
on range between range_start and ifnull(range_end,'2099-01-01')
group by range
order by range
----
physical_plan <REGEX>:.*IE_JOIN.*
query II nosort expected
select
range,
count(*) as n
from scd2
inner join calendar
on range between range_start and ifnull(range_end,'2099-01-01')
group by range
order by range

View File

@@ -0,0 +1,201 @@
# name: test/sql/join/iejoin/test_iejoin.test
# description: Test IEJoin
# group: [iejoin]
statement ok
PRAGMA enable_verification
statement ok
SET merge_join_threshold=0
# Restrictive tail predicates
# Use inequalities to prevent future range choice optimisation
query II
WITH test AS (
SELECT
i AS id,
i AS begin,
i + 10 AS end,
i % 2 AS p1,
i % 3 AS p2
FROM range(0, 10) tbl(i)
)
SELECT lhs.id, rhs.id
FROM test lhs, test rhs
WHERE lhs.begin < rhs.end
AND rhs.begin < lhs.end
AND lhs.p1 <> rhs.p1
AND lhs.p2 <> rhs.p2
ORDER BY ALL
----
0 1
0 5
0 7
1 0
1 2
1 6
1 8
2 1
2 3
2 7
2 9
3 2
3 4
3 8
4 3
4 5
4 9
5 0
5 4
5 6
6 1
6 5
6 7
7 0
7 2
7 6
7 8
8 1
8 3
8 7
8 9
9 2
9 4
9 8
# Subquery/CTE
query II
WITH test AS (
SELECT
i AS id,
i AS begin,
i + 10 AS end,
i % 2 AS p1,
i % 3 AS p2
FROM range(0, 10) tbl(i)
),
sub AS (
SELECT lhs.id AS lid, rhs.id AS rid
FROM test lhs, test rhs
WHERE lhs.begin < rhs.end
AND rhs.begin < lhs.end
AND lhs.p1 <> rhs.p1
AND lhs.p2 <> rhs.p2
ORDER BY ALL
)
SELECT MIN(lid), MAX(rid)
FROM sub
----
0 9
# RTEs are not (yet) supported
# so this should work, but not trigger IEJoin in the physical plan.
query I
WITH RECURSIVE t AS
(
SELECT 1 AS x, 0 AS begin, 4 AS end
UNION ALL
SELECT lhs.x + 1 AS x,
GREATEST(lhs.begin, rhs.begin) as begin,
LEAST(lhs.end, rhs.end) AS end
FROM t lhs, t rhs
WHERE lhs.begin + 1 < rhs.end - 1
AND rhs.begin + 1 < lhs.end - 1
AND lhs.x < 3
)
SELECT COUNT(*) FROM t
----
3
# Fix missing continue statement in right join handler
statement ok
CREATE TABLE issue3486 AS
SELECT generate_series as ts from generate_series(timestamp '2020-01-01', timestamp '2021-01-01', interval 1 day);
query IIII
WITH data_table AS (
SELECT epoch(ts) as ts
FROM issue3486
WHERE ts IS NOT NULL
),
S AS (
SELECT
min(ts) as minVal,
max(ts) as maxVal,
(max(ts) - min(ts)) as range
FROM data_table
),
buckets AS (
SELECT
range as bucket,
(range) * (select range FROM S) / 40 + (select minVal from S) as low,
(range + 1) * (select range FROM S) / 40 + (select minVal from S) as high
FROM range(0, 40, 1)
)
SELECT
bucket,
low,
high,
count(data_table.ts) as count
FROM buckets
LEFT JOIN data_table ON (data_table.ts >= low AND data_table.ts < high)
GROUP BY bucket, low, high
ORDER BY bucket;
----
0 1577836800 1578627360 10
1 1578627360 1579417920 9
2 1579417920 1580208480 9
3 1580208480 1580999040 9
4 1580999040 1581789600 9
5 1581789600 1582580160 9
6 1582580160 1583370720 10
7 1583370720 1584161280 9
8 1584161280 1584951840 9
9 1584951840 1585742400 9
10 1585742400 1586532960 9
11 1586532960 1587323520 9
12 1587323520 1588114080 9
13 1588114080 1588904640 10
14 1588904640 1589695200 9
15 1589695200 1590485760 9
16 1590485760 1591276320 9
17 1591276320 1592066880 9
18 1592066880 1592857440 9
19 1592857440 1593648000 9
20 1593648000 1594438560 10
21 1594438560 1595229120 9
22 1595229120 1596019680 9
23 1596019680 1596810240 9
24 1596810240 1597600800 9
25 1597600800 1598391360 9
26 1598391360 1599181920 10
27 1599181920 1599972480 9
28 1599972480 1600763040 9
29 1600763040 1601553600 9
30 1601553600 1602344160 9
31 1602344160 1603134720 9
32 1603134720 1603925280 9
33 1603925280 1604715840 10
34 1604715840 1605506400 9
35 1605506400 1606296960 9
36 1606296960 1607087520 9
37 1607087520 1607878080 9
38 1607878080 1608668640 9
39 1608668640 1609459200 9
# internal issue 5197
statement ok
create table test_big as select range i, range + 100_000 j, 'hello' k from range (20_000)
statement ok
create table test_small as select range i, range + 100_000 j, 'hello' k from range (0,20_000,10)
statement ok
select *
from test_small t1
join test_small t2
on (t1.i = t2.j)
join test_small t3
on (true)
join test_big t4
on (t3.i < t4.i and t3.j > t4.j)

View File

@@ -0,0 +1,118 @@
# name: test/sql/join/iejoin/test_iejoin_east_west.test
# description: Test IEJoin
# group: [iejoin]
statement ok
PRAGMA enable_verification
statement ok
PRAGMA explain_output = PHYSICAL_ONLY;
statement ok
SET merge_join_threshold=0
statement ok
SET nested_loop_join_threshold=0;
# create tables
statement ok
CREATE TABLE east AS SELECT * FROM (VALUES
('r1', 100, 140, 12, 2),
('r2', 101, 100, 12, 8),
('r3', 103, 90, 5, 4)
) east(rid, id, dur, rev, cores)
statement ok
CREATE TABLE west AS SELECT * FROM (VALUES
('s1', 404, 100, 6, 4),
('s2', 498, 140, 11, 2),
('s3', 676, 80, 10, 1),
('s4', 742, 90, 5, 4)
) west(rid, t_id, time, cost, cores)
# Qs
query II
EXPLAIN
SELECT s1.rid, s2.rid
FROM west s1, west s2
WHERE s1.time > s2.time
ORDER BY 1, 2
----
physical_plan <REGEX>:.*PIECEWISE_MERGE_JOIN.*
query II
SELECT s1.rid, s2.rid
FROM west s1, west s2
WHERE s1.time > s2.time
ORDER BY 1, 2
----
s1 s3
s1 s4
s2 s1
s2 s3
s2 s4
s4 s3
# Qp
query II
EXPLAIN
SELECT s1.rid, s2.rid
FROM west s1, west s2
WHERE s1.time > s2.time AND s1.cost < s2.cost
ORDER BY 1, 2
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT s1.rid, s2.rid
FROM west s1, west s2
WHERE s1.time > s2.time AND s1.cost < s2.cost
ORDER BY 1, 2
----
s1 s3
s4 s3
# Qt
query II
EXPLAIN
SELECT east.rid, west.rid
FROM east, west
WHERE east.dur < west.time AND east.rev > west.cost
ORDER BY 1, 2
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT east.rid, west.rid
FROM east, west
WHERE east.dur < west.time AND east.rev > west.cost
ORDER BY 1, 2
----
r2 s2
# Test string comparisons
statement ok
CREATE TABLE weststr AS (
SELECT rid, time::VARCHAR AS time, cost::VARCHAR as cost
FROM west
);
query II
EXPLAIN
SELECT s1.rid, s2.rid
FROM weststr s1, weststr s2
WHERE s1.time > s2.time AND s1.cost < s2.cost
ORDER BY 1, 2
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT s1.rid, s2.rid
FROM weststr s1, weststr s2
WHERE s1.time > s2.time AND s1.cost < s2.cost
ORDER BY 1, 2
----
s2 s1
s3 s1
s3 s2
s4 s1

View File

@@ -0,0 +1,56 @@
# name: test/sql/join/iejoin/test_iejoin_events.test
# description: Test IEJoin
# group: [iejoin]
require skip_reload
# RNG order depends on vector size
require vector_size 1024
statement ok
PRAGMA enable_verification
statement ok
SET merge_join_threshold=0
# Use small 1K table to test Q2 because it melts down the other operators at larger scales
set seed 0.8675309
statement ok
CREATE TABLE events AS (
SELECT *,
"start" + INTERVAL (CASE WHEN random() < 0.1 THEN 120 ELSE (5 + round(random() * 50, 0)::BIGINT) END) MINUTE
AS "end"
FROM (
SELECT id,
'Event ' || id::VARCHAR as "name",
(5 + round(random() * 5000, 0)::BIGINT) AS audience,
'1992-01-01'::TIMESTAMP
+ INTERVAL (round(random() * 40 * 365, 0)::BIGINT) DAY
+ INTERVAL (round(random() * 23, 0)::BIGINT) HOUR
AS "start",
'Sponsor ' || (1 + round(random() * 10, 0)::BIGINT) AS sponsor
FROM range(1, 1000) tbl(id)
) q
);
query II
EXPLAIN
SELECT COUNT(*) FROM (
SELECT r.id, s.id
FROM events r, events s
WHERE r.start <= s.end AND r.end >= s.start
AND r.id <> s.id
) q2;
----
physical_plan <REGEX>:.*IE_JOIN.*
query I
SELECT COUNT(*) FROM (
SELECT r.id, s.id
FROM events r, events s
WHERE r.start <= s.end AND r.end >= s.start
AND r.id <> s.id
) q2;
----
2

View File

@@ -0,0 +1,89 @@
# name: test/sql/join/iejoin/test_iejoin_null_keys.test
# description: Issue #10122: wrong result in IEJoin
# group: [iejoin]
statement ok
pragma enable_verification
statement ok
PRAGMA explain_output = PHYSICAL_ONLY;
statement ok
SET merge_join_threshold=0
statement ok
SET nested_loop_join_threshold=0
statement ok
create table tt (x int, y int, z int);
statement ok
insert into tt select nullif(r % 3, 0), nullif (r % 5, 0), r from range(10) tbl(r);
query II
EXPLAIN
select *
from tt t1 left join tt t2
on t1.x < t2.x and t1.y < t2.y
order by t1.x nulls first, t1.y nulls first, t1.z, t2.x, t2.y, t2.z;
----
physical_plan <REGEX>:.*IE_JOIN.*
query IIIIII
select *
from tt t1 left join tt t2
on t1.x < t2.x and t1.y < t2.y
order by t1.x nulls first, t1.y nulls first, t1.z, t2.x, t2.y, t2.z;
----
NULL NULL 0 NULL NULL NULL
NULL 1 6 NULL NULL NULL
NULL 3 3 NULL NULL NULL
NULL 4 9 NULL NULL NULL
1 1 1 2 2 2
1 1 1 2 3 8
1 2 7 2 3 8
1 4 4 NULL NULL NULL
2 NULL 5 NULL NULL NULL
2 2 2 NULL NULL NULL
2 3 8 NULL NULL NULL
statement ok
pragma disable_optimizer;
statement ok
create table tt2 (x int);
statement ok
insert into tt2 select * from range(10);
query II
explain
select t1.x, t1.y
from (
select (case when x < 100 then null else 99 end) x, (case when x < 100 then 99 else 99 end) y
from tt2
) t1 left join tt2 t2
on t1.x < t2.x and t1.y < t2.x
order by t1.x nulls first, t1.y nulls first;
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
select t1.x, t1.y
from (
select (case when x < 100 then null else 99 end) x, (case when x < 100 then 99 else 99 end) y
from tt2
) t1 left join tt2 t2
on t1.x < t2.x and t1.y < t2.x
order by t1.x nulls first, t1.y nulls first;
----
NULL 99
NULL 99
NULL 99
NULL 99
NULL 99
NULL 99
NULL 99
NULL 99
NULL 99
NULL 99

View File

@@ -0,0 +1,46 @@
# name: test/sql/join/iejoin/test_iejoin_overlaps.test
# description: IEJoin block short circuiting
# group: [iejoin]
statement ok
PRAGMA enable_verification
statement ok
SET merge_join_threshold=0
statement ok
SET nested_loop_join_threshold=0;
statement ok
PRAGMA explain_output = PHYSICAL_ONLY;
# We read from CSVs to prevent the optimiser from
# using statistics to decide the join is a NOP
query II
EXPLAIN
SELECT t1.x, t2.x
FROM 'test/sql/join/iejoin/overlap.left.csv' t1, 'test/sql/join/iejoin/overlap.right.csv' t2
WHERE t1.x < t2.x AND t1.y > t2.y;
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT t1.x, t2.x
FROM 'test/sql/join/iejoin/overlap.left.csv' t1, 'test/sql/join/iejoin/overlap.right.csv' t2
WHERE t1.x < t2.x AND t1.y > t2.y;
----
# Reverse order to test op2 short circuit
query II
SELECT t1.x, t2.x
FROM 'test/sql/join/iejoin/overlap.left.csv' t1, 'test/sql/join/iejoin/overlap.right.csv' t2
WHERE t1.y > t2.y AND t1.x < t2.x;
----
query II
EXPLAIN
SELECT t1.x, t2.x
FROM 'test/sql/join/iejoin/overlap.left.csv' t1, 'test/sql/join/iejoin/overlap.right.csv' t2
WHERE t1.y > t2.y AND t1.x < t2.x;
----
physical_plan <REGEX>:.*IE_JOIN.*

View File

@@ -0,0 +1,50 @@
# name: test/sql/join/iejoin/test_iejoin_sort_tasks.test_slow
# description: Test IEJoin
# group: [iejoin]
# No verification - it doesn't scale
# Otherwise we run out of memory
require 64bit
statement ok
PRAGMA verify_parallelism
statement ok
SET merge_join_threshold=0
# Stream tables with minimal overlap that require merge tasks on both sides.
query II
EXPLAIN
SELECT lhs.begin, rhs.begin
FROM (
SELECT
i AS id,
i AS begin,
i + 1 AS end
FROM range(1, 10000002) tbl(i)) lhs,
(SELECT
i - 100000000 AS id,
i AS begin,
i + 1 AS end
FROM range(10000001, 20000002) tbl(i)) rhs
WHERE lhs.begin < rhs.end AND rhs.begin < lhs.end
----
physical_plan <REGEX>:.*IE_JOIN.*
query II
SELECT lhs.begin, rhs.begin
FROM (
SELECT
i AS id,
i AS begin,
i + 1 AS end
FROM range(1, 10000002) tbl(i)) lhs,
(SELECT
i - 100000000 AS id,
i AS begin,
i + 1 AS end
FROM range(10000001, 20000002) tbl(i)) rhs
WHERE lhs.begin < rhs.end AND rhs.begin < lhs.end
----
10000001 10000001

View File

@@ -0,0 +1,22 @@
# name: test/sql/join/inner/empty_tinyint_column.test
# description: Internal error on join of empty tinyint column
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE t1(c0 INT4, c1 VARCHAR);
statement ok
CREATE TABLE t2(c0 TINYINT, PRIMARY KEY(c0));
statement ok
INSERT INTO t1(c0) VALUES (14161972);
statement ok
INSERT INTO t1(c0, c1) VALUES (-1.438515327E9, 4.43806148E8);
query III
SELECT * FROM t1 INNER JOIN t2 ON t1.c0 = t2.c0;
----

View File

@@ -0,0 +1,231 @@
# name: test/sql/join/inner/equality_join_limits.test
# description: Test equality joins on numeric limits
# group: [inner]
statement ok
PRAGMA enable_verification
# TINYINT limits
statement ok
CREATE TABLE t(t_k0 TINYINT);
statement ok
INSERT INTO t VALUES (-128), (127);
statement ok
CREATE TABLE u(u_k0 TINYINT);
statement ok
INSERT INTO u VALUES (-128), (127);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
-128 -128
127 127
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# SMALLINT limits
statement ok
CREATE TABLE t(t_k0 SMALLINT);
statement ok
INSERT INTO t VALUES (-32768), (32767);
statement ok
CREATE TABLE u(u_k0 SMALLINT);
statement ok
INSERT INTO u VALUES (-32768), (32767);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
-32768 -32768
32767 32767
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# INTEGER limits
statement ok
CREATE TABLE t(t_k0 INTEGER);
statement ok
INSERT INTO t VALUES (-2147483648), (2147483647);
statement ok
CREATE TABLE u(u_k0 INTEGER);
statement ok
INSERT INTO u VALUES (-2147483648), (2147483647);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
-2147483648 -2147483648
2147483647 2147483647
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# BIGINT limits
statement ok
CREATE TABLE t(t_k0 BIGINT);
statement ok
INSERT INTO t VALUES (-9223372036854775808), (9223372036854775807);
statement ok
CREATE TABLE u(u_k0 BIGINT);
statement ok
INSERT INTO u VALUES (-9223372036854775808), (9223372036854775807);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
-9223372036854775808 -9223372036854775808
9223372036854775807 9223372036854775807
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# HUGEINT limits
statement ok
CREATE TABLE t(t_k0 HUGEINT);
statement ok
INSERT INTO t VALUES (-170141183460469231731687303715884105728), (170141183460469231731687303715884105727);
statement ok
CREATE TABLE u(u_k0 HUGEINT);
statement ok
INSERT INTO u VALUES (-170141183460469231731687303715884105728), (170141183460469231731687303715884105727);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
-170141183460469231731687303715884105728 -170141183460469231731687303715884105728
170141183460469231731687303715884105727 170141183460469231731687303715884105727
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# UTINYINT limits
statement ok
CREATE TABLE t(t_k0 UTINYINT);
statement ok
INSERT INTO t VALUES (0), (255);
statement ok
CREATE TABLE u(u_k0 UTINYINT);
statement ok
INSERT INTO u VALUES (0), (255);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
0 0
255 255
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# USMALLINT limits
statement ok
CREATE TABLE t(t_k0 USMALLINT);
statement ok
INSERT INTO t VALUES (0), (65535);
statement ok
CREATE TABLE u(u_k0 USMALLINT);
statement ok
INSERT INTO u VALUES (0), (65535);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
0 0
65535 65535
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# UINTEGER limits
statement ok
CREATE TABLE t(t_k0 UINTEGER);
statement ok
INSERT INTO t VALUES (0), (4294967295);
statement ok
CREATE TABLE u(u_k0 UINTEGER);
statement ok
INSERT INTO u VALUES (0), (4294967295);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
0 0
4294967295 4294967295
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;
# UBIGINT limits
statement ok
CREATE TABLE t(t_k0 UBIGINT);
statement ok
INSERT INTO t VALUES (0), (18446744073709551615);
statement ok
CREATE TABLE u(u_k0 UBIGINT);
statement ok
INSERT INTO u VALUES (0), (18446744073709551615);
query II rowsort
SELECT t_k0, u_k0 FROM t, u WHERE t_k0 = u_k0;
----
0 0
18446744073709551615 18446744073709551615
statement ok
DROP TABLE t;
statement ok
DROP TABLE u;

View File

@@ -0,0 +1,45 @@
# name: test/sql/join/inner/join_cache.test
# description: Test joins with few matches which should result in cache usage
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE smalltable AS SELECT 1::INTEGER a;
# values 1...1024 10x
statement ok
CREATE TABLE bigtable AS SELECT a::INTEGER a FROM generate_series(0, 10000, 1) tbl(a), generate_series(0, 9, 1) tbl2(b);
query I
SELECT COUNT(*) FROM bigtable JOIN smalltable USING (a)
----
10
query I
SELECT COUNT(*) FROM bigtable JOIN smalltable USING (a) JOIN smalltable t3 USING (a)
----
10
query I
SELECT COUNT(*) FROM bigtable JOIN smalltable USING (a) JOIN smalltable t3 USING (a) JOIN smalltable t4 USING (a);
----
10
query I
SELECT * FROM bigtable JOIN smalltable USING (a)
----
1
1
1
1
1
1
1
1
1
1

View File

@@ -0,0 +1,52 @@
# name: test/sql/join/inner/join_cross_product.test
# description: Test column binding in cross product of multiple joins
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
create table t1(i integer);
statement ok
create table t2(j integer);
statement ok
create table t3(k integer);
statement ok
create table t4(l integer);
statement ok
insert into t1 values (1);
statement ok
insert into t2 values (1);
statement ok
insert into t3 values (2), (3);
statement ok
insert into t4 values (2), (3);
query IIII
select * from t1 join t2 on (i=j), t3 join t4 on (k=l) order by 1, 2, 3, 4;
----
1 1 2 2
1 1 3 3
mode skip
# lateral join
query IIII rowsort
select * from t1 join t2 on (i=j), t3 join t4 on (i+k=j+l)
----
1 1 2 2
1 1 3 3
# postgres syntax
query IIII rowsort
select * from t1 join t2 on (i=j), lateral (select * from t3 join t4 on (i+k=j+l)) t(x);
----
1 1 2 2
1 1 3 3

View File

@@ -0,0 +1,21 @@
# name: test/sql/join/inner/list_join.test
# description: Join on large lists
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE test (id INTEGER, l VARCHAR[]);
statement ok
INSERT INTO test SELECT i, case when (i/1000)%2=0 then ARRAY[1::VARCHAR, 1::VARCHAR, 1::VARCHAR] else ARRAY[2::VARCHAR, 2::VARCHAR] end FROM generate_series(0, 1999, 1) tbl(i);
query IIII
SELECT * FROM test AS t1 LEFT JOIN test AS t2 ON t1.id=t2.id WHERE t1.l!=t2.l or t1.id!=t2.id;
----

View File

@@ -0,0 +1,22 @@
# name: test/sql/join/inner/not_between_is_null.test
# description: Test INNER JOIN with NOT BETWEEN and IS NULL conditions
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE t1(c0 INT);
CREATE TABLE t2(c0 INT);
statement ok
INSERT INTO t1(c0) VALUES (-18), (NULL);
statement ok
INSERT INTO t2(c0) VALUES (NULL);
query II
SELECT * FROM t1 INNER JOIN t2 ON ((t1.c0 NOT BETWEEN t2.c0 AND t2.c0) IS NULL);
----
-18 NULL
NULL NULL

View File

@@ -0,0 +1,131 @@
# name: test/sql/join/inner/test_eq_ineq_join.test
# description: Equality + inequality joins
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test VALUES (11, 1), (12, 2), (13, 3)
statement ok
CREATE TABLE test2 (a INTEGER, c INTEGER);
statement ok
INSERT INTO test2 VALUES (11, 1), (12, 1), (13, 4)
query III
SELECT test.a, b, c FROM test, test2 WHERE test.a = test2.a AND test.b <> test2.c ORDER BY test.a;
----
12 2 1
13 3 4
query III
SELECT test.a, b, c FROM test, test2 WHERE test.a = test2.a AND test.b < test2.c ORDER BY test.a;
----
13 3 4
query III
SELECT test.a, b, c FROM test, test2 WHERE test.a = test2.a AND test.b <= test2.c ORDER BY test.a;
----
11 1 1
13 3 4
query III
SELECT test.a, b, c FROM test, test2 WHERE test.a = test2.a AND test.b > test2.c ORDER BY test.a;
----
12 2 1
query III
SELECT test.a, b, c FROM test, test2 WHERE test.a = test2.a AND test.b >= test2.c ORDER BY test.a;
----
11 1 1
12 2 1
statement ok
DROP TABLE test;
statement ok
DROP TABLE test2;
# Equality + inequality anti and semi joins
statement ok
CREATE TABLE test (a INTEGER, b INTEGER, str VARCHAR);
statement ok
INSERT INTO test VALUES (11, 1, 'a'), (12, 2, 'b'), (13, 3, 'c')
statement ok
CREATE TABLE test2 (a INTEGER, c INTEGER, str2 VARCHAR);
statement ok
INSERT INTO test2 VALUES (11, 1, 'd'), (12, 1, 'e'), (13, 4, 'f')
query IIT
SELECT * FROM test WHERE EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<>test2.c) order by 2;
----
12 2 b
13 3 c
query IIT
SELECT * FROM test WHERE EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<>test2.c) AND NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<test2.c);
----
12 2 b
query IIT
SELECT * FROM test WHERE NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<test2.c) order by 1;
----
11 1 a
12 2 b
query IIT
SELECT * FROM test WHERE NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<test2.c) AND NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b>test2.c);
----
11 1 a
query IIT
SELECT * FROM test WHERE EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<>test2.c) AND test.a > 11 order by b;
----
12 2 b
13 3 c
statement ok
DROP TABLE test;
statement ok
DROP TABLE test2;
# Equality + inequality anti and semi joins with selection vector
statement ok
CREATE TABLE test (a INTEGER, b INTEGER, str VARCHAR);
statement ok
INSERT INTO test VALUES (11, 1, 'a'), (12, 2, 'b'), (13, 3, 'c')
statement ok
CREATE TABLE test2 (a INTEGER, c INTEGER, str2 VARCHAR);
statement ok
INSERT INTO test2 VALUES (11, 1, 'd'), (12, 1, 'e'), (13, 4, 'f')
query IIT
SELECT * FROM test WHERE NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<test2.c AND test2.a>14) AND NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b>test2.c AND test2.a<10) order by 1;
----
11 1 a
12 2 b
13 3 c
query IIT
SELECT * FROM test WHERE NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<test2.c AND test2.a=12) AND NOT EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b>test2.c AND test2.a=12) order by 1;
----
11 1 a
13 3 c
query IIT
SELECT * FROM test WHERE EXISTS(SELECT * FROM test2 WHERE test.a=test2.a AND test.b<>test2.c) AND test.a < 13;
----
12 2 b

View File

@@ -0,0 +1,104 @@
# name: test/sql/join/inner/test_join.test
# description: Test basic joins of tables
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test VALUES (11, 1), (12, 2), (13, 3)
statement ok
CREATE TABLE test2 (b INTEGER, c INTEGER);
statement ok
INSERT INTO test2 VALUES (1, 10), (1, 20), (2, 30)
# simple cross product + join condition
query III
SELECT a, test.b, c FROM test, test2 WHERE test.b = test2.b ORDER BY c;
----
11 1 10
11 1 20
12 2 30
# ambiguous reference to column
statement error
SELECT b FROM test, test2 WHERE test.b > test2.b;
----
# simple cross product + multiple join conditions
query III
SELECT a, test.b, c FROM test, test2 WHERE test.b=test2.b AND test.a-1=test2.c
----
11 1 10
# use join columns in subquery
query III
SELECT a, (SELECT test.a), c FROM test, test2 WHERE test.b = test2.b ORDER BY c;
----
11 11 10
11 11 20
12 12 30
# explicit join
query III
SELECT a, test.b, c FROM test INNER JOIN test2 ON test.b = test2.b ORDER BY c;
----
11 1 10
11 1 20
12 2 30
# explicit join with condition the wrong way around
query III
SELECT a, test.b, c FROM test INNER JOIN test2 ON test2.b = test.b ORDER BY c;
----
11 1 10
11 1 20
12 2 30
# explicit join with additional condition that is no left-right comparison
query III
SELECT a, test.b, c FROM test INNER JOIN test2 ON test2.b = test.b and test.b = 2;
----
12 2 30
# explicit join with additional condition that is constant
query III
SELECT a, test.b, c FROM test INNER JOIN test2 ON test2.b = test.b and 2 = 2 ORDER BY c;
----
11 1 10
11 1 20
12 2 30
# explicit join with only condition that is no left-right comparison
query III
SELECT a, test.b, c FROM test INNER JOIN test2 ON test.b = 2 ORDER BY c;
----
12 2 10
12 2 20
12 2 30
# explicit join with only condition that is constant
query III
SELECT a, test.b, c FROM test INNER JOIN test2 ON NULL = 2;
----
# equality join where both lhs and rhs keys are projected
query II
SELECT * FROM (VALUES (1)) tbl(i) JOIN (VALUES (1)) tbl2(j) ON (i=j);
----
1 1
# equality join where both lhs and rhs keys are projected with filter
query II
SELECT * FROM (VALUES (1), (2)) tbl(i) JOIN (VALUES (1), (2)) tbl2(j) ON (i=j) WHERE i+j=2;
----
1 1

View File

@@ -0,0 +1,32 @@
# name: test/sql/join/inner/test_join_duplicates.test
# description: Test join with > STANDARD_VECTOR_SIZE duplicates
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
pragma verify_parallelism
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test VALUES (11, 1), (12, 2), (13, 3)
statement ok
CREATE TABLE test2 AS SELECT * FROM repeat(1, 10*1024) t1(b), (SELECT 10) t2(c);
query I
SELECT COUNT(*) FROM test2;
----
10240
query I
SELECT COUNT(*) FROM test INNER JOIN test2 ON test.b=test2.b
----
10240

View File

@@ -0,0 +1,39 @@
# name: test/sql/join/inner/test_join_invisible_probe.test_slow
# description: Test joins that would generate a perfect hashtable
# group: [inner]
statement ok
PRAGMA enable_verification
# create the table integers with the values 0..1000
statement ok
CREATE TABLE test3 AS SELECT range r FROM range(0, 1024, 1);
statement ok
CREATE TABLE test4 AS SELECT range r FROM range(0, 1024, 1);
# START LOOP 0..10
loop i 0 9
statement ok
INSERT INTO test4 SELECT * FROM test3;
endloop
query I
select test3.r, test4.r from test3,test4 where test3.r=test4.r order by test3.r, test4.r;
----
20480 values hashing to 35ba7ce9ff11516c6ab6793a3bf802e4
loop i 0 90
statement ok
INSERT INTO test4 SELECT * FROM test3;
endloop
query I
select test3.r, test4.r from test3,test4 where test3.r=test4.r order by test3.r, test4.r;
----
204800 values hashing to 77cdae057078ab7ba8339275f564fac1

View File

@@ -0,0 +1,404 @@
# name: test/sql/join/inner/test_join_is_distinct.test
# description: Test using two join predicates, of which one is IS DISTINCT
# group: [inner]
# issue #8328
statement ok
PRAGMA enable_verification;
statement ok
CREATE TABLE tbl (col0 INTEGER, col1 INTEGER);
statement ok
INSERT INTO tbl VALUES (1, 0), (1, 1);
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1;
----
0 1
1 0
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1;
----
0 1
1 0
statement ok
INSERT INTO tbl VALUES (1, 0), (1, 1);
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1;
----
0 1
0 1
0 1
0 1
1 0
1 0
1 0
1 0
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1;
----
0 1
0 1
0 1
0 1
1 0
1 0
1 0
1 0
# same but with structs
statement ok
CREATE TABLE tbl_s (col0 STRUCT(x INTEGER), col1 STRUCT(x INTEGER));
statement ok
INSERT INTO tbl_s VALUES ({x: 1}, {x: 0}), ({x: 1}, {x: 1});
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1;
----
{'x': 0} {'x': 1}
{'x': 1} {'x': 0}
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1;
----
{'x': 0} {'x': 1}
{'x': 1} {'x': 0}
statement ok
INSERT INTO tbl_s VALUES ({x: 1}, {x: 0}), ({x: 1}, {x: 1});
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1;
----
{'x': 0} {'x': 1}
{'x': 0} {'x': 1}
{'x': 0} {'x': 1}
{'x': 0} {'x': 1}
{'x': 1} {'x': 0}
{'x': 1} {'x': 0}
{'x': 1} {'x': 0}
{'x': 1} {'x': 0}
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1;
----
{'x': 0} {'x': 1}
{'x': 0} {'x': 1}
{'x': 0} {'x': 1}
{'x': 0} {'x': 1}
{'x': 1} {'x': 0}
{'x': 1} {'x': 0}
{'x': 1} {'x': 0}
{'x': 1} {'x': 0}
# same but with lists
statement ok
CREATE TABLE tbl_l (col0 INTEGER[], col1 INTEGER[]);
statement ok
INSERT INTO tbl_l VALUES ([1], [0]), ([1], [1]);
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1;
----
[0] [1]
[1] [0]
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1;
----
[0] [1]
[1] [0]
statement ok
INSERT INTO tbl_l VALUES ([1], [0]), ([1], [1]);
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1;
----
[0] [1]
[0] [1]
[0] [1]
[0] [1]
[1] [0]
[1] [0]
[1] [0]
[1] [0]
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1;
----
[0] [1]
[0] [1]
[0] [1]
[0] [1]
[1] [0]
[1] [0]
[1] [0]
[1] [0]
query IIII
WITH abc AS (
SELECT * FROM (
VALUES (1, 'x'), (1, 'x'), (1, '0'), (1, '0')
) AS tbl(col0, col1)
)
SELECT x.col0 AS c1, x.col1 AS c2, y.col0 AS c3, y.col1 AS c4
FROM abc x JOIN abc y ON x.col0 = y.col0
AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY c1, c2, c3, c4;
----
1 0 1 x
1 0 1 x
1 0 1 x
1 0 1 x
1 x 1 0
1 x 1 0
1 x 1 0
1 x 1 0
# tests with NULLs
statement ok
CREATE TABLE tbl_null (col0 INTEGER, col1 INTEGER);
statement ok
INSERT INTO tbl_null VALUES (1, 0), (1, 1), (1, NULL), (NULL, 1), (0, NULL), (NULL, 0), (NULL, NULL);
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1, y.col1;
----
0 1
0 NULL
1 0
1 NULL
NULL 0
NULL 1
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1;
----
0 1
1 0
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
0 0
1 1
NULL NULL
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
0 0
1 1
# similar but with structs
statement ok
CREATE TABLE tbl_s_null (col0 STRUCT(x INTEGER), col1 STRUCT(x INTEGER));
statement ok
INSERT INTO tbl_s_null VALUES ({x: 1}, {x: 0}), ({x: 1}, {x: 1}), ({x: 1}, NULL), ({x: 1}, {x: NULL});
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1, y.col1 NULLS LAST;
----
{'x': 0} {'x': 1}
{'x': 0} {'x': NULL}
{'x': 0} NULL
{'x': 1} {'x': 0}
{'x': 1} {'x': NULL}
{'x': 1} NULL
{'x': NULL} {'x': 0}
{'x': NULL} {'x': 1}
{'x': NULL} NULL
NULL {'x': 0}
NULL {'x': 1}
NULL {'x': NULL}
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1.x, y.col1.x NULLS LAST;
----
{'x': 0} {'x': 1}
{'x': 0} {'x': NULL}
{'x': 1} {'x': 0}
{'x': 1} {'x': NULL}
{'x': NULL} {'x': 0}
{'x': NULL} {'x': 1}
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND x.col1 > y.col1
ORDER BY x.col1.x, y.col1.x NULLS LAST;
----
{'x': 1} {'x': 0}
{'x': NULL} {'x': 0}
{'x': NULL} {'x': 1}
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': NULL} {'x': NULL}
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': NULL} {'x': NULL}
# same but with lists
statement ok
CREATE TABLE tbl_l_null (col0 INTEGER[], col1 INTEGER[]);
statement ok
INSERT INTO tbl_l_null VALUES ([1], [0]), ([1], [1]), ([1], NULL), ([1], [NULL]);
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND (x.col1 IS DISTINCT FROM y.col1)
ORDER BY x.col1, y.col1;
----
[0] [1]
[0] [NULL]
[0] NULL
[1] [0]
[1] [NULL]
[1] NULL
[NULL] [0]
[NULL] [1]
[NULL] NULL
NULL [0]
NULL [1]
NULL [NULL]
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND x.col1 != y.col1
ORDER BY x.col1, y.col1 NULLS LAST;
----
[0] [1]
[0] [NULL]
[1] [0]
[1] [NULL]
[NULL] [0]
[NULL] [1]
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
[0] [0]
[1] [1]
[NULL] [NULL]
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
[0] [0]
[1] [1]
[NULL] [NULL]
# duckdb-r issue 8
statement ok
create table tb1 as select range*2 as a from range(100);
statement ok
create table tb2 as select range*4 as a from range(100);
statement ok
insert into tb2 (select NULL from range(20));
statement ok
insert into tb1 (select NULL from range(20));
query I
SELECT count(*) FROM tb1 AS lhs ANTI JOIN tb2 AS rhs ON (lhs.a IS DISTINCT FROM rhs.a);
----
0
# and some coverage
statement ok
create or replace table tb1 as select range*2 as a, range*50 as b from range(2);
statement ok
create or replace table tb2 as select range*4 as a, range*500 as b from range(2);
statement ok
insert into tb2 (select NULL, NULL from range(2));
statement ok
insert into tb1 (select NULL, NULL from range(2));
query II
SELECT lhs.a, rhs.a FROM tb1 AS lhs LEFT JOIN tb2 AS rhs ON (lhs.a IS DISTINCT FROM rhs.a) ORDER BY ALL;
----
0 4
0 NULL
0 NULL
2 0
2 4
2 NULL
2 NULL
NULL 0
NULL 0
NULL 4
NULL 4

View File

@@ -0,0 +1,375 @@
# name: test/sql/join/inner/test_join_is_not_distinct.test
# description: Test using two join predicates, of which one is IS NOT DISTINCT
# group: [inner]
# internal #5264
statement ok
PRAGMA enable_verification;
statement ok
CREATE TABLE tbl (col0 INTEGER, col1 INTEGER);
statement ok
INSERT INTO tbl VALUES (1, 0), (1, 1);
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
0 0
1 1
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
0 0
1 1
statement ok
INSERT INTO tbl VALUES (1, 0), (1, 1);
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
0 0
0 0
0 0
0 0
1 1
1 1
1 1
1 1
query II
SELECT x.col1, y.col1 FROM tbl x JOIN tbl y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
0 0
0 0
0 0
0 0
1 1
1 1
1 1
1 1
# same but with structs
statement ok
CREATE TABLE tbl_s (col0 STRUCT(x INTEGER), col1 STRUCT(x INTEGER));
statement ok
INSERT INTO tbl_s VALUES ({x: 1}, {x: 0}), ({x: 1}, {x: 1});
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
statement ok
INSERT INTO tbl_s VALUES ({x: 1}, {x: 0}), ({x: 1}, {x: 1});
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 0} {'x': 0}
{'x': 0} {'x': 0}
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': 1} {'x': 1}
{'x': 1} {'x': 1}
{'x': 1} {'x': 1}
query II
SELECT x.col1, y.col1 FROM tbl_s x JOIN tbl_s y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 0} {'x': 0}
{'x': 0} {'x': 0}
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': 1} {'x': 1}
{'x': 1} {'x': 1}
{'x': 1} {'x': 1}
# same but with lists
statement ok
CREATE TABLE tbl_l (col0 INTEGER[], col1 INTEGER[]);
statement ok
INSERT INTO tbl_l VALUES ([1], [0]), ([1], [1]);
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
[0] [0]
[1] [1]
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
[0] [0]
[1] [1]
statement ok
INSERT INTO tbl_l VALUES ([1], [0]), ([1], [1]);
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
[0] [0]
[0] [0]
[0] [0]
[0] [0]
[1] [1]
[1] [1]
[1] [1]
[1] [1]
query II
SELECT x.col1, y.col1 FROM tbl_l x JOIN tbl_l y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
[0] [0]
[0] [0]
[0] [0]
[0] [0]
[1] [1]
[1] [1]
[1] [1]
[1] [1]
query IIII
WITH abc AS (
SELECT * FROM (
VALUES (1, 'x'), (1, 'x'), (1, '0'), (1, '0')
) AS tbl(col0, col1)
)
SELECT x.col0 AS c1, x.col1 AS c2, y.col0 AS c3, y.col1 AS c4
FROM abc x JOIN abc y ON x.col0 = y.col0
AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY c1, c2, c3, c4;
----
1 0 1 0
1 0 1 0
1 0 1 0
1 0 1 0
1 x 1 x
1 x 1 x
1 x 1 x
1 x 1 x
# tests with NULLs
statement ok
CREATE TABLE tbl_null (col0 INTEGER, col1 INTEGER);
statement ok
INSERT INTO tbl_null VALUES (1, 0), (1, 1), (1, NULL), (NULL, 1), (0, NULL), (NULL, 0), (NULL, NULL);
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1, y.col1;
----
0 0
1 1
NULL NULL
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
0 0
1 1
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
0 0
1 1
NULL NULL
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_null x JOIN tbl_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
0 0
1 1
# similar but with structs
statement ok
CREATE TABLE tbl_s_null (col0 STRUCT(x INTEGER), col1 STRUCT(x INTEGER));
statement ok
INSERT INTO tbl_s_null VALUES ({x: 1}, {x: 0}), ({x: 1}, {x: 1}), ({x: 1}, NULL), ({x: 1}, {x: NULL});
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1, y.col1 NULLS LAST;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': NULL} {'x': NULL}
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1.x, y.col1.x NULLS LAST;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': NULL} {'x': NULL}
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND x.col1 > y.col1
ORDER BY x.col1.x, y.col1.x NULLS LAST;
----
{'x': 1} {'x': 0}
{'x': NULL} {'x': 0}
{'x': NULL} {'x': 1}
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': NULL} {'x': NULL}
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_s_null x JOIN tbl_s_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
{'x': 0} {'x': 0}
{'x': 1} {'x': 1}
{'x': NULL} {'x': NULL}
# same but with lists
statement ok
CREATE TABLE tbl_l_null (col0 INTEGER[], col1 INTEGER[]);
statement ok
INSERT INTO tbl_l_null VALUES ([1], [0]), ([1], [1]), ([1], NULL), ([1], [NULL]);
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1, y.col1;
----
[0] [0]
[1] [1]
[NULL] [NULL]
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1, y.col1 NULLS LAST;
----
[0] [0]
[1] [1]
[NULL] [NULL]
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND (x.col1 IS NOT DISTINCT FROM y.col1)
ORDER BY x.col1;
----
[0] [0]
[1] [1]
[NULL] [NULL]
NULL NULL
query II
SELECT x.col1, y.col1 FROM tbl_l_null x JOIN tbl_l_null y
ON x.col0 = y.col0 AND x.col1 = y.col1
ORDER BY x.col1;
----
[0] [0]
[1] [1]
[NULL] [NULL]
# duckdb-r issue 8
statement ok
create table tb1 as select range*2 as a from range(100);
statement ok
create table tb2 as select range*4 as a from range(100);
statement ok
insert into tb2 (select NULL from range(20));
statement ok
insert into tb1 (select NULL from range(20));
query I
SELECT count(*) FROM tb1 AS lhs ANTI JOIN tb2 AS rhs ON (lhs.a IS NOT DISTINCT FROM rhs.a);
----
50
# and some coverage
statement ok
create or replace table tb1 as select range*2 as a, range*50 as b from range(2);
statement ok
create or replace table tb2 as select range*4 as a, range*500 as b from range(2);
statement ok
insert into tb2 (select NULL, NULL from range(2));
statement ok
insert into tb1 (select NULL, NULL from range(2));
query II
SELECT lhs.a, rhs.a FROM tb1 AS lhs LEFT JOIN tb2 AS rhs ON (lhs.a IS NOT DISTINCT FROM rhs.a) ORDER BY ALL;
----
0 0
2 NULL
NULL NULL
NULL NULL
NULL NULL
NULL NULL

View File

@@ -0,0 +1,248 @@
# name: test/sql/join/inner/test_join_perfect_hash.test_slow
# description: Test joins that would generate a perfect hashtable
# group: [inner]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
foreach type <numeric> DECIMAL(4,0) DECIMAL(8,0) DECIMAL(16,0) DECIMAL(32,0)
statement ok
CREATE TABLE test1 (a ${type}, b ${type});
statement ok
INSERT INTO test1 VALUES (11, 1), (12, 2), (13, 3)
statement ok
CREATE TABLE test2 (b ${type}, c ${type});
statement ok
INSERT INTO test2 VALUES (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30)
# simple inner join
query III
SELECT a, test1.b,c FROM test1, test2 WHERE test1.b = test2.b order by a, test1.b,c;
----
11 1 10
11 1 10
11 1 10
11 1 10
11 1 10
12 2 20
12 2 20
12 2 20
12 2 20
12 2 20
13 3 30
13 3 30
13 3 30
13 3 30
13 3 30
statement ok
DROP TABLE test1;
statement ok
DROP TABLE test2;
endloop
foreach type TINYINT SMALLINT INTEGER BIGINT
statement ok
CREATE OR REPLACE TABLE test3 (a ${type}, b ${type});
statement ok
INSERT INTO test3 VALUES (-11, -1), (-12, -2), (13, 3)
statement ok
CREATE OR REPLACE TABLE test4 (b ${type}, c ${type});
statement ok
INSERT INTO test4 VALUES (-1, -10), (-2, -20), (3, 30), (-1, -10), (-2, -20), (3, 30), (-1, -10), (-2, -20), (3, 30), (-1, -10), (-2, -20), (3, 30), (-1, -10), (-2, -20), (3, 30)
# negative keys inner join
query III
SELECT a, test3.b,c FROM test3, test4 WHERE test3.b = test4.b order by a, test3.b,c ;
----
-12 -2 -20
-12 -2 -20
-12 -2 -20
-12 -2 -20
-12 -2 -20
-11 -1 -10
-11 -1 -10
-11 -1 -10
-11 -1 -10
-11 -1 -10
13 3 30
13 3 30
13 3 30
13 3 30
13 3 30
endloop
foreach type <integral>
statement ok
CREATE OR REPLACE TABLE test5 (a ${type}, b ${type});
statement ok
INSERT INTO test5 VALUES (11, 1), (12, 2), (13, 3), (14, null), (null, 4)
statement ok
CREATE OR REPLACE TABLE test6 (b ${type}, c ${type});
statement ok
INSERT INTO test6 VALUES (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (4, 40), (null, 30), (1, null)
# inner join with nulls in the build and probe side
query III
SELECT a, test5.b,c FROM test5, test6 WHERE test5.b = test6.b order by a, test5.b,c;
----
NULL 4 40
11 1 NULL
11 1 10
11 1 10
11 1 10
11 1 10
11 1 10
12 2 20
12 2 20
12 2 20
12 2 20
12 2 20
13 3 30
13 3 30
13 3 30
13 3 30
13 3 30
statement ok
CREATE OR REPLACE TABLE test7 (a ${type}, b ${type});
statement ok
INSERT INTO test7 VALUES (11, 1), (12, 2), (13, 3), (15, 5)
statement ok
CREATE OR REPLACE TABLE test8 (b ${type}, c ${type});
statement ok
INSERT INTO test8 VALUES (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (1, 10), (2, 20), (3, 30), (4, 40)
# inner join with non-matching keys in the build and in the probe side
query III
SELECT a, test7.b,c FROM test7, test8 WHERE test7.b = test8.b order by a, test7.b,c ;
----
11 1 10
11 1 10
11 1 10
11 1 10
11 1 10
12 2 20
12 2 20
12 2 20
12 2 20
12 2 20
13 3 30
13 3 30
13 3 30
13 3 30
13 3 30
endloop
# create the table integers with the values 0..1026
statement ok
CREATE TABLE test9 AS SELECT range r FROM range(0, 1026, 1);
statement ok
CREATE TABLE test10 AS SELECT range r FROM range(0, 1025, 1);
# START LOOP 0..9
loop i 0 9
statement ok
INSERT INTO test10 SELECT * FROM test9;
endloop
# inner join with bigger than vector size tuples
query I
select test9.r, test10.r from test9,test10 where test9.r=test10.r order by test9.r, test10.r;
----
20518 values hashing to 43cfa09ff243deb128dd2bbcbb30527c
statement ok
CREATE TABLE test11 (a INTEGER, b INTEGER);
statement ok
INSERT INTO test11 VALUES (1, 1), (50000, 2), (13, 3), (NULL, NULL), (NULL, 20000), (20000, NULL)
statement ok
CREATE TABLE test12 (b INTEGER, c INTEGER);
statement ok
INSERT INTO test12 VALUES (1, 10), (2, 20), (50000, 30), (NULL, NULL), (20000, NULL), (NULL, 20000)
# simple inner join
query III
SELECT a, test11.b,c FROM test11, test12 WHERE test11.b = test12.b order by a, test11.b,c;
----
NULL 20000 NULL
1 1 10
50000 2 20
statement ok
CREATE TABLE cohort (
cohort_definition_id INTEGER,
subject_id INTEGER,
cohort_start_date DATE,
cohort_end_date DATE,
);
statement ok
INSERT INTO cohort VALUES
(100, 1, '2002-12-25', '2002-12-25'),
(100, 1, '2007-03-01', '2007-03-01'),
(100, 2, '2003-03-01', '2003-03-01'),
(100, 2, '2005-03-01', '2005-03-01'),
;
statement ok
CREATE TABLE observation_period (
observation_period_id INTEGER,
person_id INTEGER,
observation_period_start_date DATE,
observation_period_end_date DATE,
period_type_concept_id INTEGER,
);
statement ok
INSERT INTO observation_period VALUES
(1, 1, '1963-12-31', '2010-01-01', 1),
(2, 2, '1963-12-31', '2010-01-01', 2),
;
# Statistics propagation with condition pruning
query IIIIIIII
select cohort_definition_id, subject_id, cohort_start_date, cohort_end_date, op1.observation_period_start_date, op1.observation_period_end_date,
tc1.cohort_start_date >= op1.observation_period_start_date as gt_test,
tc1.cohort_start_date <= op1.observation_period_end_date as lt_test
from main.cohort tc1
inner join main.observation_period op1
on tc1.subject_id = op1.person_id
and tc1.cohort_start_date >= op1.observation_period_start_date
and tc1.cohort_start_date <= op1.observation_period_end_date
where cohort_definition_id in (100) order by subject_id, cohort_start_date;
----
100 1 2002-12-25 2002-12-25 1963-12-31 2010-01-01 true true
100 1 2007-03-01 2007-03-01 1963-12-31 2010-01-01 true true
100 2 2003-03-01 2003-03-01 1963-12-31 2010-01-01 true true
100 2 2005-03-01 2005-03-01 1963-12-31 2010-01-01 true true

View File

@@ -0,0 +1,78 @@
# name: test/sql/join/inner/test_join_types.test_slow
# description: Test joins with different types
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
# numeric types
foreach type <numeric> decimal(4,1) decimal(8,1) decimal(12,1) decimal(18,1)
statement ok
begin transaction
statement ok
create table a as select i::${type} AS i from range(1, 101, 1) t1(i)
# range joins
query IR
select count(*), sum(i) from a, (SELECT 100::${type} AS j) b where i < j
----
99 4950.000000
query I
select count(*) from a, (SELECT 100::${type} AS j) b where i <= j
----
100
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i > j
----
99
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i >= j
----
100
# inequality join
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i <> j
----
99
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i <> j AND i=j
----
0
# equality join
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i = j
----
1
# no results on one side
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i > j AND i>120
----
0
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i <> j AND i>120
----
0
query I
select count(*) from a, (SELECT 1::${type} AS j) b where i = j AND i>120
----
0
statement ok
rollback
endloop

View File

@@ -0,0 +1,35 @@
# name: test/sql/join/inner/test_join_with_nulls.test_slow
# description: Test joins on uint64 columns with NULL values
# group: [inner]
set seed 0.42
statement ok
PRAGMA enable_verification
statement ok
PRAGMA disable_optimizer;
statement ok
CREATE OR REPLACE TABLE build AS (SELECT if(random() < 0.1,null, CAST(round(random() * 1_000_000) as INT64)) as key FROM range(1_000_000))
statement ok
CREATE OR REPLACE TABLE probe AS (SELECT if(random() < 0.1,null, CAST(round(random() * 1_000_000) as INT64)) as key FROM range(4_000_000))
query II
SELECT COUNT(*), SUM(probe.key) FROM probe JOIN build ON probe.key = build.key;
----
3239239 1617830750716
statement ok
CREATE OR REPLACE TABLE build2 AS (SELECT if(CAST(round(random() * 400_000) as INT64) < 10, null, CAST(round(random() * 400_000) as INT64)) as key FROM range(500_000));
query II
SELECT COUNT(*), SUM(probe.key) FROM probe JOIN build2 ON probe.key = build2.key;
----
1801809 360752228491
query II
SELECT COUNT(*), SUM(probe.key) FROM probe JOIN build2 ON probe.key IS NOT DISTINCT FROM build2.key;
----
5393349 360752228491

View File

@@ -0,0 +1,30 @@
# name: test/sql/join/inner/test_lt_join.test
# description: Test less than join
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
create table a AS SELECT i FROM range(1, 2001, 1) t1(i)
query I
select count(*) from a, (SELECT 2000 AS j) b where i < j
----
1999
query I
select count(*) from a, (SELECT 2000 AS j) b where i <= j
----
2000
query I
select count(*) from a, (SELECT 1 AS j) b where i > j
----
1999
query I
select count(*) from a, (SELECT 1 AS j) b where i >= j
----
2000

View File

@@ -0,0 +1,82 @@
# name: test/sql/join/inner/test_range_join.test
# description: Test range joins
# group: [inner]
statement ok
PRAGMA enable_verification
# create tables
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test VALUES (11, 1), (12, 2), (13, 3)
statement ok
CREATE TABLE test2 (b INTEGER, c INTEGER);
statement ok
INSERT INTO test2 VALUES (1, 10), (1, 20), (2, 30)
query II
SELECT test.b, test2.b FROM test, test2 WHERE test.b<test2.b
----
1 2
query II
SELECT test.b, test2.b FROM test, test2 WHERE test.b <= test2.b ORDER BY 1,2
----
1 1
1 1
1 2
2 2
# range join on multiple predicates
query IIII
SELECT test.a, test.b, test2.b, test2.c FROM test, test2 WHERE test.a>test2.c AND test.b <= test2.b
----
11 1 1 10
# introduce some NULL values
statement ok
INSERT INTO test VALUES (11, NULL), (NULL, 1)
# join result should be unchanged
query IIII
SELECT test.a, test.b, test2.b, test2.c FROM test, test2 WHERE test.a>test2.c AND test.b <= test2.b
----
11 1 1 10
# on the RHS as well
statement ok
INSERT INTO test2 VALUES (1, NULL), (NULL, 10)
# join result should be unchanged
query IIII
SELECT test.a, test.b, test2.b, test2.c FROM test, test2 WHERE test.a>test2.c AND test.b <= test2.b
----
11 1 1 10
# Forced external
statement ok
PRAGMA debug_force_external=true;
# In memory unswizzling
statement ok
CREATE TABLE issue4419 (x INT, y VARCHAR);
statement ok
INSERT INTO issue4419 VALUES (1, 'sssssssssssssssssueufuheuooefef');
statement ok
INSERT INTO issue4419 VALUES (2, 'sssssssssssssssssueufuheuooefesffff');
statement ok
INSERT INTO issue4419 VALUES (2, 'sssssssssssssssssueufuheuooefesffffsssssssieiffih');
query IIII
SELECT * FROM issue4419 t1 INNER JOIN issue4419 t2 ON t1.x < t2.x;
----
1 sssssssssssssssssueufuheuooefef 2 sssssssssssssssssueufuheuooefesffff
1 sssssssssssssssssueufuheuooefef 2 sssssssssssssssssueufuheuooefesffffsssssssieiffih

View File

@@ -0,0 +1,83 @@
# name: test/sql/join/inner/test_unequal_join.test
# description: Test inequality join
# group: [inner]
statement ok
PRAGMA enable_verification
# create tables
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test VALUES (11, 1), (12, 2), (13, 3)
statement ok
CREATE TABLE test2 (b INTEGER, c INTEGER);
statement ok
INSERT INTO test2 VALUES (1, 10), (1, 20), (2, 30)
# inequality join
query II
SELECT test.b, test2.b FROM test, test2 WHERE test.b <> test2.b ORDER BY test.b, test2.b
----
1 2
2 1
2 1
3 1
3 1
3 2
# inequality join with filter
query II
SELECT test.b, test2.b FROM test, test2 WHERE test.b <> test2.b AND test.b <> 1 AND test2.b <> 2 ORDER BY test.b, test2.b
----
2 1
2 1
3 1
3 1
statement ok
INSERT INTO test VALUES (NULL, NULL)
statement ok
INSERT INTO test2 VALUES (NULL, NULL)
# inequality join with NULL values
query II
SELECT test.b, test2.b FROM test, test2 WHERE test.b <> test2.b ORDER BY test.b, test2.b
----
1 2
2 1
2 1
3 1
3 1
3 2
# inequality join with filter and NULL values
query II
SELECT test.b, test2.b FROM test, test2 WHERE test.b <> test2.b AND test.b <> 1 AND test2.b <> 2 ORDER BY test.b, test2.b
----
2 1
2 1
3 1
3 1
statement ok
create table a (i integer)
statement ok
insert into a values ('28579'),('16098'),('25281'),('28877'),('18048'),('26820'),('26971'),('22812'),('11757'),('21851'),('27752'),('28354'),('29843'),('28828'),('16668'),('20534'),('28222'),('24244'),('28877'),('20150'),('23451'),('23683'),('20419'),('28048'),('24244'),('28605'),('25752'),('24466'),('26557'),('16098'),('29454'),('24854'),('13298'),('29584'),('13394'),('24843'),('22477'),('14593'),('24244'),('28722'),('25124'),('16668'),('26787'),('28877'),('27752'),('28482'),('24408'),('25752'),('24136'),('28222'),('17683'),('24244'),('19275'),('21087'),('26594'),('22293'),('25281'),('12898'),('23451'),('12898'),('21757'),('20965'),('25709'),('26614'),('10399'),('28773'),('11933'),('29584'),('29003'),('26871'),('17746'),('24092'),('26192'),('19310'),('10965'),('29275'),('20191'),('29101'),('28059'),('29584'),('20399'),('24338'),('26192'),('25124'),('28605'),('13003'),('16668'),('23511'),('26534'),('24107')
statement ok
create table b (j integer)
statement ok
insert into b values ('31904'),('31904'),('31904'),('31904'),('35709'),('31904'),('31904'),('35709'),('31904'),('31904'),('31904'),('31904')
query I
select count(*) from a,b where i <> j
----
1080

View File

@@ -0,0 +1,26 @@
# name: test/sql/join/inner/test_unequal_join_duplicates.test
# description: Test inequality join with > STANDARD_VECTOR_SIZE duplicates
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE test (b INTEGER);
statement ok
INSERT INTO test VALUES (1), (2)
statement ok
CREATE TABLE test2 AS SELECT * FROM repeat(1, 10*1024) t1(b);
query I
SELECT COUNT(*) FROM test2;
----
10240
query I
SELECT COUNT(*) FROM test INNER JOIN test2 ON test.b<>test2.b
----
10240

View File

@@ -0,0 +1,75 @@
# name: test/sql/join/inner/test_using_chain.test
# description: Test chaining USING joins
# group: [inner]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE t1 (a INTEGER, b INTEGER)
statement ok
INSERT INTO t1 VALUES (1, 2)
statement ok
CREATE TABLE t2 (b INTEGER, c INTEGER)
statement ok
INSERT INTO t2 VALUES (2, 3)
statement ok
CREATE TABLE t3 (c INTEGER, d INTEGER)
statement ok
INSERT INTO t3 VALUES (3, 4)
# multiple joins with using
# single column
query IIII
SELECT * FROM t1 JOIN t2 USING (b) JOIN t3 USING (c) ORDER BY 1, 2, 3, 4;
----
1 2 3 4
# column does not exist on left side of join
statement error
SELECT * FROM t1 JOIN t2 USING (c)
----
# column does not exist on right side of join
statement error
SELECT * FROM t1 JOIN t2 USING (a)
----
statement ok
DROP TABLE t1
statement ok
DROP TABLE t2
statement ok
DROP TABLE t3
statement ok
CREATE TABLE t1 (a INTEGER, b INTEGER, c INTEGER)
statement ok
INSERT INTO t1 VALUES (1, 2, 2)
statement ok
CREATE TABLE t2 (b INTEGER, c INTEGER, d INTEGER, e INTEGER)
statement ok
INSERT INTO t2 VALUES (2, 2, 3, 4)
statement ok
CREATE TABLE t3 (d INTEGER, e INTEGER)
statement ok
INSERT INTO t3 VALUES (3, 4)
# multi column
query IIIII
SELECT * FROM t1 JOIN t2 USING (b, c) JOIN t3 USING (d, e);
----
1 2 2 3 4

View File

@@ -0,0 +1,102 @@
# name: test/sql/join/inner/test_using_join.test
# description: Test USING joins
# group: [inner]
statement ok
PRAGMA enable_verification
# create tables
statement ok
CREATE TABLE t1 (a INTEGER, b INTEGER, c INTEGER);
statement ok
INSERT INTO t1 VALUES (1,2,3);
statement ok
CREATE TABLE t2 (a INTEGER, b INTEGER, c INTEGER);
statement ok
INSERT INTO t2 VALUES (1,2,3), (2,2,4), (1,3,4);
query IIIIIII
SELECT * FROM t1 JOIN t2 USING(a) JOIN t2 t2b USING (a) ORDER BY 1, 2, 3, 4, 5, 6, 7;
----
1 2 3 2 3 2 3
1 2 3 2 3 3 4
1 2 3 3 4 2 3
1 2 3 3 4 3 4
# USING join
query III
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING(a) ORDER BY t2.b
----
1 2 3
1 3 4
query III
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING(b) ORDER BY t2.c
----
1 2 3
2 2 4
query III
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING(a,b)
----
1 2 3
query III
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING(a,b,c)
----
1 2 3
# USING columns can be used without requiring a table specifier
query I
SELECT a+1 FROM t1 JOIN t2 USING(a) ORDER BY a
----
2
2
statement error
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING(a+b)
----
Parser Error: syntax error at or near "+"
statement error
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING("")
----
Parser Error: zero-length delimited identifier at or near """"
statement error
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING(d)
----
statement error
SELECT t2.a, t2.b, t2.c FROM t1 JOIN t2 USING(t1.a)
----
Parser Error: syntax error at or near "."
query IIII
SELECT * FROM t1 JOIN t2 USING(a,b)
----
1 2 3 3
# CONTROVERSIAL:
# we do not allow this because it is ambiguous: "b" can be bind to both "t1.b" or "t2.b" and this would give
# different results SQLite allows this, PostgreSQL does not
statement error
SELECT * FROM t1 JOIN t2 USING(a) JOIN t2 t2b USING (b);
----
# this is the same, but now with a duplicate potential binding on the RHS
statement error
select * from (values (1)) tbl(i) join ((values (1)) tbl2(i) join (values (1)) tbl3(i) on tbl2.i=tbl3.i) using (i)
----
# a chain with the same column name is allowed though!
query IIIIIII
SELECT * FROM t1 JOIN t2 USING(a) JOIN t2 t2b USING (a) ORDER BY 1, 2, 3, 4, 5, 6, 7
----
1 2 3 2 3 2 3
1 2 3 2 3 3 4
1 2 3 3 4 2 3
1 2 3 3 4 3 4

View File

@@ -0,0 +1,27 @@
# name: test/sql/join/inner/test_varchar_join.test
# description: Test joins on VARCHAR columns with NULL values
# group: [inner]
statement ok
PRAGMA enable_verification
query TT
select * from (select NULL::varchar as b) sq1, (select 'asdf' as b) sq2 where sq1.b = sq2.b;
----
query ITIT
select * from (select 42 as a, NULL::varchar as b) sq1, (select 42 as a, 'asdf' as b) sq2 where sq1.b <> sq2.b;
----
query ITIT
select * from (select 42 as a, NULL::varchar as b) sq1, (select 42 as a, 'asdf' as b) sq2 where sq1.a=sq2.a and sq1.b <> sq2.b;
----
query ITIT
select * from (select 42 as a, 'asdf' as b) sq2, (select 42 as a, NULL::varchar as b) sq1 where sq1.b <> sq2.b;
----
query ITIT
select * from (select 42 as a, 'asdf' as b) sq2, (select 42 as a, NULL::varchar as b) sq1 where sq1.a=sq2.a and sq1.b <> sq2.b;
----

View File

@@ -0,0 +1,139 @@
# name: test/sql/join/left_outer/left_join_issue_1172.test
# description: Left Outer join dropping rows
# group: [left_outer]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
drop table if exists t1;
statement ok
drop table if exists t2;
statement ok
create table t1 (id string);
statement ok
create table t2 (id string);
statement ok
insert into t1 values
(NULL);
statement ok
insert into t2 values (1), (1);
query II
select * from t1 left join t2 on t1.id = t2.id;
----
NULL NULL
query II
select * from t1 left join t2 on t1.id > t2.id;
----
NULL NULL
query II
select * from t1 left join t2 on t1.id <> t2.id;
----
NULL NULL
statement ok
insert into t2 values (1);
query II
select * from t1 left join t2 on t1.id = t2.id;
----
NULL NULL
query II
select * from t1 left join t2 on t1.id > t2.id;
----
NULL NULL
query II
select * from t1 left join t2 on t1.id <> t2.id;
----
NULL NULL
statement ok
insert into t2 values (NULL), (NULL);
query II
select * from t1 left join t2 on t1.id = t2.id;
----
NULL NULL
query II
select * from t1 left join t2 on t1.id > t2.id;
----
NULL NULL
query II
select * from t1 left join t2 on t1.id <> t2.id;
----
NULL NULL
statement ok
drop table if exists t1;
statement ok
drop table if exists t2;
statement ok
create table t1 (id string);
statement ok
create table t2 (id string);
statement ok
insert into t1 (id) values (1), (1), (NULL);
statement ok
insert into t2 (id) values (1), (1), (1), (1), (1), (1);
query II
select * from t1 left join t2 on t1.id = t2.id order by 1, 2;
----
NULL NULL
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
statement ok
insert into t2 (id) values (1);
query II
select * from t1 left join t2 on t1.id = t2.id order by 1, 2;
----
NULL NULL
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1
1 1

View File

@@ -0,0 +1,53 @@
# name: test/sql/join/left_outer/left_join_issue_15316.test
# description: Issue #15316: Left join should strip tree if filter statically evaluates to false
# group: [left_outer]
statement ok
set explain_output='optimized_only';
statement ok
PRAGMA enable_verification
statement ok
CREATE OR REPLACE TABLE big_table AS
SELECT i.range AS col1,
CAST(random() * 1000 AS INTEGER) AS col2
FROM range(100) i;
statement ok
CREATE OR REPLACE TABLE single_col_table AS
SELECT i.range AS col1
FROM range(50) i;
query II
explain SELECT *
FROM big_table c
LEFT OUTER JOIN single_col_table hd ON hd.col1=c.col1
AND (
FALSE
);
----
logical_opt <REGEX>:.*CROSS_PRODUCT.*
# RHS contains multiple tables
statement ok
CREATE TABLE integers1 AS SELECT * FROM (VALUES (1), (2), (3)) tbl(i);
statement ok
CREATE TABLE integers2 AS SELECT * FROM (VALUES (1, '1'), (2, '2'), (3, '3')) tbl(i, s);
statement ok
CREATE TABLE integers3 AS SELECT * FROM (VALUES (1, '4'), (2, '5'), (3, '6')) tbl(i, s);
query III
SELECT
i1.i AS i1_i,
i2.s,
i3.i AS i3_i
FROM
integers1 i1
LEFT OUTER JOIN (integers2 i2 LEFT OUTER JOIN integers3 i3 ON i2.i = i3.i) on false;
----
1 NULL NULL
2 NULL NULL
3 NULL NULL

View File

@@ -0,0 +1,37 @@
# name: test/sql/join/left_outer/left_join_issue_6341.test
# description: Issue #6341: No rows returned in LEFT JOIN with < or > against table having no rows
# group: [left_outer]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE foo (ts TIMESTAMP);
statement ok
CREATE TABLE bar (ts TIMESTAMP);
statement ok
INSERT INTO foo VALUES ('2023-01-01 00:00:00');
statement ok
INSERT INTO foo VALUES ('2023-01-01 00:00:01');
query II rowsort
SELECT foo.ts foo, bar.ts bar FROM foo LEFT JOIN bar ON foo.ts = bar.ts;
----
2023-01-01 00:00:00 NULL
2023-01-01 00:00:01 NULL
query II rowsort
SELECT foo.ts foo, bar.ts bar FROM foo LEFT JOIN bar ON foo.ts < bar.ts;
----
2023-01-01 00:00:00 NULL
2023-01-01 00:00:01 NULL
query II rowsort
SELECT foo.ts foo, bar.ts bar FROM foo LEFT JOIN bar ON foo.ts > bar.ts;
----
2023-01-01 00:00:00 NULL
2023-01-01 00:00:01 NULL

View File

@@ -0,0 +1,47 @@
# name: test/sql/join/left_outer/left_join_issue_7905.test
# description: Issue #7905: DuckDB fails with INTERNAL Error: Logical column index 11 out of range
# group: [left_outer]
statement ok
CREATE TABLE a(a1 VARCHAR);
statement ok
CREATE TABLE b(
b1 VARCHAR,
b2 TIMESTAMP,
b3 TIMESTAMP,
b4 VARCHAR,
b5 VARCHAR,
b6 VARCHAR,
b7 TIMESTAMP,
b8 TIMESTAMP,
b9 VARCHAR,
b10 VARCHAR,
b11 VARCHAR,
b12 VARCHAR,
b13 VARCHAR,
b14 VARCHAR,
);
statement ok
INSERT INTO b VALUES (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
statement ok
CREATE TABLE c(
c1 VARCHAR,
);
statement ok
CREATE TABLE d(
d1 VARCHAR,
d2 VARCHAR,
);
statement ok
SELECT *
FROM a
LEFT JOIN b ON b.b14 = a.a1
LEFT JOIN c ON b.b13 = c.c1
LEFT JOIN d ON b.b12 = d.d1
WHERE d.d2 IN ('');

View File

@@ -0,0 +1,9 @@
# name: test/sql/join/left_outer/non_foldable_left_join.test
# description: Left Outer join with non-foldable filter on RHS
# group: [left_outer]
statement ok
PRAGMA enable_verification
statement ok
select * from range(1) tbl(i) left join range(2) tbl2(j) on (i=j) where j+random()<0;

View File

@@ -0,0 +1,124 @@
# name: test/sql/join/left_outer/test_left_join_on_true.test
# description: Test ON TRUE join conditions
# group: [left_outer]
query II
WITH t AS (
SELECT 1 AS r, [{n:1}, {n:2}] AS s
UNION
SELECT 2 AS r, [{n:3}, {n:4}] AS s
)
SELECT r, s1.s.n FROM t
LEFT JOIN UNNEST(s) AS s1(s) ON TRUE
ORDER BY 1, 2
----
1 1
1 2
2 3
2 4
query II
WITH t AS (
SELECT 1 AS r, ARRAY[1, 2, 3] AS a
UNION SELECT 2 AS r, ARRAY[4] AS a
UNION SELECT 4 AS r, ARRAY[] AS a
)
SELECT r, a.value
FROM t
LEFT JOIN UNNEST(a) AS a(value) ON TRUE
ORDER BY 1, 2
----
1 1
1 2
1 3
2 4
4 NULL
# more than one condition
query II
WITH t AS (
SELECT 1 AS r, ARRAY[1, 2, 3] AS a
UNION SELECT 2 AS r, ARRAY[4] AS a
UNION SELECT 4 AS r, ARRAY[]::INTEGER[] AS a
)
SELECT r, a.value
FROM t
LEFT JOIN UNNEST(a) AS a(value) ON TRUE AND a.value IS NULL
ORDER BY 1, 2
----
1 NULL
2 NULL
4 NULL
query II
WITH t AS (
SELECT 1 AS r, ARRAY[1, 2, 3] AS a
UNION SELECT 2 AS r, ARRAY[4] AS a
UNION SELECT 4 AS r, ARRAY[] AS a
)
SELECT r, a.value
FROM t
LEFT JOIN UNNEST(a) AS a(value) ON (1 = 1) AND TRUE AND list_contains([2, 3], 2)
ORDER BY 1, 2
----
1 1
1 2
1 3
2 4
4 NULL
# non-true constant expressions cause a binder error
statement error
WITH t AS (
SELECT 1 AS r, [{n:1}, {n:2}] AS s
UNION
SELECT 2 AS r, [{n:3}, {n:4}] AS s
)
SELECT r, s1.s.n FROM t
LEFT JOIN UNNEST(s) AS s1(s) ON FALSE
----
Binder Error: Join condition for non-inner LATERAL JOIN must be a comparison between the left and right side
# test non-lateral left joins
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
INSERT INTO integers VALUES (1, 2), (2, 3), (3, 4)
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER)
statement ok
INSERT INTO integers2 VALUES (1, 10), (2, 20)
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON TRUE AND integers.i=integers2.k AND TRUE ORDER BY i
----
1 2 1 10
2 3 2 20
3 4 NULL NULL
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON TRUE AND integers.i=integers2.k AND FALSE ORDER BY i
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
# this is just a cross product
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON TRUE ORDER BY i
----
1 2 1 10
1 2 2 20
2 3 1 10
2 3 2 20
3 4 1 10
3 4 2 20

View File

@@ -0,0 +1,183 @@
# name: test/sql/join/left_outer/test_left_outer.test
# description: Test LEFT OUTER JOIN
# group: [left_outer]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
INSERT INTO integers VALUES (1, 2), (2, 3), (3, 4)
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER)
statement ok
INSERT INTO integers2 VALUES (1, 10), (2, 20)
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON integers.i=integers2.k ORDER BY i
----
1 2 1 10
2 3 2 20
3 4 NULL NULL
# RIGHT OUTER JOIN is just LEFT OUTER JOIN but with arguments reversed
# with one caveat: SELECT * will project the columns of the LHS first!
query IIII
SELECT * FROM integers2 RIGHT OUTER JOIN integers ON integers.i=integers2.k ORDER BY i
----
1 10 1 2
2 20 2 3
NULL NULL 3 4
# WHERE happens AFTER the join, thus [where k IS NOT NULL] filters out any tuples with generated NULL values from
# the LEFT OUTER JOIN. Because of this, this join is equivalent to an inner join.
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON integers.i=integers2.k WHERE k IS NOT NULL ORDER BY i
----
1 2 1 10
2 3 2 20
# however, any conditions in the ON clause happen BEFORE the join, thus the condition [integers2.k IS NOT NULL]
# happens BEFORE any NULL values are generated by the LEFT OUTER JOIN.
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON integers.i=integers2.k AND integers2.k IS NOT NULL ORDER BY i
----
1 2 1 10
2 3 2 20
3 4 NULL NULL
# filter on LHS
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON i=1 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 NULL NULL
3 4 NULL NULL
# left outer join on "true" is cross product
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON 1=1 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 1 10
2 3 2 20
3 4 1 10
3 4 2 20
# except if RHS is empty; then it is the LHS with NULl values appended
query IIII
SELECT * FROM integers LEFT OUTER JOIN (SELECT * FROM integers2 WHERE 1<>1) tbl2 ON 1=2 ORDER BY i;
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
# left outer join on "false" gives the LHS with the RHS filled as NULL
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON 1=2 ORDER BY i;
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
# left outer join on NULL constant gives the LHS with the RHS filled as null as well
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON NULL<>NULL ORDER BY i;
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
# left outer join on condition that only concerns the LHS
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON i=1 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 NULL NULL
3 4 NULL NULL
# left outer join on condition that only concerns the RHS
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON l=20 ORDER BY i, k;
----
1 2 2 20
2 3 2 20
3 4 2 20
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON l>0 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 1 10
2 3 2 20
3 4 1 10
3 4 2 20
# left outer join on condition that affects both, but is not a simple comparison
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON i=1 OR l=20 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 2 20
3 4 2 20
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON i=4 OR l=17 ORDER BY i;
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON i+l=21 ORDER BY i;
----
1 2 2 20
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON i+l>12 ORDER BY i, k;
----
1 2 2 20
2 3 2 20
3 4 1 10
3 4 2 20
# range join
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON integers.i<integers2.k WHERE integers.i <= 2 ORDER BY i
----
1 2 2 20
2 3 NULL NULL
# multiple conditions
query IIII
SELECT * FROM integers LEFT OUTER JOIN integers2 ON integers.i<integers2.k AND integers.i<integers2.l WHERE integers.i <= 2 ORDER BY i
----
1 2 2 20
2 3 NULL NULL
query IIII
SELECT * FROM integers LEFT OUTER JOIN (SELECT * FROM integers2 WHERE k=100) integers2 ON integers.i<integers2.k ORDER BY i
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
query II
select * from (values(1), (2)) t1(i) left join (values (2), (3)) t2(i) on t1.i=t2.i AND t1.i+t2.i=4 ORDER BY 1, 2;
----
1 NULL
2 2

View File

@@ -0,0 +1,56 @@
# name: test/sql/join/mark/large_mark_join.test_slow
# description: Test large mark join
# group: [mark]
statement ok
CREATE TABLE IF NOT EXISTS "names"(origin VARCHAR);
statement ok
INSERT INTO "names" VALUES('DFW'), ('ATL'), ('MSY'), ('ANC'), ('LAS'), ('SEA'), ('DTW'), ('LAX'), ('JFK'), ('FLL'), ('TPA'),
('SAN'), ('SLC'), ('MSP'), ('IAH'), ('SFO'), ('MCO'), ('DEN'), ('RDU'), ('BOS'), ('BHM'), ('LGA'), ('RSW'), ('BNA'), ('SNA'),
('DCA'), ('PHX'), ('MSN'), ('PHL'), ('MIA'), ('PBI'), ('BDL'), ('TLH'), ('SJU'), ('MCI'), ('TRI'), ('STT'), ('GRB'), ('PIT'),
('ORD'), ('SAV'), ('SDF'), ('BWI'), ('PDX'), ('SJC'), ('CHS'), ('JAC'), ('ORF'), ('CLE'), ('EWR'), ('OAK'), ('VPS'), ('CLT'),
('HSV'), ('GRR'), ('CAE'), ('MTJ'), ('GEG'), ('BIL'), ('SMF'), ('PHF'), ('JAN'), ('MDW'), ('MKE'), ('ATW'), ('MOB'), ('CMH'),
('CVG'), ('STL'), ('MLB'), ('SAT'), ('HNL'), ('ELP'), ('JAX'), ('SRQ'), ('OKC'), ('ROC'), ('LIT'), ('FNT'), ('IND'), ('MEM'),
('IAD'), ('OMA'), ('AUS'), ('GSP'), ('ONT'), ('BZN'), ('GSO'), ('SHV'), ('ILM'), ('PNS'), ('DAB'), ('CID'), ('EYW'), ('BUF'),
('DAY'), ('CAK'), ('ABQ'), ('RIC'), ('DAL'), ('MDT'), ('ECP'), ('TUS'), ('PWM'), ('GPT'), ('PVD'), ('KOA'), ('AGS'), ('TYS'),
('BOI'), ('FSD'), ('OGG'), ('TUL'), ('HDN'), ('HOU'), ('MYR'), ('DSM'), ('LFT'), ('CRW'), ('MHT'), ('PSP'), ('FAY'), ('ABE'),
('CHO'), ('SYR'), ('ALB'), ('RNO'), ('COS'), ('OAJ'), ('MSO'), ('ROA'), ('FAR'), ('LIH'), ('EGE'), ('ICT'), ('XNA'), ('BTR'),
('SGF'), ('AVL'), ('BIS'), ('STX'), ('LEX'), ('MFE'), ('LBB'), ('AMA'), ('FAT'), ('CRP'), ('GUC'), ('AEX'), ('ABI'), ('TYR'),
('LAW'), ('MLU'), ('LCH'), ('SAF'), ('GRK'), ('LRD'), ('GRI'), ('MAF'), ('MGM'), ('GCK'), ('SPS'), ('SPI'), ('FSM'), ('TXK'),
('CLL'), ('ACT'), ('ROW'), ('MEI'), ('PIB'), ('BTV'), ('CWA'), ('ERI'), ('EVV'), ('BRO'), ('HRL'), ('MLI'), ('LAN'), ('HOB'),
('SCE'), ('FWA'), ('AVP'), ('LNK'), ('AZO'), ('TVC'), ('PIA'), ('RST'), ('BMI'), ('DHN'), ('GNV'), ('ISP'), ('LGB'), ('BUR'),
('PSC'), ('SWF'), ('FCA'), ('GTF'), ('IDA'), ('ISN'), ('GFK'), ('MBS'), ('LSE'), ('ASE'), ('CMX'), ('EAU'), ('SBP'), ('SBA'),
('RKS'), ('GCC'), ('MKG'), ('MRY'), ('PAH'), ('DLH'), ('DVL'), ('JMS'), ('OTH'), ('LAR'), ('HYS'), ('SGU'), ('HLN'), ('MOT'),
('RDD'), ('GJT'), ('ACV'), ('MFR'), ('RDM'), ('MMH'), ('BFL'), ('SUN'), ('EUG'), ('RAP'), ('LWS'), ('COD'), ('TWF'), ('IMT'),
('APN'), ('ESC'), ('BJI'), ('CPR'), ('BTM'), ('ITH'), ('CIU'), ('EKO'), ('MQT'), ('INL'), ('BGM'), ('PIH'), ('ABR'), ('HIB'),
('CDC'), ('RHI'), ('BRD'), ('YUM'), ('FLG'), ('IFP'), ('STS'), ('BQN'), ('ORH'), ('ITO'), ('PPG'), ('ACY'), ('LBE'), ('IAG'),
('PBG'), ('CHA'), ('DRO'), ('HPN'), ('SBN'), ('PLN'), ('TOL'), ('COU'), ('MHK'), ('PSE'), ('CSG'), ('ELM'), ('BQK'), ('ABY'),
('VLD'), ('EWN'), ('TTN'), ('PGD'), ('WYS'), ('SIT'), ('KTN'), ('BGR'), ('FAI'), ('JNU'), ('ACK'), ('MVY'), ('ADQ'), ('BET'),
('SCC'), ('BRW'), ('CDV'), ('YAK'), ('PSG'), ('WRG'), ('OME'), ('OTZ'), ('ADK'), ('GUM'), ('ALO'), ('GTR'), ('BLI'), ('SJT'),
('BPT'), ('GGG'), ('JLN'), ('UST'), ('HYA'), ('SUX'), ('GST'), ('AKN'), ('DLG'), ('TKI');
statement ok
CREATE TABLE ontime AS
SELECT
n1.origin AS origin,
n2.origin as dest,
CASE WHEN i%97=0 THEN NULL ELSE (-235 + i % 3000) END AS depdelay
FROM range(427645) t(i)
JOIN names n1 ON (n1.rowid = i % 315)
JOIN names n2 ON (n2.rowid = (i + 97) % 315);
loop i 0 10
query III
SELECT *
FROM ontime AS ontime_outer
WHERE NOT(depdelay < ANY (
SELECT depdelay
FROM ontime
WHERE ontime.origin=ontime_outer.origin AND ontime.dest=ontime_outer.dest
));
----
endloop

View File

@@ -0,0 +1,118 @@
# name: test/sql/join/mark/test_mark_join_types.test_slow
# description: Test mark join with different types
# group: [mark]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
foreach type <numeric> decimal(4,1) decimal(8,1) decimal(12,1) decimal(18,1)
# numeric types
statement ok
begin transaction
statement ok
create table a as select i::${type} AS i from range(1, 101, 1) t1(i) order by random()
# range joins
query I
select count(*) from a WHERE i > ANY((SELECT 1::${type}))
----
99
query I
select count(*) from a WHERE i >= ANY((SELECT 1::${type}))
----
100
query I
select count(*) from a WHERE i < ANY((SELECT 100::${type}))
----
99
query I
select count(*) from a WHERE i <= ANY((SELECT 100::${type}))
----
100
query I
select count(*) from a WHERE i = ANY((SELECT 1::${type}))
----
1
query I
select count(*) from a WHERE i <> ANY((SELECT 1::${type}))
----
99
# now with a filter
query I
select count(*) from (select * from a where i % 2 = 0) a WHERE i > ANY((SELECT 2::${type}))
----
49
query I
select count(*) from (select * from a where i % 2 = 0) a WHERE i >= ANY((SELECT 2::${type}))
----
50
query I
select count(*) from (select * from a where i % 2 = 0) a WHERE i < ANY((SELECT 100::${type}))
----
49
query I
select count(*) from (select * from a where i % 2 = 0) a WHERE i <= ANY((SELECT 100::${type}))
----
50
query I
select * from (select * from a where i % 2 = 0) a WHERE i = ANY((SELECT 2::${type}))
----
2
query I
select count(*) from (select * from a where i % 2 = 0) a WHERE i <> ANY((SELECT 2::${type}))
----
49
# now select the actual values, instead of only the count
query I
select * from (select * from a where i % 2 = 0) a WHERE i <= ANY((SELECT 10::${type})) ORDER BY 1
----
2
4
6
8
10
query I
select * from (select * from a where i % 2 = 0) a WHERE i >= ANY((SELECT 90::${type})) ORDER BY 1
----
90
92
94
96
98
100
query I
select * from (select * from a where i > 90) a WHERE i <> ANY((SELECT 96::${type})) ORDER BY 1
----
91
92
93
94
95
97
98
99
100
statement ok
rollback
endloop

View File

@@ -0,0 +1,257 @@
# name: test/sql/join/natural/natural_join.test
# description: Test natural joins
# group: [natural]
# create tables
statement ok
CREATE TABLE t1 (a INTEGER, b INTEGER)
statement ok
INSERT INTO t1 VALUES (1, 2)
statement ok
CREATE TABLE t2 (a INTEGER, c INTEGER)
statement ok
INSERT INTO t2 VALUES (1, 3), (2, 4)
# NATURAL join with one column
query III
SELECT * FROM t1 NATURAL JOIN t2
----
1 2 3
query III
SELECT t1.a, t1.b, t2.c FROM t1 NATURAL JOIN t2
----
1 2 3
query III
SELECT t1.a, t1.b, t2.c FROM t1 NATURAL JOIN t2 ORDER BY t2.a
----
1 2 3
# natural join with multiple matching columns
statement ok
CREATE TABLE t3 (a INTEGER, b INTEGER, c INTEGER)
statement ok
INSERT INTO t3 VALUES (1, 2, 3)
query III
SELECT * FROM t1 NATURAL JOIN t3
----
1 2 3
query III
SELECT * FROM t3 NATURAL JOIN t2
----
1 2 3
# natural join chain
query III
SELECT * FROM t1 NATURAL JOIN t2 NATURAL JOIN t3
----
1 2 3
# no matching columns
statement error
select * from (values (1)) tbl(a) natural join (values (1), (2)) tbl2(b) order by 1, 2
----
<REGEX>:.*Binder Error.*No columns found to join.*
# long join chain
query I
select * from (values (1)) tbl(a) natural join (values (1)) tbl2(a) natural join (values (1)) tbl3(a)
natural join (values (1)) tbl4(a) natural join (values (1)) tbl5(a)
----
1
# natural join with subqueries
query I
select * from (select 42) tbl(a) natural join (select 42) tbl2(a)
----
42
# uncorrelated scalar subquery
query I
select (select * from (select 42) tbl(a) natural join (select 42) tbl2(a))
----
42
# Multiple 8-bit bitmasks
query IIIIIIIIIII
select *
from
(select 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52) tbl1(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
natural join
(select 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52) tbl2(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
----
42 43 44 45 46 47 48 49 50 51 52
# JoinHashTable::ScanFullOuter coverage
statement ok
CREATE TABLE sqlancer_t0(c0 DOUBLE, c1 DOUBLE);
statement ok
INSERT INTO sqlancer_t0 VALUES
(0.000000, -1570504255.000000),
(0.000000, -1570504255.000000),
(0.000000, -1570504255.000000),
(0.000000, -1570504255.000000),
(0.000000, 1.000000),
(0.000000, 0.543647),
(0.000000, NULL),
(0.000000, 1.000000),
(0.000000, 1.000000),
(0.000000, 0.000000),
(0.000000, 1617540830.000000),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, 0.497659),
(0.000000, -1367407567.000000),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, -547966124.000000),
(0.000000, NULL),
(0.000000, -1417028911.000000),
(0.000000, 277394703.000000),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, NULL),
(0.000000, NULL)
;
statement ok
CREATE VIEW sqlancer_v0(c0, c1) AS SELECT sqlancer_t0.c0, ((sqlancer_t0.rowid)//(-1694294358))
FROM sqlancer_t0
ORDER BY TIMESTAMP '1970-01-08 16:19:01' ASC;
query II
SELECT DISTINCT sqlancer_v0.c1, sqlancer_t0.rowid
FROM sqlancer_v0 NATURAL FULL JOIN sqlancer_t0
ORDER BY 2 ASC;
----
NULL 0
NULL 1
NULL 2
NULL 3
NULL 4
NULL 5
NULL 6
NULL 7
NULL 8
0 9
NULL 10
NULL 11
NULL 12
NULL 13
NULL 14
NULL 15
NULL 16
NULL 17
NULL 18
NULL 19
NULL 20
NULL 21
NULL 22
NULL 23
NULL 24
NULL 25
NULL 26
NULL 27
NULL 28
NULL 29
query II
SELECT DISTINCT sqlancer_v0.c1, sqlancer_t0.rowid
FROM sqlancer_v0 NATURAL FULL JOIN sqlancer_t0 WHERE sqlancer_t0.c0
UNION
SELECT DISTINCT sqlancer_v0.c1, sqlancer_t0.rowid
FROM sqlancer_v0 NATURAL FULL JOIN sqlancer_t0
WHERE (NOT sqlancer_t0.c0)
UNION
SELECT DISTINCT sqlancer_v0.c1, sqlancer_t0.rowid
FROM sqlancer_v0 NATURAL FULL JOIN sqlancer_t0
WHERE ((sqlancer_t0.c0) IS NULL)
ORDER BY 2 ASC;
----
NULL 0
NULL 1
NULL 2
NULL 3
NULL 4
NULL 5
NULL 6
NULL 7
NULL 8
0 9
NULL 10
NULL 11
NULL 12
NULL 13
NULL 14
NULL 15
NULL 16
NULL 17
NULL 18
NULL 19
NULL 20
NULL 21
NULL 22
NULL 23
NULL 24
NULL 25
NULL 26
NULL 27
NULL 28
NULL 29
# error: duplicate table alias on both sides
statement error
select (select * from (select 42) tbl(a) natural join (select 42) tbl(a))
----
<REGEX>:.*Binder Error.*Ambiguous reference to table.*
statement ok
DROP TABLE t1
statement ok
CREATE TABLE t0(c0 DATE, c1 DATE DEFAULT('0.5868720116119102'), c2 INT1, PRIMARY KEY(c1, c2, c0));
statement ok
CREATE TABLE t1(c0 DATETIME, c1 DATE DEFAULT(TIMESTAMP '1970-01-11 02:37:59'), PRIMARY KEY(c0));
statement ok
CREATE VIEW v0(c0) AS SELECT false FROM t1, t0 HAVING 1689380428;
statement ok
SELECT COUNT(t1.rowid) FROM t1, v0 NATURAL RIGHT JOIN t0;
statement ok
SELECT COUNT(t1.rowid) FROM t1, v0 RIGHT JOIN t0 ON v0.c0=t0.c0;
statement error
SELECT COUNT(t1.rowid) FROM t1, v0 RIGHT JOIN t0 ON t1.c1=t0.c1 AND v0.c0=t0.c0;
----
<REGEX>:.*Not implemented Error.*Non-inner join on correlated columns.*
# column name appears more than once on left side of the natural join
statement error
select * from (values (1)) t1(i) join (values (1)) t2(i) on (t1.i=t2.i) natural join (values (1)) t3(i);
----
<REGEX>:.*Binder Error.*Ambiguous reference to column name.*
statement ok
PRAGMA disable_verification
# column name appears more than once on right side of the natural join
statement error
select * from (values (1)) t1(i) natural join ((values (1)) t2(i) join (values (1)) t3(i) on (t2.i=t3.i))
----
<REGEX>:.*Binder Error.*exists more than once on right side of join.*

View File

@@ -0,0 +1,131 @@
# name: test/sql/join/positional/test_positional_join.test
# description: Test positional joins
# group: [positional]
statement ok
CREATE TABLE two (a INTEGER, b INTEGER);
statement ok
INSERT INTO two VALUES (11, 1), (12, 2);
statement ok
CREATE TABLE three AS
SELECT * FROM (VALUES
(11, 1),
(12, 2),
(13, 3)
) tbl(a, b);
statement ok
CREATE TABLE threek AS
SELECT * FROM generate_series(0, 3001) tbl(id);
#
# Positional Scan
#
# Basic test
query IIII
SELECT *
FROM two t1 POSITIONAL JOIN two t2
----
11 1 11 1
12 2 12 2
# Multiple blocks
query II
SELECT *
FROM threek t1 POSITIONAL JOIN threek t2
WHERE t1.id <> t2.id
----
# Outer semantics
query IIII
SELECT *
FROM two t1 POSITIONAL JOIN three t2
----
11 1 11 1
12 2 12 2
NULL NULL 13 3
query IIII
SELECT *
FROM three t1 POSITIONAL JOIN two t2
----
11 1 11 1
12 2 12 2
13 3 NULL NULL
query II
SELECT COUNT(a), COUNT(id)
FROM three POSITIONAL JOIN threek
----
3 3002
query II
SELECT COUNT(id), COUNT(a)
FROM threek POSITIONAL JOIN three
----
3002 3
#
# Positional Join
#
# Basic test
query IIII
SELECT *
FROM
(SELECT * FROM two WHERE a % 2 = 0) t1
POSITIONAL JOIN
(SELECT * FROM two WHERE a % 2 = 1) t2
----
12 2 11 1
# Multiple blocks
query II
SELECT *
FROM
(SELECT * FROM threek WHERE id % 2 = 0) t1
POSITIONAL JOIN
(SELECT * FROM threek WHERE id % 2 = 1) t2
WHERE t1.id + 1 <> t2.id
# Outer semantics
query IIII
SELECT *
FROM
(SELECT * FROM three WHERE a % 2 = 1) t1
POSITIONAL JOIN
(SELECT * FROM two WHERE a % 2 = 0) t2
----
11 1 12 2
13 3 NULL NULL
query IIII
SELECT *
FROM
(SELECT * FROM two WHERE a % 2 = 0) t1
POSITIONAL JOIN
(SELECT * FROM three WHERE a % 2 = 1) t2
----
12 2 11 1
NULL NULL 13 3
query II
SELECT COUNT(t1.id), COUNT(t2.id)
FROM
(SELECT * FROM threek WHERE id % 2 = 0) t1
POSITIONAL JOIN
(SELECT * FROM threek WHERE id % 3 = 0) t2
----
1501 1001
query II
SELECT COUNT(t1.id), COUNT(t2.id)
FROM
(SELECT * FROM threek WHERE id % 3 = 0) t2
POSITIONAL JOIN
(SELECT * FROM threek WHERE id % 2 = 0) t1
----
1501 1001

View File

@@ -0,0 +1,27 @@
# name: test/sql/join/pushdown/pushdown_generated_columns.test
# description: Join pushdown on generated columns
# group: [pushdown]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE unit2(
price INTEGER,
amount_sold INTEGER,
total_profit INTEGER GENERATED ALWAYS AS (price * amount_sold) VIRTUAL,
also_total_profit INTEGER GENERATED ALWAYS AS (total_profit) VIRTUAL
);
statement ok
INSERT INTO unit2 SELECT i, 20 FROM range(1000) t(i);
query IIII
SELECT * FROM unit2 JOIN (VALUES (2000)) t(total_profit) USING (total_profit);
----
100 20 2000 2000
query IIIII
SELECT * FROM unit2 JOIN (VALUES (2000)) t(total_profit) ON (t.total_profit = unit2.total_profit AND t.total_profit=unit2.also_total_profit);
----
100 20 2000 2000 2000

View File

@@ -0,0 +1,134 @@
# name: test/sql/join/pushdown/pushdown_join_subquery.test_slow
# description: Test join filter pushdown with subqueries
# group: [pushdown]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers AS SELECT CASE WHEN i%2=0 THEN NULL ELSE i END i FROM range(1000) t(i)
# expression on LHS
query II
SELECT * FROM integers JOIN (SELECT MAX(i) AS max_i FROM integers) ON i+2=max_i
----
997 999
# expression on RHS
query II
SELECT * FROM integers JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i-2
----
997 999
# filter
query II
SELECT * FROM (FROM integers WHERE i%2 = 1) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# filter that can be pushed down
query II
SELECT * FROM (FROM integers WHERE i>500) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# limit
query II
SELECT * FROM (FROM integers LIMIT 10000) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# order by
query II
SELECT * FROM (FROM integers ORDER BY i) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# top-n
query II
SELECT * FROM (FROM integers ORDER BY i DESC LIMIT 10) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# projection
query III
SELECT * FROM (SELECT i + 2 AS i, i AS k FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 997 999
# group by with join on grouping column
query II
SELECT * FROM (SELECT i FROM integers GROUP BY i) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# group by with join on aggregate
query III
SELECT * FROM (SELECT (1000 - i) AS grp, SUM(i) AS i FROM integers GROUP BY grp) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
1 999 999
# distinct
query II
SELECT * FROM (SELECT DISTINCT i FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# window
query IIII
SELECT * FROM (SELECT i + 2 AS i, i AS k, row_number() over () as rownum FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 997 998 999
statement ok
CREATE TABLE lists AS SELECT CASE WHEN i%2=0 THEN NULL ELSE i END AS i, [500 + i, 500 + i + 1, 500 + i + 2] l FROM range(1000) t(i)
# unnest where filter applies to non-unnest column
query III
SELECT * FROM (SELECT i, UNNEST(l) AS l FROM lists) JOIN (SELECT MAX(i) AS max_i FROM lists) ON i=max_i
----
999 1499 999
999 1500 999
999 1501 999
# unnest where filter applies to unnest column
query III
SELECT * FROM (SELECT i AS k, UNNEST(l) AS i FROM lists) JOIN (SELECT MAX(i) AS max_i FROM lists) ON i=max_i
----
497 999 999
NULL 999 999
499 999 999
# set operations
# union
query II
SELECT * FROM (FROM integers UNION ALL FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
999 999
query II
SELECT * FROM (FROM integers UNION FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# intersect
query II
SELECT * FROM (FROM integers INTERSECT FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
query II
SELECT * FROM (FROM integers INTERSECT ALL FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# except
query II
SELECT * FROM (FROM integers EXCEPT (SELECT 42)) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
query II
SELECT * FROM ((SELECT 999 i) EXCEPT FROM integers) JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----

View File

@@ -0,0 +1,44 @@
# name: test/sql/join/pushdown/pushdown_join_tpch.test_slow
# description: Test join filter pushdown on TPC-H
# group: [pushdown]
require tpch
statement ok
CALL dbgen(sf=1);
# single join
query II
SELECT l_orderkey, l_comment FROM lineitem WHERE l_orderkey=(SELECT MAX(l_orderkey) FROM lineitem) ORDER BY ALL
----
6000000 pecial excuses nag evenly f
6000000 riously pe
# multiple joins
query III
select l_orderkey, l_linenumber, l_comment
from lineitem
where l_linenumber=(select max(l_linenumber) from lineitem) AND
l_orderkey=(SELECT MAX(l_orderkey) FROM lineitem WHERE l_linenumber=7);
----
5999968 7 . express requests are
# involving separate tables
query I
select count(*) from lineitem where l_linenumber=(select max(l_linenumber) from lineitem) and l_suppkey=(select max(s_suppkey) from supplier);
----
16
# bunch of joins
query IIII
select l_orderkey, o_orderpriority, l_suppkey, l_linenumber
from lineitem join orders on (l_orderkey=o_orderkey)
where l_linenumber=(select max(l_linenumber) from lineitem) and
l_suppkey=(select max(s_suppkey) from supplier) and
o_orderpriority=(select max(o_orderpriority) from orders)
order by all
----
2076419 5-LOW 10000 7
2770594 5-LOW 10000 7
3196290 5-LOW 10000 7
3892931 5-LOW 10000 7

View File

@@ -0,0 +1,61 @@
# name: test/sql/join/pushdown/pushdown_join_types.test
# description: Test join filter pushdown with various join types
# group: [pushdown]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers AS SELECT CASE WHEN i%2=0 THEN NULL ELSE i END i FROM range(1000) t(i)
# inner join
query II
SELECT * FROM integers JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# right join
query II
SELECT * FROM integers RIGHT JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
----
999 999
# left join
query II
SELECT COUNT(*), COUNT(max_i) IS NOT NULL FROM (
SELECT * FROM integers LEFT JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
)
----
1000 1
query II
SELECT COUNT(*), COUNT(max_i) IS NOT NULL FROM (
SELECT * FROM integers FULL OUTER JOIN (SELECT MAX(i) AS max_i FROM integers) ON i=max_i
)
----
1000 1
# semi join
query I
SELECT * FROM integers WHERE i=(SELECT MAX(i) FROM integers)
----
999
query I
SELECT * FROM integers WHERE i IN (SELECT MAX(i) FROM integers)
----
999
# multiple values
query I
SELECT * FROM integers WHERE i IN (997, 999)
----
997
999
# mark join
query II
SELECT COUNT(*), SUM(CASE WHEN in_result THEN 1 ELSE 0 END) FROM
(SELECT i IN (SELECT MAX(i) FROM integers) AS in_result FROM integers)
----
1000 1

View File

@@ -0,0 +1,33 @@
# name: test/sql/join/pushdown/pushdown_many_columns.test_slow
# description: Test join filter pushdown on multiple columns
# group: [pushdown]
statement ok
PRAGMA enable_verification
# two columns of different types
statement ok
CREATE TABLE tbl AS SELECT CASE WHEN i%2=0 THEN NULL ELSE i END i, concat('thisisastring', i) s FROM range(1000) t(i)
query II
SELECT s, i FROM tbl WHERE i>10 AND s=(SELECT MAX(s) FROM tbl)
----
thisisastring999 999
query II
SELECT s, i FROM tbl JOIN (VALUES (999, 'thisisastring999')) t(i, s) USING (s, i)
----
thisisastring999 999
# all types
statement ok
CREATE TABLE all_types AS FROM test_all_types();
foreach col <all_types_columns>
query I
SELECT COUNT(*) FROM all_types WHERE "${col}"=(SELECT MIN("${col}") FROM all_types)
----
1
endloop

View File

@@ -0,0 +1,43 @@
# name: test/sql/join/pushdown/pushdown_many_joins.test
# description: Test join filter pushdown with many joins
# group: [pushdown]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE bigtbl AS SELECT i%2 AS small_key, i%10 AS medium_key, i AS val FROM range(10000) t(i) ORDER BY small_key, medium_key
statement ok
CREATE TABLE smalltbl AS SELECT i small_key FROM range(2) t(i)
statement ok
CREATE TABLE mediumtbl AS SELECT i medium_key FROM range(10) t(i)
query I
SELECT COUNT(*) FROM bigtbl JOIN smalltbl USING (small_key) JOIN mediumtbl USING (medium_key)
----
10000
# individual filters
query I
SELECT COUNT(*) FROM bigtbl JOIN (FROM smalltbl WHERE small_key=1) smalltbl USING (small_key) JOIN mediumtbl USING (medium_key)
----
5000
query I
SELECT COUNT(*) FROM bigtbl JOIN smalltbl USING (small_key) JOIN (FROM mediumtbl WHERE medium_key=1) mediumtbl USING (medium_key)
----
1000
# double filter
query I
SELECT COUNT(*) FROM bigtbl JOIN (FROM smalltbl WHERE small_key=1) smalltbl USING (small_key) JOIN (FROM mediumtbl WHERE medium_key=1) mediumtbl USING (medium_key)
----
1000
# double filter
query I
SELECT COUNT(*) FROM bigtbl JOIN (FROM smalltbl WHERE small_key=1) smalltbl USING (small_key) JOIN (FROM mediumtbl WHERE medium_key=1) mediumtbl ON (mediumtbl.medium_key=smalltbl.small_key)
----
5000

View File

@@ -0,0 +1,39 @@
# name: test/sql/join/right_outer/right_join_complex_null.test
# description: Test RIGHT OUTER JOIN on complex expression involving NULL
# group: [right_outer]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE t0(c0 DATE, PRIMARY KEY(c0));
statement ok
CREATE TABLE t1(c0 VARCHAR DEFAULT(DATE '1969-12-10'), c1 DOUBLE DEFAULT(0.16338108651823613));
statement ok
INSERT INTO t1(c1) VALUES (true);
statement ok
INSERT INTO t1(c0) VALUES (TIMESTAMP '1969-12-13 07:02:08');
statement ok
INSERT INTO t0(c0) VALUES (DATE '1970-01-01'), (TIMESTAMP '1969-12-13 17:49:43');
query I
SELECT MAX('a') FROM t0 JOIN t1 ON ((t0.c0)<=(((NULL)-(t1.rowid))::DATE));
----
NULL
query I
SELECT MAX('a') FROM t0 RIGHT JOIN t1 ON ((t0.c0)<=(((NULL)-(t1.rowid))::DATE));
----
a
statement error
SELECT MAX(agg0) FROM (SELECT MAX('a') AS agg0 FROM t0 RIGHT JOIN t1 ON ((t0.c0)<=(((NULL)-(t1.rowid)))) WHERE t1.c0 UNION ALL SELECT MAX('a') AS agg0 FROM t0 RIGHT JOIN t1 ON ((t0.c0)<=(((NULL)-(t1.rowid)))) WHERE (NOT t1.c0) UNION ALL SELECT MAX('a') AS agg0 FROM t0 RIGHT JOIN t1 ON ((t0.c0)<=(((NULL)-(t1.rowid)))) WHERE ((t1.c0) IS NULL)) as asdf;
----
<REGEX>:.*Binder Error.*Cannot compare values.*

View File

@@ -0,0 +1,156 @@
# name: test/sql/join/right_outer/test_right_outer.test
# description: Test RIGHT OUTER JOIN
# group: [right_outer]
statement ok
PRAGMA enable_verification
statement ok
pragma verify_external
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER)
statement ok
INSERT INTO integers VALUES (1, 2), (2, 3), (3, 4)
statement ok
CREATE TABLE integers2(k INTEGER, l INTEGER)
statement ok
INSERT INTO integers2 VALUES (1, 10), (2, 20)
# all these tests are equivalent to the tests in test_left_outer.test
# but with the tables reversed and using a right outer join instead
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON integers.i=integers2.k ORDER BY i
----
1 2 1 10
2 3 2 20
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON integers.i=integers2.k WHERE k IS NOT NULL ORDER BY i
----
1 2 1 10
2 3 2 20
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON integers.i=integers2.k AND integers2.k IS NOT NULL ORDER BY i
----
1 2 1 10
2 3 2 20
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON i=1 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON 1=1 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 1 10
2 3 2 20
3 4 1 10
3 4 2 20
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON 1=2 ORDER BY i;
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON NULL<>NULL ORDER BY i;
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON i=1 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON l=20 ORDER BY i, k;
----
1 2 2 20
2 3 2 20
3 4 2 20
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON l>0 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 1 10
2 3 2 20
3 4 1 10
3 4 2 20
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON i=1 OR l=20 ORDER BY i, k;
----
1 2 1 10
1 2 2 20
2 3 2 20
3 4 2 20
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON i=4 OR l=17 ORDER BY i;
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON i+l=21 ORDER BY i;
----
1 2 2 20
2 3 NULL NULL
3 4 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON i+l>12 ORDER BY i, k;
----
1 2 2 20
2 3 2 20
3 4 1 10
3 4 2 20
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON integers.i<integers2.k WHERE integers.i <= 2 ORDER BY i
----
1 2 2 20
2 3 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM integers2 RIGHT OUTER JOIN integers ON integers.i<integers2.k AND integers.i<integers2.l WHERE integers.i <= 2 ORDER BY i
----
1 2 2 20
2 3 NULL NULL
query IIII
SELECT integers.*, integers2.* FROM (SELECT * FROM integers2 WHERE k=100) integers2 RIGHT OUTER JOIN integers ON integers.i<integers2.k ORDER BY i
----
1 2 NULL NULL
2 3 NULL NULL
3 4 NULL NULL
query II
select t1.*, t2.* from (values (2), (3)) t2(i) right join (values(1), (2)) t1(i) on t1.i=t2.i AND t1.i+t2.i=4 ORDER BY 1, 2;
----
1 NULL
2 2

View File

@@ -0,0 +1,53 @@
# name: test/sql/join/semianti/10406-anti-on-ints-strings.test
# description: github reported bug
# group: [semianti]
statement ok
create table test_str(k varchar);
statement ok
create table test_str_del(pk varchar);
statement ok
create table test_int(k bigint);
statement ok
create table test_int_del(pk bigint);
statement ok
insert into test_str values('abc'), ('def');
statement ok
insert into test_int values(1), (2);
query I rowsort
select l.* from test_str l anti join test_str_del r on l.k = r.pk;
----
abc
def
query I rowsort
select l.* from test_int l anti join test_int_del r on l.k = r.pk;
----
1
2
statement ok
insert into test_int VALUES (NULL);
query I rowsort
select l.* from test_int l anti join test_int_del r on l.k is not distinct from r.pk;
----
1
2
NULL
statement ok
insert into test_int_del VALUES (NULL);
# NULL is now not distinct from null
query I rowsort
select l.* from test_int l anti join test_int_del r on l.k is not distinct from r.pk;
----
1
2

View File

@@ -0,0 +1,166 @@
# name: test/sql/join/semianti/antijoin.test
# description: Test positional joins
# group: [semianti]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE left_table (a INTEGER, b INTEGER, c INTEGER);
statement ok
INSERT INTO left_table VALUES(42, 1, 1), (43, 1, 1);
statement ok
CREATE TABLE right_table (a INTEGER, b INTEGER);
statement ok
INSERT INTO right_table VALUES(42, 1);
# STAR expression expands only the left table
query III
SELECT * FROM left_table ANTI JOIN right_table ON left_table.a = right_table.a;
----
43 1 1
# can filter on columns in left table
query III
SELECT * FROM left_table ANTI JOIN right_table ON left_table.a = right_table.a WHERE a > 5;
----
43 1 1
# can have list type expressions in the condition
query III
SELECT * FROM left_table ANTI JOIN right_table ON ([left_table.a, left_table.b] = [right_table.a, right_table.b]);
----
43 1 1
# right table can be a subquery
query III
SELECT * FROM left_table ANTI JOIN (SELECT a as foo from right_table where b = 1) buzz ON left_table.a = buzz.foo
----
43 1 1
# Should throw error when filtering on column in right table
statement error
SELECT * FROM left_table ANTI JOIN right_table ON left_table.a = right_table.a WHERE right_table.a < 43;
----
Binder Error
statement ok
INSERT INTO left_table VALUES (43, 1, 5), (43, 1, 5), (43, 1, 5), (43, 1, 5);
# left results are not deduplicated
query III
SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a);
----
43 1 1
43 1 5
43 1 5
43 1 5
43 1 5
query I
CREATE TABLE other (a INTEGER, b INTEGER);
statement ok
INSERT INTO other VALUES (42, 1), (43, 1);
# a table that is the result of a join can also be anti joined on
query III
SELECT * FROM left_table
ANTI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table
ON left_table.a = joined_right_table.a;
----
43 1 1
43 1 5
43 1 5
43 1 5
43 1 5
statement ok
DELETE FROM left_table where c=5;
# USING COLUMNS also works
query III
SELECT * FROM left_table ANTI JOIN right_table USING (a);
----
43 1 1
# natural anti join works
query III
SELECT * FROM left_table NATURAL ANTI JOIN right_table;
----
43 1 1
query III
SELECT * FROM left_table
NATURAL ANTI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table;
----
43 1 1
# right_table.a and left_table.a have the value 42
# only left_table.a has the value 43
# test inequality joins
query III
SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a <> right_table.a) ORDER BY a, c;
----
42 1 1
# range joins
query III
SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a > right_table.a);
----
42 1 1
statement ok
SELECT * from left_table, right_table;
# complex condition resulting in an any join
query III
SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
42 1 1
statement ok
INSERT INTO right_table VALUES (1, 42), (1, 42);
# Insert more values so that the scan side in the cross product is the right hand side
statement ok
INSERT INTO left_table VALUES (42, 1, 5), (42, 1, 5), (42, 1, 5), (2000, 20000, 200000);
# complex condition resulting in an any join
query III
SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
2000 20000 200000
# correlated subqueries
query II
SELECT a as outer_a, (SELECT MAX(right_table.b) FROM right_table where right_table.a != outer_a) right_table_b FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
43 42
2000 42
statement ok
INSERT INTO right_table VALUES (1, 20);
# correlated subqueries
query II
SELECT a as outer_a, (SELECT MAX(b) FROM right_table where right_table.a != outer_a) right_table_b FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
43 42
2000 42
statement ok
SET scalar_subquery_error_on_multiple_rows=false
# this is probably not deterministic
query II
SELECT a as outer_a, (SELECT b FROM right_table where right_table.a != outer_a) right_table_b FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
43 20
2000 20

View File

@@ -0,0 +1,87 @@
# name: test/sql/join/semianti/plan_blockwise_NL_join_with_mutliple_conditions.test
# description: Test anti ijoin results
# group: [semianti]
statement ok
PRAGMA enable_verification
statement ok
create table t1 as select * from values (1, 2), (2, 4), (3, 8), (6, 25), (1, 25) t(a, b);
statement ok
create table t2 as select * from values (4), (5) t(b);
query II
select * from t1 semi join t2 on t1.a < t2.b and t1.b > t2.b order by all;
----
1 25
3 8
query II
select * from t1 anti join t2 on t1.a < t2.b and t1.b < t2.b order by all;
----
1 25
3 8
6 25
query II
Explain select * from t1 anti join t2 on t1.a < t2.b and t1.b < t2.b order by all;
----
physical_plan <REGEX>:.*BLOCKWISE_NL_JOIN.*
query II
select * from t1 anti join t2 on t1.a < t2.b and t1.b < t2.b order by all;
----
1 25
3 8
6 25
query II
select * from t1 semi join t2 on t1.a < t2.b or t1.b < t2.b order by all;
----
1 2
1 25
2 4
3 8
query II
select * from t1 semi join t2 on (t1.a < t2.b and t1.b < t2.b) or (t1.a < t2.b and t1.b = 4) order by all;
----
1 2
2 4
query II
select * from t1 semi join t2 on (t1.a < t2.b or t1.b < t2.b) and (t1.a = 1 or t1.b = 4) order by all;
----
1 2
1 25
2 4
statement ok
CREATE TABLE flattened ("start" varchar, "end" varchar);
statement ok
insert into flattened values ('2023-03-15T00:00:00Z', '2023-03-20T00:00:00Z');
statement ok
create table input_table as select * from VALUES
('1', '2023-03-14T00:00:00Z', 2),
('2', '2023-03-15T00:00:00Z', 4),
('3', '2023-03-16T00:00:00Z', 7),
('4', '2023-03-17T00:00:00Z', 3),
('5', '2023-03-18T00:00:00Z', 2),
('6', '2023-03-19T23:59:59Z', 4),
('7', '2023-03-20T00:00:00Z', 7),
('8', '2023-03-21T00:00:00Z', 3) t(user_id, timestamp, value);
query III
SELECT * FROM input_table
ANTI JOIN flattened
ON input_table."timestamp" >= flattened.start AND input_table."timestamp" < flattened.end;
----
1 2023-03-14T00:00:00Z 2
7 2023-03-20T00:00:00Z 7
8 2023-03-21T00:00:00Z 3

View File

@@ -0,0 +1,149 @@
# name: test/sql/join/semianti/right_anti.test
# description: Test positional joins
# group: [semianti]
statement ok
CREATE TABLE left_table (a INTEGER, b INTEGER, c INTEGER);
statement ok
INSERT INTO left_table VALUES (42, 1, 1), (43, 1, 1), (42, 1, 1), (41, 1, 1), (41, 2, 2), (41, 7, 7);
statement ok
CREATE TABLE right_table (a INTEGER, b INTEGER);
# insert 2x values into right table. This means it will be forced to be the probe side
statement ok
INSERT INTO right_table select 41, range as b from range(375);
query II
EXPLAIN ANALYZE SELECT * FROM left_table ANTI JOIN right_table ON left_table.a = right_table.a;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
# still flips with filter
query II
explain analyze SELECT * FROM left_table ANTI JOIN right_table ON left_table.a = right_table.a WHERE a > 5;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
# still flips with equality condition on tuples
query II
explain analyze SELECT * FROM left_table ANTI JOIN right_table ON ([left_table.a, left_table.b] = [right_table.a, right_table.b]);
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
# right table can be a subquery, but using equality we still flip
query II
explain analyze SELECT * FROM left_table ANTI JOIN (SELECT a as foo from right_table where b > 5) buzz ON left_table.a = buzz.foo
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
statement ok
INSERT INTO left_table VALUES (43, 1, 5), (43, 1, 5), (43, 1, 5), (43, 1, 5);
query I
CREATE TABLE other (a INTEGER, b INTEGER);
statement ok
INSERT INTO other VALUES (42, 1), (43, 1);
# Still flip on intermediate table that is joined
query II
EXPLAIN ANALYZE SELECT * FROM left_table
ANTI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table
ON left_table.a = joined_right_table.a;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
statement ok
DELETE FROM left_table where c=5;
# USING COLUMNS also works,
query II
EXPLAIN ANALYZE SELECT * FROM left_table ANTI JOIN right_table USING (a);
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
# natural anti join works
query II
explain analyze SELECT * FROM left_table NATURAL ANTI JOIN right_table;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
query II
EXPLAIN ANALYZE SELECT * FROM left_table
NATURAL ANTI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
# right_table.a and left_table.a have the value 42
# only left_table.a has the value 43
# test flip on inequalities as well
query II
EXPLAIN ANALYZE SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a <> right_table.a) ORDER BY a, c;
----
analyzed_plan <!REGEX>:.*RIGHT_ANTI.*
# range joins do *not* flip
query II
EXPLAIN ANALYZE SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a > right_table.a);
----
analyzed_plan <!REGEX>:.*RIGHT_ANTI.*
# complex condition resulting in an any join DOES *NOT* flip
query II
explain analyze SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
analyzed_plan <!REGEX>:.*RIGHT_ANTI.*
statement ok
INSERT INTO right_table VALUES (1, 42), (1, 42);
# Insert more values so that the scan side in the cross product is the right hand side
statement ok
INSERT INTO left_table VALUES (42, 1, 5), (42, 1, 5), (42, 1, 5), (2000, 20000, 200000);
# complex condition resulting in an any join does *NOT* flip
query II
explain analyze SELECT * FROM left_table ANTI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
analyzed_plan <!REGEX>:.*RIGHT_ANTI.*
# correlated subqueries can flip
query II
explain analyze SELECT a as outer_a, (SELECT MAX(right_table.b) FROM right_table where right_table.a != outer_a) right_table_b FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
statement ok
INSERT INTO right_table VALUES (1, 20);
# correlated subqueries
query II
explain analyze SELECT a as outer_a, (SELECT MAX(b) FROM right_table where right_table.a != outer_a) right_table_b FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
statement ok
SET scalar_subquery_error_on_multiple_rows=false
query II
explain analyze SELECT a as outer_a, (SELECT right_table.b FROM right_table where right_table.a != outer_a) right_table_b FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*
statement ok
INSERT INTO right_table VALUES (1, 20);
# correlated subqueries
query II
explain analyze SELECT a as outer_a, (SELECT b FROM right_table where right_table.a != outer_a) right_table_b FROM left_table ANTI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_ANTI.*

View File

@@ -0,0 +1,148 @@
# name: test/sql/join/semianti/right_semi.test
# description: Test positional joins
# group: [semianti]
statement ok
CREATE TABLE left_table (a INTEGER, b INTEGER, c INTEGER);
statement ok
INSERT INTO left_table VALUES (41, 1, 1), (42, 1, 1), (42, 1, 1), (43, 1, 1), (45, 2, 2), (46, 7, 7);
statement ok
CREATE TABLE right_table (a INTEGER, b INTEGER);
# insert 2x values into right table. This means it will be forced to be the probe side
statement ok
INSERT INTO right_table select 41, range as b from range(375);
query II
EXPLAIN ANALYZE SELECT * FROM left_table SEMI JOIN right_table ON left_table.a = right_table.a;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
# still flips with filter
query II
explain analyze SELECT * FROM left_table SEMI JOIN right_table ON left_table.a = right_table.a WHERE a > 5;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
# still flips with equality condition on tuples
query II
explain analyze SELECT * FROM left_table SEMI JOIN right_table ON ([left_table.a, left_table.b] = [right_table.a, right_table.b]);
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
# right table can be a subquery, but using equality we still flip
query II
explain analyze SELECT * FROM left_table SEMI JOIN (SELECT a as foo from right_table where b > 1) buzz ON left_table.a = buzz.foo
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
statement ok
INSERT INTO left_table VALUES (43, 1, 5), (43, 1, 5), (43, 1, 5), (43, 1, 5);
query I
CREATE TABLE other (a INTEGER, b INTEGER);
statement ok
INSERT INTO other VALUES (42, 1), (43, 1);
# Still flip on intermediate table that is joined
query II
EXPLAIN ANALYZE SELECT * FROM left_table
SEMI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table
ON left_table.a = joined_right_table.a;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
statement ok
DELETE FROM left_table where c=5;
# USING COLUMNS also works,
query II
EXPLAIN ANALYZE SELECT * FROM left_table SEMI JOIN right_table USING (a);
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
# natural anti join works
query II
explain analyze SELECT * FROM left_table NATURAL SEMI JOIN right_table;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
query II
EXPLAIN ANALYZE SELECT * FROM left_table
NATURAL SEMI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
# right_table.a and left_table.a have the value 42
# only left_table.a has the value 43
# test flip on inequalities as well
query II
EXPLAIN ANALYZE SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a <> right_table.a) ORDER BY a, c;
----
analyzed_plan <!REGEX>:.*RIGHT_SEMI.*
# range joins do *not* flip
query II
EXPLAIN ANALYZE SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a > right_table.a);
----
analyzed_plan <!REGEX>:.*RIGHT_SEMI.*
# complex condition resulting in an any join DOES *NOT* flip
query II
explain analyze SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
analyzed_plan <!REGEX>:.*RIGHT_SEMI.*
statement ok
INSERT INTO right_table VALUES (1, 42), (1, 42);
# Insert more values so that the scan side in the cross product is the right hand side
statement ok
INSERT INTO left_table VALUES (42, 1, 5), (42, 1, 5), (42, 1, 5), (2000, 20000, 200000);
# complex condition resulting in an any join does *NOT* flip
query II
explain analyze SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
analyzed_plan <!REGEX>:.*RIGHT_SEMI.*
# correlated subqueries can flip
query II
explain analyze SELECT a as outer_a, (SELECT MAX(right_table.b) FROM right_table where right_table.a != outer_a) right_table_b FROM left_table SEMI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
statement ok
INSERT INTO right_table VALUES (1, 20);
# correlated subqueries
query II
explain analyze SELECT a as outer_a, (SELECT MAX(b) FROM right_table where right_table.a != outer_a) right_table_b FROM left_table SEMI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
statement ok
SET scalar_subquery_error_on_multiple_rows=false
query II
explain analyze SELECT a as outer_a, (SELECT right_table.b FROM right_table where right_table.a != outer_a) right_table_b FROM left_table SEMI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*
statement ok
INSERT INTO right_table VALUES (1, 20);
# correlated subqueries
query II
explain analyze SELECT a as outer_a, (SELECT b FROM right_table where right_table.a != outer_a) right_table_b FROM left_table SEMI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
analyzed_plan <REGEX>:.*RIGHT_SEMI.*

View File

@@ -0,0 +1,169 @@
# name: test/sql/join/semianti/semijoin.test
# description: Test semi joins
# group: [semianti]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE left_table (a INTEGER, b INTEGER, c INTEGER);
statement ok
INSERT INTO left_table VALUES(42, 1, 1), (43, 1, 1);
statement ok
CREATE TABLE right_table (a INTEGER, b INTEGER);
statement ok
INSERT INTO right_table VALUES(42, 1);
# * expression expands all of the left table
query III
SELECT * FROM left_table SEMI JOIN right_table ON left_table.a = right_table.a;
----
42 1 1
# can filter on columns in left table
query III
SELECT * FROM left_table SEMI JOIN right_table ON left_table.a = right_table.a WHERE a > 5;
----
42 1 1
# can have list type expressions in the condition
query III
SELECT * FROM left_table SEMI JOIN right_table ON ([left_table.a, left_table.b] = [right_table.a, right_table.b]);
----
42 1 1
# right table can be a subquery
query III
SELECT * FROM left_table SEMI JOIN (SELECT a as foo from right_table where b = 1) buzz ON left_table.a = buzz.foo
----
42 1 1
# Should throw error when filtering on column in right table
statement error
SELECT * FROM left_table SEMI JOIN right_table ON left_table.a = right_table.a WHERE right_table.a < 43;
----
Binder Error
# left results are not deduplicated
statement ok
INSERT INTO left_table VALUES (42, 1, 5), (42, 1, 5), (42, 1, 5), (42, 1, 5);
query III
SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a = right_table.a);
----
42 1 1
42 1 5
42 1 5
42 1 5
42 1 5
query I
CREATE TABLE other (a INTEGER, b INTEGER);
statement ok
INSERT INTO other VALUES (42, 1), (43, 1);
# a table that is the result of a join can also be semi joined on
query III
SELECT * FROM left_table
SEMI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table
ON left_table.a = joined_right_table.a;
----
42 1 1
42 1 5
42 1 5
42 1 5
42 1 5
statement ok
DELETE FROM left_table where c=5;
# USING COLUMNS also works
query III
SELECT * FROM left_table SEMI JOIN right_table USING (a);
----
42 1 1
# natural semi join also works
query III
SELECT * FROM left_table NATURAL SEMI JOIN right_table;
----
42 1 1
# also with subqueries
query III
SELECT * FROM left_table
NATURAL SEMI JOIN (select right_table.a FROM right_table JOIN other ON (other.a = right_table.a)) joined_right_table;
----
42 1 1
# test correlated queries
# right_table.a and left_table.a have the value 42
# only left_table.a has the value 43
# test inequality joins
query III
SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a <> right_table.a) ORDER BY a, c;
----
43 1 1
# range joins
query III
SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a > right_table.a);
----
43 1 1
# complex condition resulting in an any join
query III
SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
43 1 1
statement ok
INSERT INTO right_table VALUES (1, 42), (1, 42);
# Insert more values so that the scan side in the cross product is the right hand side
statement ok
INSERT INTO left_table VALUES (42, 1, 5), (42, 1, 5), (42, 1, 5), (2000, 20000, 200000);
# complex condition resulting in an any join
query III
SELECT * FROM left_table SEMI JOIN right_table ON (left_table.a + right_table.a = 85 OR left_table.a + right_table.b = 84) order by left_table.a, left_table.c;
----
42 1 1
42 1 5
42 1 5
42 1 5
43 1 1
# complex condition resulting in an any join
query III
SELECT * FROM left_table SEMI JOIN right_table ON ((left_table.a = NULL AND right_table.a = NULL) OR left_table.a = right_table.a) order by left_table.a, left_table.c;
----
42 1 1
42 1 5
42 1 5
42 1 5
# correlated subqueries
query II
SELECT a as outer_a, (SELECT ANY_VALUE(b) FROM right_table where right_table.a != outer_a) right_table_b FROM left_table SEMI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
42 42
42 42
42 42
42 42
statement ok
SET scalar_subquery_error_on_multiple_rows=false
query II
SELECT a as outer_a, (SELECT b FROM right_table where right_table.a != outer_a) right_table_b FROM left_table SEMI JOIN right_table ON (left_table.a = right_table.a) Order by outer_a, right_table_b;
----
42 42
42 42
42 42
42 42

View File

@@ -0,0 +1,55 @@
# name: test/sql/join/semianti/test_simple_anti_join.test
# description: Test semi joins
# group: [semianti]
statement ok
pragma enable_verification;
statement ok
CREATE TABLE t0(c0 VARCHAR);
statement ok
CREATE TABLE t1(c1 VARCHAR);
statement ok
INSERT INTO t1(c1) VALUES (NULL);
statement ok
INSERT INTO t0(c0) VALUES (1);
query I
select * FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t0 WHERE null);
----
NULL
query I
select * FROM t1 WHERE EXISTS (SELECT 1 FROM t0 WHERE ((t0.c0) != (t1.c1)));
----
query I
select * FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t0 WHERE ((t0.c0)!=(t1.c1))); -- wrong, no row
----
NULL
statement ok
create table lineitem (l_orderkey int, l_suppkey int, l_partkey int);
statement ok
insert into lineitem values (1,1,42),(1,2,43),(3,3,44),(4,5,45),(5,5,46),(6,5,47);
query III rowsort
select * from lineitem l1 where exists (
select * from lineitem l2
where
l2.l_orderkey = l1.l_orderkey
and l2.l_suppkey <> l1.l_suppkey
);
----
1 1 42
1 2 43
query II
select c0, EXISTS (select * from t1 where c1 != c0) from t0;
----
1 false

View File

@@ -0,0 +1,20 @@
# name: test/sql/join/set_operators/test_set_operator_reordering_with_delim_joins.test
# description: Test reodering set operators
# group: [set_operators]
statement ok
create or replace table xx as select w from (values ('a'),('b'),('c'),('d'),('e')) t(w);
statement ok
select w from (from xx limit 4)
CROSS JOIN (select 1 as f1) p
WHERE
w IN (
SELECT 'a'
UNION -- with 'UNION ALL' it works also using 'limit 4'
SELECT 'b'
UNION
SELECT 'c' WHERE p.f1 = 1
UNION
SELECT 'd' WHERE p.f1 = 1
);

View File

@@ -0,0 +1,43 @@
# name: test/sql/join/test_complex_join_expr.test
# description: Test joins with comparisons involving both sides of the join
# group: [join]
statement ok
SET default_null_order='nulls_first';
# create tables
statement ok
CREATE TABLE test (a INTEGER, b INTEGER);
statement ok
INSERT INTO test VALUES (4, 1), (2, 2)
statement ok
CREATE TABLE test2 (b INTEGER, c INTEGER);
statement ok
INSERT INTO test2 VALUES (1, 2), (3, 0)
query IIII
SELECT * FROM test JOIN test2 ON test.a+test2.c=test.b+test2.b
----
4 1 3 0
query IIII
SELECT * FROM test LEFT JOIN test2 ON test.a+test2.c=test.b+test2.b ORDER BY 1
----
2 2 NULL NULL
4 1 3 0
query IIII
SELECT * FROM test RIGHT JOIN test2 ON test.a+test2.c=test.b+test2.b ORDER BY 1
----
NULL NULL 1 2
4 1 3 0
query IIII
SELECT * FROM test FULL OUTER JOIN test2 ON test.a+test2.c=test.b+test2.b ORDER BY 1
----
NULL NULL 1 2
2 2 NULL NULL
4 1 3 0

View File

@@ -0,0 +1,149 @@
# name: test/sql/join/test_complex_join_structs.test_slow
# description: Test complex joins and count distincts with structs
# group: [join]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE structs AS SELECT i id, {'i': i} s, i%3 j FROM generate_series(0,99,1) tbl(i), generate_series(0,1,1);
statement ok
CREATE TABLE other_table AS SELECT i id, i%3 j FROM generate_series(0,99,1) tbl(i) WHERE i%2=0;
# count distinct
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs;
----
200 200 100 100
#count distinct with a filter
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs WHERE id%2<>0;
----
100 100 50 50
# count distinct with a join
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs JOIN other_table USING (id);
----
100 100 50 50
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs LEFT JOIN other_table USING (id);
----
200 200 100 100
# count distinct with a complex join condition
query IIIII
SELECT structs.j, COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id)
FROM structs
LEFT JOIN other_table o1 USING (id)
CROSS JOIN other_table
WHERE ((structs.j IN (0, 1) AND (structs.id=other_table.id)) OR (structs.j=2 AND structs.id+1=other_table.id))
GROUP BY ALL
ORDER BY ALL
----
0 34 34 17 17
1 32 32 16 16
2 32 32 16 16
# now with lists
statement ok
DROP TABLE structs;
statement ok
DROP TABLE other_table
statement ok
CREATE TABLE structs AS SELECT i id, {'i': [i, i + 1, i + 2], 'j': CASE WHEN i%4=1 THEN NULL ELSE [i, i] END} s, i%3 j FROM generate_series(0,99,1) tbl(i), generate_series(0,1,1);
statement ok
CREATE TABLE other_table AS SELECT i id, i%3 j FROM generate_series(0,99,1) tbl(i) WHERE i%2=0;
# count distinct
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs;
----
200 200 100 100
#count distinct with a filter
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs WHERE id%2<>0;
----
100 100 50 50
# count distinct with a join
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs JOIN other_table USING (id);
----
100 100 50 50
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs LEFT JOIN other_table USING (id);
----
200 200 100 100
# count distinct with a complex join condition
query IIIII
SELECT structs.j, COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id)
FROM structs
LEFT JOIN other_table o1 USING (id)
CROSS JOIN other_table
WHERE ((structs.j IN (0, 1) AND (structs.id=other_table.id)) OR (structs.j=2 AND structs.id+1=other_table.id))
GROUP BY ALL
ORDER BY ALL
----
0 34 34 17 17
1 32 32 16 16
2 32 32 16 16
# more complex nested structs
statement ok
DROP TABLE structs;
statement ok
DROP TABLE other_table
statement ok
CREATE TABLE structs AS SELECT i id, {'i': {'j': [i + 1, i + 2, i + 3], 'k': i}, 'l': NULL} s, i%3 j FROM generate_series(0,99,1) tbl(i), generate_series(0,1,1);
statement ok
CREATE TABLE other_table AS SELECT i id, i%3 j FROM generate_series(0,99,1) tbl(i) WHERE i%2=0;
# count distinct
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs;
----
200 200 100 100
#count distinct with a filter
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs WHERE id%2<>0;
----
100 100 50 50
# count distinct with a join
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs JOIN other_table USING (id);
----
100 100 50 50
query IIII
SELECT COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id) FROM structs LEFT JOIN other_table USING (id);
----
200 200 100 100
# count distinct with a complex join condition
query IIIII
SELECT structs.j, COUNT(*), COUNT(s), COUNT(DISTINCT s), COUNT(DISTINCT structs.id)
FROM structs
LEFT JOIN other_table o1 USING (id)
CROSS JOIN other_table
WHERE ((structs.j IN (0, 1) AND (structs.id=other_table.id)) OR (structs.j=2 AND structs.id+1=other_table.id))
GROUP BY ALL
ORDER BY ALL
----
0 34 34 17 17
1 32 32 16 16
2 32 32 16 16

View File

@@ -0,0 +1,456 @@
# name: test/sql/join/test_complex_range_join.test
# description: Test inequality join
# group: [join]
# Coverage for multiple slicing predicates
query IIIIII
WITH lhs(i, j, k) AS (VALUES
(100, 10, 1),
(200, 20, 2)
),
rhs(p, q, r) AS (VALUES
(100, 10, 1),
(200, 20, 2)
)
SELECT lhs.*, rhs.*
FROM lhs, rhs
WHERE i <= p AND j <> q AND k IS DISTINCT FROM r
----
100 10 1 200 20 2
# Coverage for multiple range predicates
query IIIIII
WITH lhs(i, j, k) AS (VALUES
(100, 10, 1),
(200, 20, 2)
),
rhs(p, q, r) AS (VALUES
(100, 10, 1),
(200, 20, 2)
)
SELECT lhs.*, rhs.*
FROM lhs, rhs
WHERE i <= p AND k >= r AND j <= q
ORDER BY i
----
100 10 1 100 10 1
200 20 2 200 20 2
# A test involving many (~10) predicates, each filtering out a certain subset of the rows
# (e.g. a<z and b<z and c<z and d<z and e<z and ... where z=1..100 in random order
# and a=10, b=20, c=30, etc)
statement ok
CREATE TABLE wide AS (
SELECT
i,
10 * (i + 0) AS c0,
10 * (i + 1) AS c1,
10 * (i + 2) AS c2,
10 * (i + 3) AS c3,
10 * (i + 4) AS c4,
10 * (i + 5) AS c5,
10 * (i + 6) AS c6,
10 * (i + 7) AS c7,
10 * (i + 8) AS c8,
10 * (i + 9) AS c9
FROM range(1, 10) tbl(i)
);
query IIIIIIIIIII
SELECT * FROM wide;
----
1 10 20 30 40 50 60 70 80 90 100
2 20 30 40 50 60 70 80 90 100 110
3 30 40 50 60 70 80 90 100 110 120
4 40 50 60 70 80 90 100 110 120 130
5 50 60 70 80 90 100 110 120 130 140
6 60 70 80 90 100 110 120 130 140 150
7 70 80 90 100 110 120 130 140 150 160
8 80 90 100 110 120 130 140 150 160 170
9 90 100 110 120 130 140 150 160 170 180
statement ok
CREATE TABLE limits AS (
SELECT 100 + (i * 17 % 100) AS z
FROM range(1, 10) tbl(i)
);
query I
SELECT z FROM limits;
----
117
134
151
168
185
102
119
136
153
query II
SELECT i, z
FROM wide, limits
WHERE c0 < z
AND c1 < z
AND c2 < z
AND c3 < z
AND c4 < z
AND c5 < z
AND c6 < z
AND c7 < z
AND c8 < z
AND c9 < z
ORDER BY 1, 2
----
1 102
1 117
1 119
1 134
1 136
1 151
1 153
1 168
1 185
2 117
2 119
2 134
2 136
2 151
2 153
2 168
2 185
3 134
3 136
3 151
3 153
3 168
3 185
4 134
4 136
4 151
4 153
4 168
4 185
5 151
5 153
5 168
5 185
6 151
6 153
6 168
6 185
7 168
7 185
8 185
9 185
# The same test but with NULLs mixed in as well
statement ok
CREATE TABLE wide_nulls AS (
SELECT i, c0, c1, c2,
CASE WHEN i % 7 = 0 THEN NULL ELSE c3 END AS c3,
c4, c5, c6, c7,
CASE WHEN i % 5 = 0 THEN NULL ELSE c8 END AS c8,
c9
FROM wide
);
query IIIIIIIIIII
SELECT * FROM wide_nulls;
----
1 10 20 30 40 50 60 70 80 90 100
2 20 30 40 50 60 70 80 90 100 110
3 30 40 50 60 70 80 90 100 110 120
4 40 50 60 70 80 90 100 110 120 130
5 50 60 70 80 90 100 110 120 NULL 140
6 60 70 80 90 100 110 120 130 140 150
7 70 80 90 NULL 110 120 130 140 150 160
8 80 90 100 110 120 130 140 150 160 170
9 90 100 110 120 130 140 150 160 170 180
statement ok
CREATE TABLE limits_nulls AS (
SELECT CASE WHEN z % 9 = 0 THEN NULL ELSE z END AS z
FROM limits
);
query I
SELECT * FROM limits_nulls;
----
NULL
134
151
168
185
102
119
136
NULL
query II
SELECT i, z
FROM wide_nulls, limits_nulls
WHERE c0 < z
AND c1 < z
AND c2 < z
AND c3 < z
AND c4 < z
AND c5 < z
AND c6 < z
AND c7 < z
AND c8 < z
AND c9 < z
ORDER BY 1, 2
----
1 102
1 119
1 134
1 136
1 151
1 168
1 185
2 119
2 134
2 136
2 151
2 168
2 185
3 134
3 136
3 151
3 168
3 185
4 134
4 136
4 151
4 168
4 185
6 151
6 168
6 185
8 185
9 185
# Joins on BETWEEN
query II
SELECT i, z
FROM wide, limits
WHERE z BETWEEN c8 AND c9
ORDER BY 1, 2;
----
2 102
3 117
3 119
5 134
5 136
7 151
7 153
8 168
query II
SELECT i, z
FROM wide_nulls, limits_nulls
WHERE z BETWEEN c8 AND c9
ORDER BY 1, 2;
----
2 102
3 119
7 151
8 168
# and NOT BETWEEN
query II
SELECT i, z
FROM wide, limits
WHERE z NOT BETWEEN c8 AND c9
ORDER BY 1, 2;
----
1 102
1 117
1 119
1 134
1 136
1 151
1 153
1 168
1 185
2 117
2 119
2 134
2 136
2 151
2 153
2 168
2 185
3 102
3 134
3 136
3 151
3 153
3 168
3 185
4 102
4 117
4 119
4 134
4 136
4 151
4 153
4 168
4 185
5 102
5 117
5 119
5 151
5 153
5 168
5 185
6 102
6 117
6 119
6 134
6 136
6 151
6 153
6 168
6 185
7 102
7 117
7 119
7 134
7 136
7 168
7 185
8 102
8 117
8 119
8 134
8 136
8 151
8 153
8 185
9 102
9 117
9 119
9 134
9 136
9 151
9 153
9 168
9 185
query II
SELECT i, z
FROM wide_nulls, limits_nulls
WHERE z NOT BETWEEN c8 AND c9
ORDER BY 1, 2;
----
1 102
1 119
1 134
1 136
1 151
1 168
1 185
2 119
2 134
2 136
2 151
2 168
2 185
3 102
3 134
3 136
3 151
3 168
3 185
4 102
4 119
4 134
4 136
4 151
4 168
4 185
5 151
5 168
5 185
6 102
6 119
6 134
6 136
6 151
6 168
6 185
7 102
7 119
7 134
7 136
7 168
7 185
8 102
8 119
8 134
8 136
8 151
8 185
9 102
9 119
9 134
9 136
9 151
9 168
9 185
# Some more tests with joins on COMPARE_DISTINCT_FROM
query II
SELECT lhs.i, rhs.i
FROM wide_nulls lhs, wide_nulls rhs
WHERE lhs.c3 < rhs.c0
AND lhs.c8 IS DISTINCT FROM rhs.c3
ORDER BY 1, 2;
----
1 5
1 7
1 8
1 9
2 6
2 7
2 8
2 9
3 7
3 9
4 8
5 9
query II
EXPLAIN
SELECT lhs.i, rhs.i
FROM wide_nulls lhs, wide_nulls rhs
WHERE lhs.c3 < rhs.c0
AND lhs.c8 IS DISTINCT FROM rhs.c3
ORDER BY 1, 2;
----
physical_plan <REGEX>:.*PIECEWISE_MERGE_JOIN.*
# Multi-predicate merge joins with many matches
# (similar to test/sql/join/inner/test_unequal_join_duplicates.test
# but with a merge join with multiple predicates)
statement ok
CREATE TABLE many_bounds AS (
SELECT * FROM (VALUES (2000, 4000)) tbl(lo, hi)
);
statement ok
CREATE TABLE many_values AS (
SELECT * from range(10 * 1024) tbl(val)
);
query I
SELECT COUNT(*)
FROM many_values, many_bounds
WHERE val BETWEEN lo AND hi;
----
2001

View File

@@ -0,0 +1,175 @@
# name: test/sql/join/test_huge_nested_payloads.test_slow
# description: Test join with nested types in a HUGE payload
# group: [join]
require parquet
statement ok
IMPORT DATABASE 'data/parquet-testing/malloy-smaller';
# minimal reproducible examples for internal issue 1546
query I
SELECT count(DISTINCT [[p.v2ProductName for p in h.product] for h in hits]) FROM tbl2;
----
1022
query I
SELECT count(DISTINCT [[p.customDimensions for p in h.product] for h in hits]) FROM tbl2;
----
794
query III
SELECT
hits_0.page."pageTitle" as "pageTitle",
COUNT(DISTINCT CONCAT(ga_sessions."__distinct_key", 'x', hits_0_outer.__row_id)) as "hits_count",
COUNT(DISTINCT CASE WHEN product_0."productQuantity">0
THEN CONCAT(ga_sessions."__distinct_key", 'x', hits_0_outer.__row_id) END) as "sold_count"
FROM (SELECT GEN_RANDOM_UUID() as __distinct_key, * FROM tbl2) as ga_sessions
LEFT JOIN LATERAL (SELECT UNNEST(GENERATE_SERIES(1, length(ga_sessions."hits"),1)) as __row_id,
UNNEST(ga_sessions."hits"), 1 as ignoreme) as hits_0_outer(__row_id, hits_0,ignoreme) ON hits_0_outer.ignoreme=1
LEFT JOIN LATERAL (SELECT UNNEST(hits_0."product"), 1 as ignoreme) as product_0_outer(product_0,ignoreme)
ON product_0_outer.ignoreme=1
WHERE ga_sessions.totals."transactionRevenue">0
GROUP BY 1
ORDER BY 2 DESC NULLS LAST, 1;
----
Shopping Cart 207 22
Checkout Confirmation 92 45
Infant | Kids' Apparel | Google Merchandise Store 89 24
Payment Method 89 0
Checkout Your Information 76 76
Home 62 0
Men's T-Shirts | Apparel | Google Merchandise Store 58 1
Store search results 56 8
Notebooks & Journals | Office | Google Merchandise Store 54 4
Electronics | Google Merchandise Store 51 3
The Google Merchandise Store - Log In 50 0
Men's Outerwear | Apparel | Google Merchandise Store 49 11
Bags | Google Merchandise Store 45 7
The Google Merchandise Store - My Account 43 0
Checkout Review 42 0
Men's Apparel | Google Merchandise Store 41 7
Headgear | Apparel | Google Merchandise Store 31 3
More Bags | Bags | Google Merchandise Store 29 0
Shopping & Totes | Bags | Google Merchandise Store 28 4
Youth | Kids' Apparel | Google Merchandise Store 25 4
Toddler | Kids' Apparel | Google Merchandise Store 24 5
Office | Google Merchandise Store 23 1
Accessories | Google Merchandise Store 21 2
Drinkware | Google Merchandise Store 21 3
Fun | Accessories | Google Merchandise Store 21 5
Women's Outerwear | Apparel | Google Merchandise Store 21 2
Water Bottles & Tumblers | Drinkware | Google Merchandise Store 17 2
Women's T-Shirts | Apparel | Google Merchandise Store 17 2
Flashlights | Electronics | Google Merchandise Store 13 1
Women's Performance Wear | Apparel | Google Merchandise Store 12 0
Google Men's 100% Cotton Short Sleeve Hero Tee Navy 11 1
Stickers | Accessories | Google Merchandise Store 11 1
Writing Instruments | Office | Google Merchandise Store 11 2
Google | Shop by Brand | Google Merchandise Store 10 0
Google Women's Scoop Neck Tee Black 9 0
The Google Merchandise Store/Malibu Sunglasses 9 5
Audio | Electronics | Google Merchandise Store 8 1
Google Infant Short Sleeve Tee Green 8 4
Google Power Bank 8 3
Google Women's 1/4 Zip Performance Pullover Black 7 3
Apparel | Google Merchandise Store 6 0
Backpacks | Bags | Google Merchandise Store 6 0
Google Men's Zip Hoodie 6 0
Kids' Apparel | Google Merchandise Store 6 1
NULL 6 1
Google Spiral Journal with Pen 5 2
Housewares | Accessories | Google Merchandise Store 5 0
Page Unavailable 5 0
The Google Merchandise Store/BRIGHTtravels Seat Pack Organizer 5 1
Accessories | Electronics | Google Merchandise Store 4 0
Google Men's 100% Cotton Short Sleeve Hero Tee White 4 1
Google Men's Bayside Graphic Tee 4 0
Google Snapback Hat Black 4 1
Google Women's Vintage Hero Tee Black 4 0
Mugs & Cups | Drinkware | Google Merchandise Store 4 0
Sports & Fitness | Accessories | Google Merchandise Store 4 0
Android Men's Long Sleeve Badge Crew Tee Heather 3 0
Collapsible Shopping Bag 3 2
Google 17oz Stainless Steel Sport Bottle 3 1
Google High Capacity 10,400mAh Charger 3 0
Google Leather Journal 3 1
Google Men's 100% Cotton Short Sleeve Hero Tee Black 3 0
Google Men's 100% Cotton Short Sleeve Hero Tee Red 3 0
Google Men's Watershed Full Zip Hoodie Grey 3 0
Google Online Store 3 0
Google Slim Utility Travel Bag 3 0
Google Women's Short Sleeve Hero Tee White 3 2
Other | Office | Google Merchandise Store 3 0
Suitcase Organizer Cubes 3 1
The Google Merchandise Store/Ballpoint LED Light Pen 3 1
Women's Apparel | Google Merchandise Store 3 0
26 oz Double Wall Insulated Bottle 2 1
Android Men's Short Sleeve Hero Tee White 2 1
Badge Holder 2 1
Clearance Sale 2 0
Clip-on Compact Charger 2 1
Crunch Noise Dog Toy 2 1
Foam Can and Bottle Cooler 2 1
Frequently Asked Questions 2 0
Google 22 oz Water Bottle 2 1
Google Car Clip Phone Holder 2 0
Google Doodle Decal 2 1
Google Luggage Tag 2 1
Google Lunch Bag 2 0
Google Men's Bike Short Sleeve Tee Charcoal 2 0
Google Men's Short Sleeve Badge Tee Charcoal 2 0
Google Men's Short Sleeve Hero Tee Charcoal 2 0
Google RFID Journal 2 0
Google Tube Power Bank 2 0
Google Women's Scoop Neck Tee White 2 0
Google Women's Short Sleeve Hero Tee Black 2 0
Google Women's Short Sleeve Performance Tee Charcoal 2 1
Google Women's Vintage Hero Tee White 2 0
Men's Performance Wear | Apparel | Google Merchandise Store 2 0
Power & Chargers | Electronics | Google Merchandise Store 2 0
Return Policy 2 0
SPF-15 Slim & Slender Lip Balm 2 1
Satin Black Ballpoint Pen 2 1
Spiral Notebook and Pen Set 2 1
Switch Tone Color Crayon Pen 2 1
The Google Merchandise Store/Galaxy Screen Cleaning Cloth 2 1
Waze Mood Original Window Decal 2 1
25L Classic Rucksack 1 0
Android Lunch Kit 1 0
Android Men's Engineer Short Sleeve Tee Charcoal 1 0
Android RFID Journal 1 0
Android Stretch Fit Hat 1 0
Ballpoint Stylus Pen 1 0
Four Color Retractable Pen 1 0
Google 4400mAh Power Bank 1 0
Google Alpine Style Backpack 1 0
Google Bib Red 1 0
Google Canvas Tote Natural/Navy 1 0
Google Flashlight 1 0
Google Hard Cover Journal 1 0
Google Infant Short Sleeve Tee White 1 0
Google Men's Vintage Badge Tee Black 1 0
Google Rucksack 1 0
Google Spiral Leather Journal 1 0
Google Tote Bag 1 0
Google Twill Cap 1 0
Google Women's 1/4 Zip Performance Pullover Two-Tone Blue 1 0
Google Women's Performance Full Zip Jacket Black 1 0
Google Women's Quilted Insulated Vest White 1 0
Google Women's Short Sleeve Badge Tee Navy 1 0
Google Women's Short Sleeve Hero Tee Grey 1 0
Google Youth Baseball Raglan Heather/Black 1 0
Google Youth Short Sleeve Tee White 1 0
Micro Wireless Earbud 1 0
Shipping Information 1 0
Shop by Brand | Google Merchandise Store 1 0
The Google Merchandise Store/Basecamp Explorer Powerbank Flashlight 1 0
The Google Merchandise Store/Colored Pencil Set 1 0
The Google Merchandise Store/Maze Pen 1 0
The Google Merchandise Store/Pen Pencil & Highlighter Set 1 0
The Google Merchandise Store/Plastic Sliding Flashlight 1 0
UpCycled Handlebar Bag 1 0
Waterproof Backpack 1 0
YouTube | Shop by Brand | Google Merchandise Store 1 0
Your Wishlist 1 0

View File

@@ -0,0 +1,29 @@
# name: test/sql/join/test_join_on_aggregates.test
# description: Test join on aggregates
# group: [join]
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
INSERT INTO integers VALUES (1), (2), (3), (NULL)
# test join on ungrouped aggregates
query RR
SELECT * FROM (SELECT SUM(i) AS x FROM integers) a, (SELECT SUM(i) AS x FROM integers) b WHERE a.x=b.x;
----
6.000000 6.000000
# Test join on aggregates with GROUP BY
statement ok
CREATE TABLE groups(i INTEGER, j INTEGER)
statement ok
INSERT INTO groups VALUES (1, 1), (2, 1), (3, 2), (NULL, 2)
query IRII
SELECT a.j,a.x,a.y,b.y FROM (SELECT j, MIN(i) AS y, SUM(i) AS x FROM groups GROUP BY j) a, (SELECT j, MIN(i) AS y, SUM(i) AS x FROM groups GROUP BY j) b WHERE a.j=b.j AND a.x=b.x ORDER BY a.j;
----
1 3.000000 1 1
2 3.000000 3 3

View File

@@ -0,0 +1,101 @@
#name: test/sql/join/test_joins_on_weird_indexes.test
# description: Test joins that stress the logic of the join order optimizer
# group: [join]
statement ok
CREATE TABLE integers(i INTEGER)
statement ok
INSERT INTO integers VALUES (1), (2), (3), (NULL)
# join multiple set operations
query I
SELECT SUM(i) FROM integers UNION ALL SELECT AVG(i) FROM integers UNION ALL SELECT MIN(i) FROM integers UNION ALL SELECT MAX(i) FROM integers;
----
6.000000
2.000000
1.000000
3.000000
# join multiple set operations
statement ok
SELECT *, i1.rowid as diff_row_id_name FROM integers i1, integers i2 where i1.rowid = i2.i;
statement ok
create table t1 as (select range as a from range(20));
statement ok
create table t2 as (select range as a from range(30));
statement ok
create table t3 as (select range as a from range(50));
statement ok
select t3.a from t3, (select * from t2 intersect select * from t1) t4 where t4.a=t3.a;
# join on PIVOT results
statement ok
CREATE TABLE Cities(Country VARCHAR, Name VARCHAR, Year INT, Population INT);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2000, 1005);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2010, 1065);
statement ok
INSERT INTO Cities VALUES ('NL', 'Amsterdam', 2020, 1158);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2000, 564);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2010, 608);
statement ok
INSERT INTO Cities VALUES ('US', 'Seattle', 2020, 738);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2000, 8015);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2010, 8175);
statement ok
INSERT INTO Cities VALUES ('US', 'New York City', 2020, 8772);
statement ok
create table cities_i_have_been_to (Name Varchar);
statement ok
insert into cities_i_have_been_to VALUES ('Amsterdam'), ('Seattle'), ('New York City');
statement ok
select * from (PIVOT Cities ON Year USING SUM(Population)) t1, cities_i_have_been_to t2 where t1.Name=t2.Name;
statement ok
insert into t1 (select * from range(100));
statement ok
insert into t2 (select * from range(100));
statement ok
insert into t3 (select * from range(100));
# join on a constant value column from reorderable to non-reorderable to reorderable
statement ok
select outer_table_1.a from
t1 as outer_table_1
inner join t2 as outer_table_2
on outer_table_1.a = outer_table_2.a
inner join
t3 as inner_table_1
left join t1 as left_join_table_1
inner join (select 50 as rand_int,
from t3 where t3.a >= 0) as constant_table
on left_join_table_1.a = constant_table.rand_int
on inner_table_1.a = left_join_table_1.a
on outer_table_1.a = constant_table.rand_int;

View File

@@ -0,0 +1,183 @@
# name: test/sql/join/test_nested_inequality.test
# description: Test join with nested types for the keys
# group: [join]
statement ok
CREATE VIEW list_int AS
SELECT i, i%2 as i2, [i, i + 1, i + 2] as l3
FROM range(10) tbl(i);
query IIIIII
select lhs.*, rhs.*
from list_int lhs, list_int rhs
where lhs.i2 = rhs.i2 and lhs.l3 <> rhs.l3
order by lhs.i, rhs.i;
----
0 0 [0, 1, 2] 2 0 [2, 3, 4]
0 0 [0, 1, 2] 4 0 [4, 5, 6]
0 0 [0, 1, 2] 6 0 [6, 7, 8]
0 0 [0, 1, 2] 8 0 [8, 9, 10]
1 1 [1, 2, 3] 3 1 [3, 4, 5]
1 1 [1, 2, 3] 5 1 [5, 6, 7]
1 1 [1, 2, 3] 7 1 [7, 8, 9]
1 1 [1, 2, 3] 9 1 [9, 10, 11]
2 0 [2, 3, 4] 0 0 [0, 1, 2]
2 0 [2, 3, 4] 4 0 [4, 5, 6]
2 0 [2, 3, 4] 6 0 [6, 7, 8]
2 0 [2, 3, 4] 8 0 [8, 9, 10]
3 1 [3, 4, 5] 1 1 [1, 2, 3]
3 1 [3, 4, 5] 5 1 [5, 6, 7]
3 1 [3, 4, 5] 7 1 [7, 8, 9]
3 1 [3, 4, 5] 9 1 [9, 10, 11]
4 0 [4, 5, 6] 0 0 [0, 1, 2]
4 0 [4, 5, 6] 2 0 [2, 3, 4]
4 0 [4, 5, 6] 6 0 [6, 7, 8]
4 0 [4, 5, 6] 8 0 [8, 9, 10]
5 1 [5, 6, 7] 1 1 [1, 2, 3]
5 1 [5, 6, 7] 3 1 [3, 4, 5]
5 1 [5, 6, 7] 7 1 [7, 8, 9]
5 1 [5, 6, 7] 9 1 [9, 10, 11]
6 0 [6, 7, 8] 0 0 [0, 1, 2]
6 0 [6, 7, 8] 2 0 [2, 3, 4]
6 0 [6, 7, 8] 4 0 [4, 5, 6]
6 0 [6, 7, 8] 8 0 [8, 9, 10]
7 1 [7, 8, 9] 1 1 [1, 2, 3]
7 1 [7, 8, 9] 3 1 [3, 4, 5]
7 1 [7, 8, 9] 5 1 [5, 6, 7]
7 1 [7, 8, 9] 9 1 [9, 10, 11]
8 0 [8, 9, 10] 0 0 [0, 1, 2]
8 0 [8, 9, 10] 2 0 [2, 3, 4]
8 0 [8, 9, 10] 4 0 [4, 5, 6]
8 0 [8, 9, 10] 6 0 [6, 7, 8]
9 1 [9, 10, 11] 1 1 [1, 2, 3]
9 1 [9, 10, 11] 3 1 [3, 4, 5]
9 1 [9, 10, 11] 5 1 [5, 6, 7]
9 1 [9, 10, 11] 7 1 [7, 8, 9]
query IIIIII
select lhs.*, rhs.*
from list_int lhs, list_int rhs
where lhs.i2 = rhs.i2 and lhs.l3 <= rhs.l3
order by lhs.i, rhs.i;
----
0 0 [0, 1, 2] 0 0 [0, 1, 2]
0 0 [0, 1, 2] 2 0 [2, 3, 4]
0 0 [0, 1, 2] 4 0 [4, 5, 6]
0 0 [0, 1, 2] 6 0 [6, 7, 8]
0 0 [0, 1, 2] 8 0 [8, 9, 10]
1 1 [1, 2, 3] 1 1 [1, 2, 3]
1 1 [1, 2, 3] 3 1 [3, 4, 5]
1 1 [1, 2, 3] 5 1 [5, 6, 7]
1 1 [1, 2, 3] 7 1 [7, 8, 9]
1 1 [1, 2, 3] 9 1 [9, 10, 11]
2 0 [2, 3, 4] 2 0 [2, 3, 4]
2 0 [2, 3, 4] 4 0 [4, 5, 6]
2 0 [2, 3, 4] 6 0 [6, 7, 8]
2 0 [2, 3, 4] 8 0 [8, 9, 10]
3 1 [3, 4, 5] 3 1 [3, 4, 5]
3 1 [3, 4, 5] 5 1 [5, 6, 7]
3 1 [3, 4, 5] 7 1 [7, 8, 9]
3 1 [3, 4, 5] 9 1 [9, 10, 11]
4 0 [4, 5, 6] 4 0 [4, 5, 6]
4 0 [4, 5, 6] 6 0 [6, 7, 8]
4 0 [4, 5, 6] 8 0 [8, 9, 10]
5 1 [5, 6, 7] 5 1 [5, 6, 7]
5 1 [5, 6, 7] 7 1 [7, 8, 9]
5 1 [5, 6, 7] 9 1 [9, 10, 11]
6 0 [6, 7, 8] 6 0 [6, 7, 8]
6 0 [6, 7, 8] 8 0 [8, 9, 10]
7 1 [7, 8, 9] 7 1 [7, 8, 9]
7 1 [7, 8, 9] 9 1 [9, 10, 11]
8 0 [8, 9, 10] 8 0 [8, 9, 10]
9 1 [9, 10, 11] 9 1 [9, 10, 11]
query IIIIII
select lhs.*, rhs.*
from list_int lhs, list_int rhs
where lhs.i2 = rhs.i2 and lhs.l3 < rhs.l3
order by lhs.i, rhs.i;
----
0 0 [0, 1, 2] 2 0 [2, 3, 4]
0 0 [0, 1, 2] 4 0 [4, 5, 6]
0 0 [0, 1, 2] 6 0 [6, 7, 8]
0 0 [0, 1, 2] 8 0 [8, 9, 10]
1 1 [1, 2, 3] 3 1 [3, 4, 5]
1 1 [1, 2, 3] 5 1 [5, 6, 7]
1 1 [1, 2, 3] 7 1 [7, 8, 9]
1 1 [1, 2, 3] 9 1 [9, 10, 11]
2 0 [2, 3, 4] 4 0 [4, 5, 6]
2 0 [2, 3, 4] 6 0 [6, 7, 8]
2 0 [2, 3, 4] 8 0 [8, 9, 10]
3 1 [3, 4, 5] 5 1 [5, 6, 7]
3 1 [3, 4, 5] 7 1 [7, 8, 9]
3 1 [3, 4, 5] 9 1 [9, 10, 11]
4 0 [4, 5, 6] 6 0 [6, 7, 8]
4 0 [4, 5, 6] 8 0 [8, 9, 10]
5 1 [5, 6, 7] 7 1 [7, 8, 9]
5 1 [5, 6, 7] 9 1 [9, 10, 11]
6 0 [6, 7, 8] 8 0 [8, 9, 10]
7 1 [7, 8, 9] 9 1 [9, 10, 11]
query IIIIII
select lhs.*, rhs.*
from list_int lhs, list_int rhs
where lhs.i2 = rhs.i2 and lhs.l3 >= rhs.l3
order by lhs.i, rhs.i;
----
0 0 [0, 1, 2] 0 0 [0, 1, 2]
1 1 [1, 2, 3] 1 1 [1, 2, 3]
2 0 [2, 3, 4] 0 0 [0, 1, 2]
2 0 [2, 3, 4] 2 0 [2, 3, 4]
3 1 [3, 4, 5] 1 1 [1, 2, 3]
3 1 [3, 4, 5] 3 1 [3, 4, 5]
4 0 [4, 5, 6] 0 0 [0, 1, 2]
4 0 [4, 5, 6] 2 0 [2, 3, 4]
4 0 [4, 5, 6] 4 0 [4, 5, 6]
5 1 [5, 6, 7] 1 1 [1, 2, 3]
5 1 [5, 6, 7] 3 1 [3, 4, 5]
5 1 [5, 6, 7] 5 1 [5, 6, 7]
6 0 [6, 7, 8] 0 0 [0, 1, 2]
6 0 [6, 7, 8] 2 0 [2, 3, 4]
6 0 [6, 7, 8] 4 0 [4, 5, 6]
6 0 [6, 7, 8] 6 0 [6, 7, 8]
7 1 [7, 8, 9] 1 1 [1, 2, 3]
7 1 [7, 8, 9] 3 1 [3, 4, 5]
7 1 [7, 8, 9] 5 1 [5, 6, 7]
7 1 [7, 8, 9] 7 1 [7, 8, 9]
8 0 [8, 9, 10] 0 0 [0, 1, 2]
8 0 [8, 9, 10] 2 0 [2, 3, 4]
8 0 [8, 9, 10] 4 0 [4, 5, 6]
8 0 [8, 9, 10] 6 0 [6, 7, 8]
8 0 [8, 9, 10] 8 0 [8, 9, 10]
9 1 [9, 10, 11] 1 1 [1, 2, 3]
9 1 [9, 10, 11] 3 1 [3, 4, 5]
9 1 [9, 10, 11] 5 1 [5, 6, 7]
9 1 [9, 10, 11] 7 1 [7, 8, 9]
9 1 [9, 10, 11] 9 1 [9, 10, 11]
query IIIIII
select lhs.*, rhs.*
from list_int lhs, list_int rhs
where lhs.i2 = rhs.i2 and lhs.l3 > rhs.l3
order by lhs.i, rhs.i;
----
2 0 [2, 3, 4] 0 0 [0, 1, 2]
3 1 [3, 4, 5] 1 1 [1, 2, 3]
4 0 [4, 5, 6] 0 0 [0, 1, 2]
4 0 [4, 5, 6] 2 0 [2, 3, 4]
5 1 [5, 6, 7] 1 1 [1, 2, 3]
5 1 [5, 6, 7] 3 1 [3, 4, 5]
6 0 [6, 7, 8] 0 0 [0, 1, 2]
6 0 [6, 7, 8] 2 0 [2, 3, 4]
6 0 [6, 7, 8] 4 0 [4, 5, 6]
7 1 [7, 8, 9] 1 1 [1, 2, 3]
7 1 [7, 8, 9] 3 1 [3, 4, 5]
7 1 [7, 8, 9] 5 1 [5, 6, 7]
8 0 [8, 9, 10] 0 0 [0, 1, 2]
8 0 [8, 9, 10] 2 0 [2, 3, 4]
8 0 [8, 9, 10] 4 0 [4, 5, 6]
8 0 [8, 9, 10] 6 0 [6, 7, 8]
9 1 [9, 10, 11] 1 1 [1, 2, 3]
9 1 [9, 10, 11] 3 1 [3, 4, 5]
9 1 [9, 10, 11] 5 1 [5, 6, 7]
9 1 [9, 10, 11] 7 1 [7, 8, 9]

View File

@@ -0,0 +1,426 @@
# name: test/sql/join/test_nested_keys.test_slow
# description: Test join with nested types for the keys
# group: [join]
statement ok
SET default_null_order='nulls_first';
statement ok
PRAGMA enable_verification
# Key is LIST<INTEGER>
statement ok
CREATE VIEW intlistdim AS SELECT * FROM (VALUES
([1]),
([NULL]),
([]),
([9,10,11]),
(NULL)
) lv(pk);
statement ok
CREATE VIEW intlists AS SELECT * FROM (VALUES
(1, [1]),
(2, [NULL]),
(3, []),
(4, [2, 3]),
(5, [9,10,11]),
(NULL::INTEGER, [13])
) lv(i, fk);
query III
SELECT i, pk, fk FROM intlistdim, intlists WHERE pk = fk ORDER BY i
----
1 [1] [1]
2 [NULL] [NULL]
3 [] []
5 [9, 10, 11] [9, 10, 11]
query III
SELECT i, pk, fk FROM intlistdim LEFT OUTER JOIN intlists ON intlistdim.pk=intlists.fk ORDER BY i
----
NULL NULL NULL
1 [1] [1]
2 [NULL] [NULL]
3 [] []
5 [9, 10, 11] [9, 10, 11]
query III
SELECT i, pk, fk FROM intlists RIGHT OUTER JOIN intlistdim ON intlistdim.pk=intlists.fk ORDER BY i
----
NULL NULL NULL
1 [1] [1]
2 [NULL] [NULL]
3 [] []
5 [9, 10, 11] [9, 10, 11]
query III
SELECT i, pk, fk FROM intlistdim FULL OUTER JOIN intlists ON intlistdim.pk=intlists.fk ORDER BY ALL
----
NULL NULL NULL
NULL NULL [13]
1 [1] [1]
2 [NULL] [NULL]
3 [] []
4 NULL [2, 3]
5 [9, 10, 11] [9, 10, 11]
# Key is LIST<VARCHAR>
statement ok
CREATE VIEW strlistdim AS SELECT * FROM (VALUES
(['a']),
([NULL]),
([]),
(['i','j','k']),
(NULL)
) lv(pk);
statement ok
CREATE VIEW strlists AS SELECT * FROM (VALUES
(1, ['a']),
(2, [NULL]),
(3, []),
(4, ['Branta Canadensis', 'c']),
(5, ['i','j','k']),
(NULL::INTEGER, ['Somateria mollissima'])
) lv(i, fk);
query III
SELECT i, pk, fk FROM strlistdim, strlists WHERE pk = fk ORDER BY i
----
1 [a] [a]
2 [NULL] [NULL]
3 [] []
5 [i, j, k] [i, j, k]
query III
SELECT i, pk, fk FROM strlistdim LEFT OUTER JOIN strlists ON strlistdim.pk=strlists.fk ORDER BY i
----
NULL NULL NULL
1 [a] [a]
2 [NULL] [NULL]
3 [] []
5 [i, j, k] [i, j, k]
query III
SELECT i, pk, fk FROM strlists RIGHT OUTER JOIN strlistdim ON strlistdim.pk=strlists.fk ORDER BY i
----
NULL NULL NULL
1 [a] [a]
2 [NULL] [NULL]
3 [] []
5 [i, j, k] [i, j, k]
query III
SELECT i, pk, fk FROM strlistdim FULL OUTER JOIN strlists ON strlistdim.pk=strlists.fk ORDER BY ALL
----
NULL NULL NULL
NULL NULL [Somateria mollissima]
1 [a] [a]
2 [NULL] [NULL]
3 [] []
4 NULL [Branta Canadensis, c]
5 [i, j, k] [i, j, k]
# Key is STRUCT<x: INTEGER, y: VARCHAR>
statement ok
CREATE VIEW structdim AS SELECT * FROM (VALUES
({'x': 1, 'y': 'a'}),
({'x': NULL, 'y': NULL}),
({'x': 0, 'y': ''}),
({'x': 9, 'y': 'i'}),
(NULL)
) sd(pk);
statement ok
CREATE VIEW structs AS SELECT * FROM (VALUES
(1, {'x': 1, 'y': 'a'}),
(2, {'x': NULL, 'y': NULL}),
(3, {'x': 0, 'y': ''}),
(4, {'x': 2, 'y': 'c'}),
(5, {'x': 9, 'y': 'i'}),
(NULL::INTEGER, {'x': 13, 'y': 'Somateria mollissima'})
) sv(i, fk);
query III
SELECT i, pk, fk FROM structdim, structs WHERE pk = fk ORDER BY i
----
1 {'x': 1, 'y': a} {'x': 1, 'y': a}
2 {'x': NULL, 'y': NULL} {'x': NULL, 'y': NULL}
3 {'x': 0, 'y': ''} {'x': 0, 'y': ''}
5 {'x': 9, 'y': i} {'x': 9, 'y': i}
query III
SELECT i, pk, fk FROM structdim LEFT OUTER JOIN structs ON structdim.pk=structs.fk ORDER BY i
----
NULL NULL NULL
1 {'x': 1, 'y': a} {'x': 1, 'y': a}
2 {'x': NULL, 'y': NULL} {'x': NULL, 'y': NULL}
3 {'x': 0, 'y': ''} {'x': 0, 'y': ''}
5 {'x': 9, 'y': i} {'x': 9, 'y': i}
query III
SELECT i, pk, fk FROM structs RIGHT OUTER JOIN structdim ON structdim.pk=structs.fk ORDER BY i
----
NULL NULL NULL
1 {'x': 1, 'y': a} {'x': 1, 'y': a}
2 {'x': NULL, 'y': NULL} {'x': NULL, 'y': NULL}
3 {'x': 0, 'y': ''} {'x': 0, 'y': ''}
5 {'x': 9, 'y': i} {'x': 9, 'y': i}
query III
SELECT i, pk, fk FROM structdim FULL OUTER JOIN structs ON structdim.pk=structs.fk ORDER BY ALL
----
NULL NULL NULL
NULL NULL {'x': 13, 'y': Somateria mollissima}
1 {'x': 1, 'y': a} {'x': 1, 'y': a}
2 {'x': NULL, 'y': NULL} {'x': NULL, 'y': NULL}
3 {'x': 0, 'y': ''} {'x': 0, 'y': ''}
4 NULL {'x': 2, 'y': c}
5 {'x': 9, 'y': i} {'x': 9, 'y': i}
# Key is STRUCT<x: LIST<INTEGER>, y: LIST<VARCHAR> >
statement ok
CREATE VIEW struct_lint_lstr_dim AS SELECT * FROM (VALUES
({'x': [1], 'y': ['a']}),
({'x': [NULL], 'y': [NULL]}),
({'x': [], 'y': []}),
({'x': [2, 3], 'y': ['Branta Canadensis', 'c']}),
(NULL)
) dim(pk);
statement ok
CREATE VIEW struct_lint_lstr AS SELECT * FROM (VALUES
(1, {'x': [1], 'y': ['a']}),
(2, {'x': [NULL], 'y': [NULL]}),
(3, {'x': [], 'y': []}),
(4, {'x': [2, 3], 'y': ['Branta Canadensis', 'c']}),
(5, {'x': [9,10,11], 'y': ['i','j','k']}),
(NULL::INTEGER, {'x': [13], 'y': ['Somateria mollissima']})
) fact(i, fk);
query III
SELECT i, pk, fk
FROM struct_lint_lstr_dim, struct_lint_lstr
WHERE pk = fk
ORDER BY i
----
1 {'x': [1], 'y': [a]} {'x': [1], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [2, 3], 'y': [Branta Canadensis, c]} {'x': [2, 3], 'y': [Branta Canadensis, c]}
query III
SELECT i, pk, fk
FROM struct_lint_lstr_dim
LEFT OUTER JOIN struct_lint_lstr
ON struct_lint_lstr_dim.pk = struct_lint_lstr.fk
ORDER BY i
----
NULL NULL NULL
1 {'x': [1], 'y': [a]} {'x': [1], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [2, 3], 'y': [Branta Canadensis, c]} {'x': [2, 3], 'y': [Branta Canadensis, c]}
query III
SELECT i, pk, fk
FROM struct_lint_lstr
RIGHT OUTER JOIN struct_lint_lstr_dim
ON struct_lint_lstr_dim.pk = struct_lint_lstr.fk
ORDER BY i
----
NULL NULL NULL
1 {'x': [1], 'y': [a]} {'x': [1], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [2, 3], 'y': [Branta Canadensis, c]} {'x': [2, 3], 'y': [Branta Canadensis, c]}
query III
SELECT i, pk, fk
FROM struct_lint_lstr_dim
FULL OUTER JOIN struct_lint_lstr
ON struct_lint_lstr_dim.pk=struct_lint_lstr.fk
ORDER BY ALL
----
NULL NULL NULL
NULL NULL {'x': [13], 'y': [Somateria mollissima]}
1 {'x': [1], 'y': [a]} {'x': [1], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [2, 3], 'y': [Branta Canadensis, c]} {'x': [2, 3], 'y': [Branta Canadensis, c]}
5 NULL {'x': [9, 10, 11], 'y': [i, j, k]}
# Payload is STRUCT<x: LIST<STRUCT<l4: LIST<INT>, i4 INT> >, y: LIST<VARCHAR> >.
statement ok
CREATE VIEW r2l3r4l5i4i2l3v AS SELECT * FROM (VALUES
(1, {'x': [{'l4': [51], 'i4': 41}], 'y': ['a']}),
(2, {'x': [NULL], 'y': [NULL]}),
(3, {'x': [], 'y': []}),
(4, {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': ['Branta Canadensis', 'c']}),
(5, {'x': [{'l4': [56], 'i4': 44}, {'l4': [57, 58], 'i4': 45}, {'l4': [59, 60, 61], 'i4': 46}], 'y': ['i','j','k']}),
(NULL::INTEGER, {'x': [{'l4': [62], 'i4': 47}], 'y': ['Somateria mollissima']})
) fact(i, fk);
statement ok
CREATE VIEW r2l3r4l5i4i2l3v_dim AS SELECT * FROM (VALUES
({'x': [{'l4': [51], 'i4': 41}], 'y': ['a']}),
({'x': [NULL], 'y': [NULL]}),
({'x': [], 'y': []}),
({'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': ['Branta Canadensis', 'c']}),
(NULL)
) dim(pk);
query III
SELECT i, pk, fk
FROM r2l3r4l5i4i2l3v_dim, r2l3r4l5i4i2l3v
WHERE fk = pk
ORDER BY i
----
1 {'x': [{'l4': [51], 'i4': 41}], 'y': [a]} {'x': [{'l4': [51], 'i4': 41}], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]} {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]}
query III
SELECT i, pk, fk
FROM r2l3r4l5i4i2l3v_dim
LEFT OUTER JOIN r2l3r4l5i4i2l3v
ON r2l3r4l5i4i2l3v_dim.pk = r2l3r4l5i4i2l3v.fk
ORDER BY i
----
NULL NULL NULL
1 {'x': [{'l4': [51], 'i4': 41}], 'y': [a]} {'x': [{'l4': [51], 'i4': 41}], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]} {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]}
query III
SELECT i, pk, fk
FROM r2l3r4l5i4i2l3v_dim
RIGHT OUTER JOIN r2l3r4l5i4i2l3v
ON r2l3r4l5i4i2l3v_dim.pk = r2l3r4l5i4i2l3v.fk
ORDER BY i
----
NULL NULL {'x': [{'l4': [62], 'i4': 47}], 'y': [Somateria mollissima]}
1 {'x': [{'l4': [51], 'i4': 41}], 'y': [a]} {'x': [{'l4': [51], 'i4': 41}], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]} {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]}
5 NULL {'x': [{'l4': [56], 'i4': 44}, {'l4': [57, 58], 'i4': 45}, {'l4': [59, 60, 61], 'i4': 46}], 'y': [i, j, k]}
query III
SELECT i, pk, fk
FROM r2l3r4l5i4i2l3v_dim
FULL OUTER JOIN r2l3r4l5i4i2l3v
ON r2l3r4l5i4i2l3v_dim.pk = r2l3r4l5i4i2l3v.fk
ORDER BY ALL
----
NULL NULL NULL
NULL NULL {'x': [{'l4': [62], 'i4': 47}], 'y': [Somateria mollissima]}
1 {'x': [{'l4': [51], 'i4': 41}], 'y': [a]} {'x': [{'l4': [51], 'i4': 41}], 'y': [a]}
2 {'x': [NULL], 'y': [NULL]} {'x': [NULL], 'y': [NULL]}
3 {'x': [], 'y': []} {'x': [], 'y': []}
4 {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]} {'x': [{'l4': [52, 53], 'i4': 42}, {'l4': [54, 55], 'i4': 43}], 'y': [Branta Canadensis, c]}
5 NULL {'x': [{'l4': [56], 'i4': 44}, {'l4': [57, 58], 'i4': 45}, {'l4': [59, 60, 61], 'i4': 46}], 'y': [i, j, k]}
# Key is LIST<INTEGER[2000]>
statement ok
CREATE VIEW longlists AS
SELECT *
FROM ((VALUES
(1, [1]),
(2, [NULL]),
(3, []),
(4, [2, 3]),
(NULL::INTEGER, [13])
)
UNION ALL
select 5 as i, list(r) as pk from range(2000) tbl(r)
) lv(i, fk);
statement ok
CREATE VIEW longlists_dim AS
SELECT *
FROM ((VALUES
([1]),
([NULL]),
([]),
([2, 3]),
(NULL)
)
UNION ALL
select list(r) as pk from range(2000) tbl(r)
UNION ALL
select list(r) as pk from range(1050) tbl(r)
) dim(pk);
query III
SELECT i, pk, fk
FROM longlists_dim, longlists
WHERE fk = pk
ORDER BY 1, 2, 3
----
15 values hashing to 9cf60d50bdcdf90da73b0fbdc873da5b
query III
SELECT i, pk, fk
FROM longlists_dim
LEFT OUTER JOIN longlists
ON longlists.fk = longlists_dim.pk
ORDER BY 1, 2, 3
----
21 values hashing to 4220e1d4299da1bd2d8baa63e2714a05
query III
SELECT i, pk, fk
FROM longlists_dim
RIGHT OUTER JOIN longlists
ON longlists.fk = longlists_dim.pk
ORDER BY 1, 2, 3
----
18 values hashing to 2cb5cda12f183cadc7ff1ac7fb599eed
query III
SELECT i, pk, fk
FROM longlists_dim
FULL OUTER JOIN longlists
ON longlists.fk = longlists_dim.pk
ORDER BY 1, 2, 3
----
24 values hashing to 6df3ff46363f2676f8a97128fc0e7e34
# Multiple key matches
query II
select * from (
(select [1,2,3] a from range(3))) tbl(i)
join
((select [1,2,3] a from range(3))) tbl2(j)
on (i=j);
----
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
[1, 2, 3] [1, 2, 3]
query II
select * from (
(select {'x': 1, 'y': 2, 'z': 3} a from range(3))) tbl(i)
join
((select {'x': 1, 'y': 2, 'z': 3} a from range(3))) tbl2(j)
on (i=j);
----
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}
{'x': 1, 'y': 2, 'z': 3} {'x': 1, 'y': 2, 'z': 3}

Some files were not shown because too many files have changed in this diff Show More