Back to home page

OSCL-LXR

 
 

    


0001 --
0002 -- Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
0003 --
0004 --
0005 -- UNION (also INTERSECT, EXCEPT)
0006 -- https://github.com/postgres/postgres/blob/REL_12_BETA2/src/test/regress/sql/union.sql
0007 --
0008 
0009 CREATE OR REPLACE TEMPORARY VIEW INT4_TBL AS SELECT * FROM
0010   (VALUES (0), (123456), (-123456), (2147483647), (-2147483647))
0011   AS v(f1);
0012 CREATE OR REPLACE TEMPORARY VIEW INT8_TBL AS SELECT * FROM
0013   (VALUES
0014     (123, 456),
0015     (123, 4567890123456789),
0016     (4567890123456789, 123),
0017     (4567890123456789, 4567890123456789),
0018     (4567890123456789, -4567890123456789))
0019   AS v(q1, q2);
0020 CREATE OR REPLACE TEMPORARY VIEW FLOAT8_TBL AS SELECT * FROM
0021   (VALUES (0.0), (-34.84), (-1004.30),
0022     (CAST('-1.2345678901234e+200' AS DOUBLE)), (CAST('-1.2345678901234e-200' AS DOUBLE)))
0023   AS v(f1);
0024 
0025 -- Simple UNION constructs
0026 
0027 SELECT 1 AS two UNION SELECT 2 ORDER BY 1;
0028 
0029 SELECT 1 AS one UNION SELECT 1 ORDER BY 1;
0030 
0031 SELECT 1 AS two UNION ALL SELECT 2;
0032 
0033 SELECT 1 AS two UNION ALL SELECT 1;
0034 
0035 SELECT 1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1;
0036 
0037 SELECT 1 AS two UNION SELECT 2 UNION SELECT 2 ORDER BY 1;
0038 
0039 SELECT 1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1;
0040 
0041 SELECT 1.1 AS two UNION SELECT 2.2 ORDER BY 1;
0042 
0043 -- Mixed types
0044 
0045 SELECT 1.1 AS two UNION SELECT 2 ORDER BY 1;
0046 
0047 SELECT 1 AS two UNION SELECT 2.2 ORDER BY 1;
0048 
0049 SELECT 1 AS one UNION SELECT double(1.0) ORDER BY 1;
0050 
0051 SELECT 1.1 AS two UNION ALL SELECT 2 ORDER BY 1;
0052 
0053 SELECT double(1.0) AS two UNION ALL SELECT 1 ORDER BY 1;
0054 
0055 SELECT 1.1 AS three UNION SELECT 2 UNION SELECT 3 ORDER BY 1;
0056 
0057 SELECT double(1.1) AS two UNION SELECT 2 UNION SELECT double(2.0) ORDER BY 1;
0058 
0059 SELECT 1.1 AS three UNION SELECT 2 UNION ALL SELECT 2 ORDER BY 1;
0060 
0061 SELECT 1.1 AS two UNION (SELECT 2 UNION ALL SELECT 2) ORDER BY 1;
0062 
0063 --
0064 -- Try testing from tables...
0065 --
0066 
0067 SELECT f1 AS five FROM FLOAT8_TBL
0068 UNION
0069 SELECT f1 FROM FLOAT8_TBL
0070 ORDER BY 1;
0071 
0072 SELECT f1 AS ten FROM FLOAT8_TBL
0073 UNION ALL
0074 SELECT f1 FROM FLOAT8_TBL;
0075 
0076 SELECT f1 AS nine FROM FLOAT8_TBL
0077 UNION
0078 SELECT f1 FROM INT4_TBL
0079 ORDER BY 1;
0080 
0081 SELECT f1 AS ten FROM FLOAT8_TBL
0082 UNION ALL
0083 SELECT f1 FROM INT4_TBL;
0084 
0085 SELECT f1 AS five FROM FLOAT8_TBL
0086   WHERE f1 BETWEEN -1e6 AND 1e6
0087 UNION
0088 SELECT f1 FROM INT4_TBL
0089   WHERE f1 BETWEEN 0 AND 1000000
0090 ORDER BY 1;
0091 
0092 -- [SPARK-28298] Fully support char and varchar types
0093 -- SELECT CAST(f1 AS char(4)) AS three FROM VARCHAR_TBL
0094 -- UNION
0095 -- SELECT f1 FROM CHAR_TBL
0096 -- ORDER BY 1;
0097 
0098 -- SELECT f1 AS three FROM VARCHAR_TBL
0099 -- UNION
0100 -- SELECT CAST(f1 AS varchar) FROM CHAR_TBL
0101 -- ORDER BY 1;
0102 
0103 -- SELECT f1 AS eight FROM VARCHAR_TBL
0104 -- UNION ALL
0105 -- SELECT f1 FROM CHAR_TBL;
0106 
0107 -- SELECT f1 AS five FROM TEXT_TBL
0108 -- UNION
0109 -- SELECT f1 FROM VARCHAR_TBL
0110 -- UNION
0111 -- SELECT TRIM(TRAILING FROM f1) FROM CHAR_TBL
0112 -- ORDER BY 1;
0113 
0114 --
0115 -- INTERSECT and EXCEPT
0116 --
0117 
0118 SELECT q2 FROM int8_tbl INTERSECT SELECT q1 FROM int8_tbl ORDER BY 1;
0119 
0120 SELECT q2 FROM int8_tbl INTERSECT ALL SELECT q1 FROM int8_tbl ORDER BY 1;
0121 
0122 SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1;
0123 
0124 SELECT q2 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl ORDER BY 1;
0125 
0126 SELECT q2 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q1 FROM int8_tbl ORDER BY 1;
0127 
0128 SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY 1;
0129 
0130 SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q2 FROM int8_tbl ORDER BY 1;
0131 
0132 SELECT q1 FROM int8_tbl EXCEPT ALL SELECT DISTINCT q2 FROM int8_tbl ORDER BY 1;
0133 
0134 -- Spark SQL do not support update
0135 -- SELECT q1 FROM int8_tbl EXCEPT ALL SELECT q1 FROM int8_tbl FOR NO KEY UPDATE;
0136 
0137 -- nested cases
0138 (SELECT 1,2,3 UNION SELECT 4,5,6) INTERSECT SELECT 4,5,6;
0139 (SELECT 1,2,3 UNION SELECT 4,5,6 ORDER BY 1,2) INTERSECT SELECT 4,5,6;
0140 (SELECT 1,2,3 UNION SELECT 4,5,6) EXCEPT SELECT 4,5,6;
0141 (SELECT 1,2,3 UNION SELECT 4,5,6 ORDER BY 1,2) EXCEPT SELECT 4,5,6;
0142 
0143 -- exercise both hashed and sorted implementations of INTERSECT/EXCEPT
0144 
0145 -- set enable_hashagg to on;
0146 
0147 -- explain (costs off)
0148 -- select count(*) from
0149 --   ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss;
0150 select count(*) from
0151   ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss;
0152 
0153 -- explain (costs off)
0154 -- select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
0155 select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
0156 
0157 -- set enable_hashagg to off;
0158 
0159 -- explain (costs off)
0160 -- select count(*) from
0161 --   ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss;
0162 select count(*) from
0163   ( select unique1 from tenk1 intersect select fivethous from tenk1 ) ss;
0164 
0165 -- explain (costs off)
0166 -- select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
0167 select unique1 from tenk1 except select unique2 from tenk1 where unique2 != 10;
0168 
0169 -- reset enable_hashagg;
0170 
0171 --
0172 -- Mixed types
0173 --
0174 
0175 SELECT f1 FROM float8_tbl INTERSECT SELECT f1 FROM int4_tbl ORDER BY 1;
0176 
0177 SELECT f1 FROM float8_tbl EXCEPT SELECT f1 FROM int4_tbl ORDER BY 1;
0178 
0179 --
0180 -- Operator precedence and (((((extra))))) parentheses
0181 --
0182 
0183 SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl  ORDER BY 1;
0184 
0185 SELECT q1 FROM int8_tbl INTERSECT (((SELECT q2 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) ORDER BY 1;
0186 
0187 (((SELECT q1 FROM int8_tbl INTERSECT SELECT q2 FROM int8_tbl ORDER BY 1))) UNION ALL SELECT q2 FROM int8_tbl;
0188 
0189 SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1;
0190 
0191 SELECT q1 FROM int8_tbl UNION ALL (((SELECT q2 FROM int8_tbl EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1)));
0192 
0193 (((SELECT q1 FROM int8_tbl UNION ALL SELECT q2 FROM int8_tbl))) EXCEPT SELECT q1 FROM int8_tbl ORDER BY 1;
0194 
0195 --
0196 -- Subqueries with ORDER BY & LIMIT clauses
0197 --
0198 
0199 -- In this syntax, ORDER BY/LIMIT apply to the result of the EXCEPT
0200 SELECT q1,q2 FROM int8_tbl EXCEPT SELECT q2,q1 FROM int8_tbl
0201 ORDER BY q2,q1;
0202 
0203 -- This should fail, because q2 isn't a name of an EXCEPT output column
0204 SELECT q1 FROM int8_tbl EXCEPT SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1;
0205 
0206 -- But this should work:
0207 SELECT q1 FROM int8_tbl EXCEPT (((SELECT q2 FROM int8_tbl ORDER BY q2 LIMIT 1))) ORDER BY 1;
0208 
0209 --
0210 -- New syntaxes (7.1) permit new tests
0211 --
0212 
0213 (((((select * from int8_tbl)))));
0214 
0215 -- [SPARK-28557] Support empty select list
0216 --
0217 -- Check behavior with empty select list (allowed since 9.4)
0218 --
0219 
0220 -- select union select;
0221 -- select intersect select;
0222 -- select except select;
0223 
0224 -- check hashed implementation
0225 -- set enable_hashagg = true;
0226 -- set enable_sort = false;
0227 
0228 -- explain (costs off)
0229 -- select from generate_series(1,5) union select from generate_series(1,3);
0230 -- explain (costs off)
0231 -- select from generate_series(1,5) intersect select from generate_series(1,3);
0232 
0233 -- [SPARK-28409] SELECT FROM syntax
0234 -- [SPARK-27767] Built-in function: generate_series
0235 select * from range(1,5) union select * from range(1,3);
0236 select * from range(1,6) union all select * from range(1,4);
0237 select * from range(1,6) intersect select * from range(1,4);
0238 select * from range(1,6) intersect all select * from range(1,4);
0239 select * from range(1,6) except select * from range(1,4);
0240 select * from range(1,6) except all select * from range(1,4);
0241 
0242 -- check sorted implementation
0243 -- set enable_hashagg = false;
0244 -- set enable_sort = true;
0245 
0246 -- explain (costs off)
0247 -- select from generate_series(1,5) union select from generate_series(1,3);
0248 -- explain (costs off)
0249 -- select from generate_series(1,5) intersect select from generate_series(1,3);
0250 
0251 select * from range(1,6) union select * from range(1,4);
0252 select * from range(1,6) union all select * from range(1,4);
0253 select * from range(1,6) intersect select * from range(1,4);
0254 select * from range(1,6) intersect all select * from range(1,4);
0255 select * from range(1,6) except select * from range(1,4);
0256 select * from range(1,6) except all select * from range(1,4);
0257 
0258 -- reset enable_hashagg;
0259 -- reset enable_sort;
0260 
0261 --
0262 -- Check handling of a case with unknown constants.  We don't guarantee
0263 -- an undecorated constant will work in all cases, but historically this
0264 -- usage has worked, so test we don't break it.
0265 --
0266 
0267 -- SELECT a.f1 FROM (SELECT 'test' AS f1 FROM varchar_tbl) a
0268 -- UNION
0269 -- SELECT b.f1 FROM (SELECT f1 FROM varchar_tbl) b
0270 -- ORDER BY 1;
0271 
0272 -- This should fail, but it should produce an error cursor
0273 SELECT cast('3.4' as decimal(38, 18)) UNION SELECT 'foo';
0274 
0275 -- Skip this test because it only test explain
0276 --
0277 -- Test that expression-index constraints can be pushed down through
0278 -- UNION or UNION ALL
0279 --
0280 
0281 -- CREATE TEMP TABLE t1 (a text, b text);
0282 -- CREATE INDEX t1_ab_idx on t1 ((a || b));
0283 -- CREATE TEMP TABLE t2 (ab text primary key);
0284 -- INSERT INTO t1 VALUES ('a', 'b'), ('x', 'y');
0285 -- INSERT INTO t2 VALUES ('ab'), ('xy');
0286 
0287 -- set enable_seqscan = off;
0288 -- set enable_indexscan = on;
0289 -- set enable_bitmapscan = off;
0290 
0291 -- explain (costs off)
0292 --  SELECT * FROM
0293 --  (SELECT a || b AS ab FROM t1
0294 --   UNION ALL
0295 --   SELECT * FROM t2) t
0296 --  WHERE ab = 'ab';
0297 
0298 -- explain (costs off)
0299 --  SELECT * FROM
0300 --  (SELECT a || b AS ab FROM t1
0301 --   UNION
0302 --   SELECT * FROM t2) t
0303 --  WHERE ab = 'ab';
0304 
0305 -- Skip this test because we do not support inheritance
0306 --
0307 -- Test that ORDER BY for UNION ALL can be pushed down to inheritance
0308 -- children.
0309 --
0310 
0311 -- CREATE TEMP TABLE t1c (b text, a text);
0312 -- ALTER TABLE t1c INHERIT t1;
0313 -- CREATE TEMP TABLE t2c (primary key (ab)) INHERITS (t2);
0314 -- INSERT INTO t1c VALUES ('v', 'w'), ('c', 'd'), ('m', 'n'), ('e', 'f');
0315 -- INSERT INTO t2c VALUES ('vw'), ('cd'), ('mn'), ('ef');
0316 -- CREATE INDEX t1c_ab_idx on t1c ((a || b));
0317 
0318 -- set enable_seqscan = on;
0319 -- set enable_indexonlyscan = off;
0320 
0321 -- explain (costs off)
0322 --   SELECT * FROM
0323 --   (SELECT a || b AS ab FROM t1
0324 --    UNION ALL
0325 --    SELECT ab FROM t2) t
0326 --   ORDER BY 1 LIMIT 8;
0327 
0328 --   SELECT * FROM
0329 --   (SELECT a || b AS ab FROM t1
0330 --    UNION ALL
0331 --    SELECT ab FROM t2) t
0332 --   ORDER BY 1 LIMIT 8;
0333 
0334 -- reset enable_seqscan;
0335 -- reset enable_indexscan;
0336 -- reset enable_bitmapscan;
0337 
0338 -- This simpler variant of the above test has been observed to fail differently
0339 
0340 -- create table events (event_id int primary key);
0341 -- create table other_events (event_id int primary key);
0342 -- create table events_child () inherits (events);
0343 
0344 -- explain (costs off)
0345 -- select event_id
0346 --  from (select event_id from events
0347 --        union all
0348 --        select event_id from other_events) ss
0349 --  order by event_id;
0350 
0351 -- drop table events_child, events, other_events;
0352 
0353 -- reset enable_indexonlyscan;
0354 
0355 -- Test constraint exclusion of UNION ALL subqueries
0356 -- explain (costs off)
0357 --  SELECT * FROM
0358 --   (SELECT 1 AS t, * FROM tenk1 a
0359 --    UNION ALL
0360 --    SELECT 2 AS t, * FROM tenk1 b) c
0361 --  WHERE t = 2;
0362 
0363 -- Test that we push quals into UNION sub-selects only when it's safe
0364 -- explain (costs off)
0365 -- SELECT * FROM
0366 --   (SELECT 1 AS t, 2 AS x
0367 --    UNION
0368 --    SELECT 2 AS t, 4 AS x) ss
0369 -- WHERE x < 4
0370 -- ORDER BY x;
0371 
0372 SELECT * FROM
0373   (SELECT 1 AS t, 2 AS x
0374    UNION
0375    SELECT 2 AS t, 4 AS x) ss
0376 WHERE x < 4
0377 ORDER BY x;
0378 
0379 -- explain (costs off)
0380 -- SELECT * FROM
0381 --   (SELECT 1 AS t, generate_series(1,10) AS x
0382 --    UNION
0383 --    SELECT 2 AS t, 4 AS x) ss
0384 -- WHERE x < 4
0385 -- ORDER BY x;
0386 
0387 ;
0388 
0389 SELECT * FROM
0390   (SELECT 1 AS t, id as x from range(1,11)
0391    UNION
0392    SELECT 2 AS t, 4 AS x) ss
0393 WHERE x < 4
0394 ORDER BY x;
0395 
0396 -- explain (costs off)
0397 -- SELECT * FROM
0398 --   (SELECT 1 AS t, (random()*3)::int AS x
0399 --    UNION
0400 --    SELECT 2 AS t, 4 AS x) ss
0401 -- WHERE x > 3
0402 -- ORDER BY x;
0403 
0404 SELECT * FROM
0405   (SELECT 1 AS t, int((random()*3)) AS x
0406    UNION
0407    SELECT 2 AS t, 4 AS x) ss
0408 WHERE x > 3
0409 ORDER BY x;
0410 
0411 -- Test cases where the native ordering of a sub-select has more pathkeys
0412 -- than the outer query cares about
0413 -- explain (costs off)
0414 -- select distinct q1 from
0415 --   (select distinct * from int8_tbl i81
0416 --    union all
0417 --    select distinct * from int8_tbl i82) ss
0418 -- where q2 = q2;
0419 
0420 select distinct q1 from
0421   (select distinct * from int8_tbl i81
0422    union all
0423    select distinct * from int8_tbl i82) ss
0424 where q2 = q2;
0425 
0426 -- explain (costs off)
0427 -- select distinct q1 from
0428 --   (select distinct * from int8_tbl i81
0429 --    union all
0430 --    select distinct * from int8_tbl i82) ss
0431 -- where -q1 = q2;
0432 
0433 select distinct q1 from
0434   (select distinct * from int8_tbl i81
0435    union all
0436    select distinct * from int8_tbl i82) ss
0437 where -q1 = q2;
0438 
0439 -- Skip this test because it only test explain
0440 -- Test proper handling of parameterized appendrel paths when the
0441 -- potential join qual is expensive
0442 -- create function expensivefunc(int) returns int
0443 -- language plpgsql immutable strict cost 10000
0444 -- as $$begin return $1; end$$;
0445 
0446 -- create temp table t3 as select generate_series(-1000,1000) as x;
0447 -- create index t3i on t3 (expensivefunc(x));
0448 -- analyze t3;
0449 
0450 -- explain (costs off)
0451 -- select * from
0452 --   (select * from t3 a union all select * from t3 b) ss
0453 --   join int4_tbl on f1 = expensivefunc(x);
0454 -- select * from
0455 --   (select * from t3 a union all select * from t3 b) ss
0456 --   join int4_tbl on f1 = expensivefunc(x);
0457 
0458 -- drop table t3;
0459 -- drop function expensivefunc(int);
0460 
0461 -- Test handling of appendrel quals that const-simplify into an AND
0462 -- explain (costs off)
0463 -- select * from
0464 --   (select *, 0 as x from int8_tbl a
0465 --    union all
0466 --    select *, 1 as x from int8_tbl b) ss
0467 -- where (x = 0) or (q1 >= q2 and q1 <= q2);
0468 select * from
0469   (select *, 0 as x from int8_tbl a
0470    union all
0471    select *, 1 as x from int8_tbl b) ss
0472 where (x = 0) or (q1 >= q2 and q1 <= q2);