should be it
This commit is contained in:
120
external/duckdb/test/sql/join/asof/test_asof_join.test
vendored
Normal file
120
external/duckdb/test/sql/join/asof/test_asof_join.test
vendored
Normal 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
|
||||
64
external/duckdb/test/sql/join/asof/test_asof_join.test_slow
vendored
Normal file
64
external/duckdb/test/sql/join/asof/test_asof_join.test_slow
vendored
Normal 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
|
||||
354
external/duckdb/test/sql/join/asof/test_asof_join_doubles.test
vendored
Normal file
354
external/duckdb/test/sql/join/asof/test_asof_join_doubles.test
vendored
Normal 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
|
||||
----
|
||||
236
external/duckdb/test/sql/join/asof/test_asof_join_inequalities.test
vendored
Normal file
236
external/duckdb/test/sql/join/asof/test_asof_join_inequalities.test
vendored
Normal 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
|
||||
138
external/duckdb/test/sql/join/asof/test_asof_join_integers.test
vendored
Normal file
138
external/duckdb/test/sql/join/asof/test_asof_join_integers.test
vendored
Normal 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
|
||||
29
external/duckdb/test/sql/join/asof/test_asof_join_merge.test_slow
vendored
Normal file
29
external/duckdb/test/sql/join/asof/test_asof_join_merge.test_slow
vendored
Normal 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
|
||||
165
external/duckdb/test/sql/join/asof/test_asof_join_missing.test_slow
vendored
Normal file
165
external/duckdb/test/sql/join/asof/test_asof_join_missing.test_slow
vendored
Normal 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
|
||||
114
external/duckdb/test/sql/join/asof/test_asof_join_predicates.test
vendored
Normal file
114
external/duckdb/test/sql/join/asof/test_asof_join_predicates.test
vendored
Normal 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;
|
||||
201
external/duckdb/test/sql/join/asof/test_asof_join_pushdown.test
vendored
Normal file
201
external/duckdb/test/sql/join/asof/test_asof_join_pushdown.test
vendored
Normal 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
|
||||
41
external/duckdb/test/sql/join/asof/test_asof_join_subquery.test
vendored
Normal file
41
external/duckdb/test/sql/join/asof/test_asof_join_subquery.test
vendored
Normal 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
|
||||
232
external/duckdb/test/sql/join/asof/test_asof_join_timestamps.test
vendored
Normal file
232
external/duckdb/test/sql/join/asof/test_asof_join_timestamps.test
vendored
Normal 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
|
||||
25
external/duckdb/test/sql/join/asof/test_asof_join_tpch.test_slow
vendored
Normal file
25
external/duckdb/test/sql/join/asof/test_asof_join_tpch.test_slow
vendored
Normal 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
|
||||
138
external/duckdb/test/sql/join/asof/test_asof_join_varchar.test
vendored
Normal file
138
external/duckdb/test/sql/join/asof/test_asof_join_varchar.test
vendored
Normal 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
|
||||
Reference in New Issue
Block a user