000001  # 2022-04-12
000002  #
000003  # The author disclaims copyright to this source code.  In place of
000004  # a legal notice, here is a blessing:
000005  #
000006  #    May you do good and not evil.
000007  #    May you find forgiveness for yourself and forgive others.
000008  #    May you share freely, never taking more than you give.
000009  #
000010  #***********************************************************************
000011  #
000012  # This file implements tests for RIGHT and FULL OUTER JOINs.
000013  
000014  set testdir [file dirname $argv0]
000015  source $testdir/tester.tcl
000016  
000017  ifcapable !vtab {
000018    finish_test
000019    return
000020  }
000021  
000022  db null NULL
000023  # EVIDENCE-OF: R-33754-02880 you can say "LEFT RIGHT JOIN" which is the
000024  # same as "FULL JOIN".
000025  do_execsql_test join8-10 {
000026    CREATE TABLE t1(a,b,c);
000027    CREATE TABLE t2(x,y);
000028    CREATE INDEX t2x ON t2(x);
000029    SELECT avg(DISTINCT b) FROM (SELECT * FROM t2 LEFT RIGHT JOIN t1 ON c);
000030  } {NULL}
000031  
000032  # Pending optimization opportunity:
000033  # Row-value initialization subroutines must be called from with the
000034  # RIGHT JOIN body subroutine before the first use of any register containing
000035  # the results of that subroutine.  This seems dodgy.  Test case:
000036  #
000037  reset_db
000038  do_execsql_test join8-1000 {
000039    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT,b,c,d,e,f,g,h,j,k,l,m,n,o,p,q,r,s);
000040    CREATE INDEX t1x1 ON t1(g+h,j,k);
000041    CREATE INDEX t1x2 ON t1(b);
000042    INSERT INTO t1 DEFAULT VALUES;
000043  } {}
000044  do_catchsql_test join8-1010 {
000045    SELECT a
000046      FROM (
000047            SELECT a
000048              FROM (
000049                    SELECT a
000050                      FROM (
000051                            SELECT a FROM t1 NATURAL LEFT JOIN t1
000052                             WHERE (b, 2 ) IS ( SELECT 2 IN(2,2),2)
000053                           )
000054                      NATURAL LEFT FULL JOIN t1
000055                     WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0)
000056                     ORDER BY a ASC
000057                   )
000058              NATURAL LEFT JOIN t1
000059             WHERE (b, 2 ) IS ( SELECT 3 IN(3,3),3)
000060           )
000061      NATURAL LEFT FULL JOIN t1
000062     WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0)
000063     ORDER BY a ASC;
000064  } {0 1}
000065  
000066  # Pending issue #2: (now resolved)
000067  # Jump to addrHalt inside the RIGHT JOIN body subroutine bypasses the
000068  # OP_Return, resulting in a subroutine loop.  Test case:
000069  #
000070  reset_db
000071  do_execsql_test join8-2000 {
000072    CREATE TABLE t1(a int, b int, c int);
000073    INSERT INTO t1 VALUES(1,2,3),(4,5,6);
000074    CREATE TABLE t2(d int, e int);
000075    INSERT INTO t2 VALUES(3,333),(4,444);
000076    CREATE TABLE t3(f int, g int);
000077    PRAGMA automatic_index=off;
000078  } {}
000079  do_catchsql_test join8-2010 {
000080    SELECT * FROM t1 RIGHT JOIN t2 ON c=d JOIN t3 ON f=e;
000081  } {0 {}}
000082  
000083  # Demonstrate that nested FULL JOINs and USING clauses work
000084  #
000085  reset_db
000086  load_static_extension db series
000087  do_execsql_test join8-3000 {
000088    CREATE TABLE t1(id INTEGER PRIMARY KEY, a INT);
000089    CREATE TABLE t2(id INTEGER PRIMARY KEY, b INT);
000090    CREATE TABLE t3(id INTEGER PRIMARY KEY, c INT);
000091    CREATE TABLE t4(id INTEGER PRIMARY KEY, d INT);
000092    CREATE TABLE t5(id INTEGER PRIMARY KEY, e INT);
000093    CREATE TABLE t6(id INTEGER PRIMARY KEY, f INT);
000094    CREATE TABLE t7(id INTEGER PRIMARY KEY, g INT);
000095    CREATE TABLE t8(id INTEGER PRIMARY KEY, h INT);
000096    INSERT INTO t1 SELECT value, 1 FROM generate_series(1,256) WHERE value & 1;
000097    INSERT INTO t2 SELECT value, 1 FROM generate_series(1,256) WHERE value & 2;
000098    INSERT INTO t3 SELECT value, 1 FROM generate_series(1,256) WHERE value & 4;
000099    INSERT INTO t4 SELECT value, 1 FROM generate_series(1,256) WHERE value & 8;
000100    INSERT INTO t5 SELECT value, 1 FROM generate_series(1,256) WHERE value & 16;
000101    INSERT INTO t6 SELECT value, 1 FROM generate_series(1,256) WHERE value & 32;
000102    INSERT INTO t7 SELECT value, 1 FROM generate_series(1,256) WHERE value & 64;
000103    INSERT INTO t8 SELECT value, 1 FROM generate_series(1,256) WHERE value & 128;
000104    CREATE TABLE t9 AS
000105      SELECT id, h, g, f, e, d, c, b, a
000106        FROM t1
000107        NATURAL FULL JOIN t2
000108        NATURAL FULL JOIN t3
000109        NATURAL FULL JOIN t4
000110        NATURAL FULL JOIN t5
000111        NATURAL FULL JOIN t6
000112        NATURAL FULL JOIN t7
000113        NATURAL FULL JOIN t8;
000114  } {}
000115  do_execsql_test join8-3010 {
000116    SELECT count(*) FROM t9;
000117  } {255}
000118  do_execsql_test join8-3020 {
000119    SELECT id, count(*) FROM t9 GROUP BY id HAVING count(*)!=1;
000120  } {}
000121  do_execsql_test join8-3030 {
000122    UPDATE t9 SET a=0 WHERE a IS NULL;
000123    UPDATE t9 SET b=0 WHERE b IS NULL;
000124    UPDATE t9 SET c=0 WHERE c IS NULL;
000125    UPDATE t9 SET d=0 WHERE d IS NULL;
000126    UPDATE t9 SET e=0 WHERE e IS NULL;
000127    UPDATE t9 SET f=0 WHERE f IS NULL;
000128    UPDATE t9 SET g=0 WHERE g IS NULL;
000129    UPDATE t9 SET h=0 WHERE h IS NULL;
000130    SELECT count(*) FROM t9 WHERE id=128*h+64*g+32*f+16*e+8*d+4*c+2*b+a;
000131  } {255}
000132  do_execsql_test join8-3040 {
000133    SELECT * FROM t9 WHERE id<>128*h+64*g+32*f+16*e+8*d+4*c+2*b+a;
000134  } {}
000135  
000136  # 2022-04-21 dbsqlfuzz find
000137  #
000138  reset_db
000139  do_execsql_test join8-4000 {
000140    CREATE TABLE t1(x INTEGER PRIMARY KEY, a, b);
000141    INSERT INTO t1 VALUES(1,5555,4);
000142    CREATE INDEX i1a ON t1(a);
000143    CREATE INDEX i1b ON t1(b);
000144    SELECT a FROM t1 NATURAL RIGHT JOIN t1 WHERE a=5555 OR (1,b)==(SELECT 2 IN (2,2),4);
000145  } {5555}
000146  
000147  # 2022-04-23 dbsqlfuzz c7ee5500e3abddec3557016de777713b80c790d3
000148  # Escape from the right-join body subroutine via the ORDER BY LIMIT optimization.
000149  #
000150  reset_db
000151  db null -
000152  do_catchsql_test join8-5000 {
000153    CREATE TABLE t1(x);
000154    INSERT INTO t1(x) VALUES(NULL),(NULL);
000155    CREATE TABLE t2(c, d);
000156    INSERT INTO t2(c,d) SELECT x, x FROM t1;
000157    CREATE INDEX t2dc ON t2(d, c);
000158    SELECT (SELECT c FROM sqlite_temp_schema FULL JOIN t2 ON d IN (1,2,3) ORDER BY d) AS x FROM t1;
000159  } {0 {- -}}
000160  
000161  # 2022-04-29 dbsqlfuzz 19f1102a70cf966ab249de56d944fc20dbebcfcf
000162  # Verification of testtag-20230227b and testtag-20230227c
000163  #
000164  reset_db
000165  do_execsql_test join8-6000 {
000166    CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d REAL);
000167    INSERT INTO t1 VALUES(1,'A','aa',2.5);
000168    SELECT * FROM t1 AS t2 NATURAL RIGHT JOIN t1 AS t3
000169     WHERE (a,b) IN (SELECT rowid, b FROM t1);
000170  } {1 A aa 2.5}
000171  do_execsql_test join8-6010 {
000172    DROP TABLE IF EXISTS t1;
000173    CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, c TEXT, d INT) WITHOUT ROWID;
000174    INSERT INTO t1 VALUES(15,'xray','baker',42);
000175    SELECT value, t1.* FROM json_each('7') NATURAL RIGHT JOIN t1
000176     WHERE (a,b) IN (SELECT a, b FROM t1);
000177  } {7 15 xray baker 42}
000178  do_execsql_test join8-6020 {
000179    DROP TABLE IF EXISTS t1;
000180    CREATE TABLE t1(a INTEGER PRIMARY KEY,b);
000181    INSERT INTO t1 VALUES(0,NULL),(1,2);
000182    SELECT value, t1.* FROM json_each('17') NATURAL RIGHT JOIN t1
000183     WHERE (a,b) IN (SELECT rowid, b FROM t1);
000184  } {17 1 2}
000185  do_execsql_test join8-6021 {
000186    SELECT value, t1.* FROM json_each('null') NATURAL RIGHT JOIN t1
000187     WHERE (a,b) IN (SELECT rowid, b FROM t1);
000188  } {{} 1 2}
000189  do_execsql_test join8-6022 {
000190    CREATE TABLE a(key TEXT);
000191    INSERT INTO a(key) VALUES('a'),('b');
000192    SELECT quote(a.key), b.value
000193      FROM a RIGHT JOIN json_each('["a","c"]') AS b ON a.key=b.value;
000194  } {'a' a NULL c}
000195  
000196  # Bloom filter usage by RIGHT and FULL JOIN
000197  #
000198  reset_db
000199  do_execsql_test join8-7000 {
000200  CREATE TABLE t1(a INT, b INT, c INT, d INT);
000201    WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<10)
000202      INSERT INTO t1(a,b,c,d) SELECT x, x+100, x+200, x+300 FROM c;
000203    CREATE TABLE t2(b INT, x INT);
000204    INSERT INTO t2(b,x) SELECT b, a FROM t1 WHERE a%2=0;
000205    CREATE INDEX t2b ON t2(b);
000206    CREATE TABLE t3(c INT, y INT);
000207    INSERT INTO t3(c,y) SELECT c, a FROM t1 WHERE a%3=0;
000208    CREATE INDEX t3c ON t3(c);
000209    CREATE TABLE t4(d INT, z INT);
000210    INSERT INTO t4(d,z) SELECT d, a FROM t1 WHERE a%5=0;
000211    CREATE INDEX t4d ON t4(d);
000212    INSERT INTO t1(a,b,c,d) VALUES
000213      (96,NULL,296,396),
000214      (97,197,NULL,397),
000215      (98,198,298,NULL),
000216      (99,NULL,NULL,NULL);
000217    ANALYZE sqlite_schema;
000218    INSERT INTO sqlite_stat1 VALUES('t4','t4d','20 1');
000219    INSERT INTO sqlite_stat1 VALUES('t3','t3c','32 1');
000220    INSERT INTO sqlite_stat1 VALUES('t2','t2b','48 1');
000221    INSERT INTO sqlite_stat1 VALUES('t1',NULL,'100');
000222    ANALYZE sqlite_schema;
000223  } {}
000224  db null -
000225  do_execsql_test join8-7010 {
000226    WITH t0 AS MATERIALIZED (
000227      SELECT t1.*, t2.*, t3.*
000228        FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0
000229          RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0
000230    )
000231    SELECT * FROM t0 FULL JOIN t4 ON t0.a=t4.d AND t4.z>0
000232     ORDER BY coalesce(t0.a, t0.y+200, t4.d);
000233  } {
000234    6  106  206  306  106  6  206  6    -   -
000235    -    -    -    -    -  -  200  0    -   -
000236    -    -    -    -    -  -  203  3    -   -
000237    -    -    -    -    -  -  209  9    -   -
000238    -    -    -    -    -  -    -  -  300   0
000239    -    -    -    -    -  -    -  -  305   5
000240    -    -    -    -    -  -    -  -  310  10
000241  }
000242  
000243  # EVIDENCE-OF: R-33754-02880 you can say "LEFT RIGHT JOIN" which is the
000244  # same as "FULL JOIN".
000245  do_execsql_test join8-7011 {
000246    WITH t0 AS MATERIALIZED (
000247      SELECT t1.*, t2.*, t3.*
000248        FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0
000249          RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0
000250    )
000251    SELECT * FROM t0 LEFT RIGHT JOIN t4 ON t0.a=t4.d AND t4.z>0
000252     ORDER BY coalesce(t0.a, t0.y+200, t4.d);
000253  } {
000254    6  106  206  306  106  6  206  6    -   -
000255    -    -    -    -    -  -  200  0    -   -
000256    -    -    -    -    -  -  203  3    -   -
000257    -    -    -    -    -  -  209  9    -   -
000258    -    -    -    -    -  -    -  -  300   0
000259    -    -    -    -    -  -    -  -  305   5
000260    -    -    -    -    -  -    -  -  310  10
000261  }
000262  
000263  do_execsql_test join8-7020 {
000264    EXPLAIN QUERY PLAN
000265    WITH t0 AS MATERIALIZED (
000266      SELECT t1.*, t2.*, t3.*
000267        FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0
000268          RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0
000269    )
000270    SELECT * FROM t0 FULL JOIN t4 ON t0.a=t4.d AND t4.z>0
000271     ORDER BY coalesce(t0.a, t0.y+200, t4.d);
000272  } {/.*BLOOM FILTER ON t2.*BLOOM FILTER ON t3.*/}
000273  
000274  # 2022-05-12 Difference with PG found (by Dan) while exploring
000275  # https://sqlite.org/forum/forumpost/677a0ab93fcd9ccd
000276  #
000277  reset_db
000278  do_execsql_test join8-8000 {
000279    CREATE TABLE t1(a INT, b INT);
000280    CREATE TABLE t2(c INT, d INT);
000281    CREATE TABLE t3(e INT, f INT);
000282    INSERT INTO t1 VALUES(1, 2);
000283    INSERT INTO t2 VALUES(3, 4);
000284    INSERT INTO t3 VALUES(5, 6);
000285  } {}
000286  do_execsql_test join8-8010 {
000287    SELECT *
000288      FROM t3 LEFT JOIN t2 ON true
000289              JOIN t1 ON (t3.e IS t2.c);
000290  } {}
000291  do_execsql_test join8-8020 {
000292    SELECT *
000293      FROM t3 LEFT JOIN t2 ON true
000294              JOIN t1 ON (t3.e IS NOT DISTINCT FROM t2.c);
000295  } {}
000296  
000297  # 2022-05-13 The idea of reusing subquery cursors does not
000298  # work, if the cursors are used both for scanning and lookups.
000299  #
000300  reset_db
000301  db null -
000302  do_execsql_test join8-9000 {
000303    CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d REAL);
000304    INSERT INTO t1 VALUES(1,'E','bb',NULL),(2,NULL,NULL,NULL);
000305    SELECT * FROM t1 NATURAL RIGHT JOIN t1 AS t2 WHERE (a,b) IN (SELECT a+0, b FROM t1);
000306  } {1 E bb -}
000307  
000308  # 2022-05-14 https://sqlite.org/forum/forumpost/c06b10ad7e
000309  #
000310  reset_db
000311  db null -
000312  do_execsql_test join8-10000 {
000313    CREATE TABLE t1(c0 INT UNIQUE);
000314    CREATE TABLE t2(c0);
000315    CREATE TABLE t2i(c0 INT);
000316    CREATE TABLE t3(c0 INT);
000317    INSERT INTO t1 VALUES(1);
000318    INSERT INTO t2 VALUES(2);
000319    INSERT INTO t2i VALUES(2);
000320    INSERT INTO t3 VALUES(3);
000321  } {}
000322  do_execsql_test join8-10010 {
000323    SELECT DISTINCT t1.c0, t3.c0
000324      FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
000325  } {- 3}
000326  do_execsql_test join8-10020 {
000327    SELECT t1.c0, t3.c0
000328      FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
000329  } {- 3}
000330  do_execsql_test join8-10030 {
000331    SELECT DISTINCT t1.c0, t3.c0
000332      FROM t2 NATURAL CROSS JOIN t1 RIGHT JOIN t3 ON t1.c0;
000333  } {- 3}
000334  do_execsql_test join8-10040 {
000335    SELECT t1.c0, t3.c0
000336      FROM t1 NATURAL CROSS JOIN t2 RIGHT JOIN t3 ON t1.c0;
000337  } {- 3}
000338  do_execsql_test join8-10050 {
000339    SELECT DISTINCT t1.c0, t3.c0
000340      FROM t2i NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
000341  } {- 3}
000342  do_execsql_test join8-10060 {
000343    SELECT DISTINCT +t1.c0, t3.c0
000344      FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0;
000345  } {- 3}
000346  do_execsql_test join8-10070 {
000347    SELECT DISTINCT +t1.c0, t3.c0
000348      FROM t1 NATURAL CROSS JOIN t2 RIGHT JOIN t3 ON t1.c0;
000349  } {- 3}
000350  do_execsql_test join8-10080 {
000351    SELECT DISTINCT t1.c0, t3.c0
000352      FROM t2 NATURAL JOIN t1 RIGHT JOIN t3 ON t1.c0<>0;
000353  } {- 3}
000354  
000355  # 2022-05-14
000356  # index-on-expr scan on a RIGHT JOIN
000357  # dbsqlfuzz 39ee60004ff027a9e2846cf76e02cd5ac0953739
000358  #
000359  reset_db
000360  db null -
000361  do_execsql_test join8-11000 {
000362    CREATE TABLE t1(a);
000363    CREATE TABLE t2(b);
000364    INSERT INTO t2 VALUES(0),(1),(2);
000365    SELECT * FROM t1 RIGHT JOIN t2 ON (a=b) WHERE 99+(b+1)!=99;
000366  } {- 0 - 1 - 2}
000367  do_execsql_test join8-11010 {
000368    CREATE INDEX t2b ON t2(b+1) WHERE b IS NOT NULL;
000369    SELECT * FROM t1 RIGHT JOIN t2 ON (a=b) WHERE 99+(b+1)!=99;
000370  } {- 0 - 1 - 2}
000371  do_execsql_test join8-11020 {
000372    DROP TABLE t1;
000373    DROP TABLE t2;
000374    CREATE TABLE t1(a);
000375    CREATE TABLE t2(b, c, d);
000376    INSERT INTO t2 VALUES(1, 3, 'not-4');
000377    SELECT b, d FROM t1 RIGHT JOIN t2 WHERE (b+0)=1 AND d!=4;
000378  } {1 not-4}
000379  do_execsql_test join8-11030 {
000380    CREATE INDEX i2 ON t2((b+0), d);
000381    SELECT b, d FROM t1 RIGHT JOIN t2 WHERE (b+0)=1 AND d!=4;
000382  } {1 not-4}
000383  do_execsql_test join8-11040 {
000384    DROP INDEX i2;
000385    CREATE INDEX i2 ON t2((b+0), d) WHERE d IS NOT NULL;
000386    SELECT b, d FROM t1 RIGHT JOIN t2 WHERE (b+0)=1 AND d!=4;
000387  } {1 not-4}
000388  
000389  # 2022-05-23
000390  # NATURAL JOIN name resolution is more forgiving with LEFT JOIN
000391  # https://sqlite.org/forum/forumpost/e90a8e6e6f
000392  #
000393  reset_db
000394  db null -
000395  do_execsql_test join8-12000 {
000396    CREATE TABLE t1(a INT);  INSERT INTO t1 VALUES(0),(1);
000397    CREATE TABLE t2(a INT);  INSERT INTO t2 VALUES(0),(2);
000398    CREATE TABLE t3(a INT);  INSERT INTO t3 VALUES(0),(3);
000399  } {}
000400  do_catchsql_test join8-12010 {
000401    SELECT * FROM t1 RIGHT JOIN t2 ON t2.a<>0 NATURAL RIGHT JOIN t3;
000402  } {1 {ambiguous reference to a in USING()}}
000403  do_catchsql_test join8-12020 {
000404    SELECT * FROM t1 RIGHT JOIN t2 ON t2.a<>0 NATURAL LEFT JOIN t3;
000405  } {1 {ambiguous reference to a in USING()}}
000406  do_catchsql_test join8-12030 {
000407    SELECT * FROM t1 LEFT JOIN t2 ON t2.a<>0 NATURAL RIGHT JOIN t3;
000408  } {1 {ambiguous reference to a in USING()}}
000409  
000410  # The following query should probably also return the same error as the
000411  # previous three cases.  However, historical versions of SQLite have always
000412  # let it pass.  We will not "fix" this, since to do so might break legacy
000413  # applications.
000414  #
000415  do_catchsql_test join8-12040 {
000416    SELECT * FROM t1 LEFT JOIN t2 ON t2.a<>0 NATURAL LEFT JOIN t3;
000417  } {0 {0 2 1 2}}
000418  
000419  # 2022-05-24
000420  # https://sqlite.org/forum/forumpost/687b0bf563a1d4f1
000421  #
000422  reset_db
000423  do_execsql_test join8-13000 {
000424    CREATE TABLE t0(t TEXT, u TEXT);  INSERT INTO t0 VALUES('t', 'u');
000425    CREATE TABLE t1(v TEXT, w TEXT);  INSERT INTO t1 VALUES('v', 'w');
000426    CREATE TABLE t2(x TEXT, y TEXT);  INSERT INTO t2 VALUES('x', 'y');
000427    SELECT * FROM t0 JOIN t1 ON (t2.x NOTNULL) LEFT JOIN t2 ON false;
000428    SELECT * FROM t0 JOIN t1 ON (t2.x NOTNULL) LEFT JOIN t2 ON false
000429     WHERE t2.y ISNULL;
000430  } {}
000431  
000432  # 2022-05-25
000433  # https://sqlite.org/forum/forumpost/5cfe08eed6
000434  #
000435  reset_db
000436  do_execsql_test join8-14000 {
000437    CREATE TABLE t0(a TEXT, b TEXT, c TEXT);
000438    CREATE TABLE t1(a TEXT);
000439    INSERT INTO t1 VALUES('1');
000440    CREATE VIEW v0 AS SELECT 'xyz' AS d;
000441    SELECT * FROM v0 RIGHT JOIN t1 ON t1.a<>'' INNER JOIN t0 ON t0.c<>'';
000442    SELECT * FROM v0 RIGHT JOIN t1 ON t1.a<>'' INNER JOIN t0 ON t0.c<>'' WHERE b ISNULL;
000443  } {}
000444  do_execsql_test join8-14010 {
000445    CREATE TABLE y0(a INT);
000446    CREATE TABLE y1(b INT); INSERT INTO y1 VALUES(1), (2);
000447    CREATE TABLE y2(c INT); INSERT INTO y2 VALUES(3), (4);
000448  } {}
000449  db null -
000450  do_execsql_test join8-14020 {
000451    SELECT * FROM y0 RIGHT JOIN y1 ON true INNER JOIN y2 ON true WHERE y2.c!=99 AND y2.c!=98;
000452  } {
000453    - 1 3
000454    - 1 4
000455    - 2 3
000456    - 2 4
000457  }
000458  
000459  # 2022-05-30
000460  # https://sqlite.org/forum/forumpost/3902c7b833
000461  #
000462  reset_db
000463  do_execsql_test join8-15000 {
000464    CREATE TABLE t1(x INT);
000465    CREATE TABLE t2(y INT);
000466    CREATE TABLE t3(z INT);
000467    INSERT INTO t1 VALUES(10);
000468    INSERT INTO t3 VALUES(20),(30);
000469  }
000470  do_execsql_test join8-15010 {
000471    SELECT * FROM t1 LEFT JOIN t2 ON true JOIN t3 ON t2.y IS NOT NULL;
000472  } {}
000473  do_execsql_test join8-15020 {
000474    SELECT * FROM t1 LEFT JOIN t2 ON true JOIN t3 ON t2.y IS NOT NULL
000475     WHERE (t3.z!=400 AND t3.z!=500 AND t3.z!=600);
000476  } {}
000477  do_execsql_test join8-15100 {
000478    PRAGMA automatic_index = 0;
000479    CREATE TABLE t4(x TEXT);
000480    CREATE TABLE t5(y TEXT);
000481    CREATE TABLE t6(z TEXT);
000482    INSERT INTO t4 VALUES('a'), ('b');
000483    INSERT INTO t5 VALUES('b'), ('c');
000484    INSERT INTO t6 VALUES('a'), ('d');
000485  } {}
000486  db null -
000487  do_execsql_test join8-15110 {
000488    SELECT * FROM t4 LEFT JOIN t5 ON x=y LEFT JOIN t6 ON (x=z) ORDER BY +x;
000489  } {a - a b b -}
000490  do_execsql_test join8-15120 {
000491    SELECT * FROM t4 LEFT JOIN t5 ON x=y LEFT JOIN t6 ON (x=z)
000492     WHERE t5.y!='x' AND t4.x!='x';
000493  } {b b -}
000494  
000495  # 2022-05-31
000496  # https://sqlite.org/forum/forumpost/c2554d560b
000497  reset_db
000498  do_execsql_test join8-16000 {
000499    CREATE TABLE t1(a TEXT);
000500    CREATE TABLE t2(b TEXT);
000501    CREATE TABLE t3(c TEXT);
000502    INSERT INTO t2(b) VALUES ('x');
000503    INSERT INTO t3(c) VALUES ('y'), ('z');
000504  } {}
000505  db null -
000506  do_execsql_test join8-16010 {
000507    SELECT * FROM t1 RIGHT JOIN t2 ON true LEFT JOIN t3 ON a<>'';
000508  } {- x -}
000509  do_execsql_test join8-16020 {
000510    SELECT * FROM t1 RIGHT JOIN t2 ON true LEFT JOIN t3 ON a<>'' WHERE c IS NULL;
000511  } {- x -}
000512  do_execsql_test join8-16020 {
000513    SELECT * FROM t1 RIGHT JOIN t2 ON true JOIN t3 ON a<>'' WHERE c IS NULL;
000514  } {}
000515  do_execsql_test join8-16030 {
000516    SELECT * FROM t1 RIGHT JOIN t2 ON true JOIN t3 ON a<>'';
000517  } {}
000518  do_execsql_test join8-16040 {
000519    SELECT * FROM t1 RIGHT JOIN t2 ON true LEFT JOIN t3 ON a<>'' WHERE c<>'';
000520  } {}
000521  do_execsql_test join8-16050 {
000522    SELECT * FROM t1 RIGHT JOIN t2 ON true LEFT JOIN t3 ON a<>'' WHERE c IS NOT NULL;
000523  } {}
000524  do_execsql_test join8-16060 {
000525    SELECT * FROM t1 RIGHT JOIN t2 ON true JOIN t3 ON a<>'' WHERE c<>'';
000526  } {}
000527  do_execsql_test join8-16070 {
000528    SELECT * FROM t1 RIGHT JOIN t2 ON true JOIN t3 ON a<>'' WHERE c IS NOT NULL;
000529  } {}
000530  
000531  # 2022-06-01
000532  # https://sqlite.org/forum/forumpost/087de2d9ec
000533  #
000534  reset_db
000535  do_execsql_test join8-17000 {
000536    CREATE TABLE t1(id INTEGER PRIMARY KEY, x INT, y INT);
000537    CREATE TABLE t2(z INT);
000538    INSERT INTO t1(id,x,y) VALUES(1, 0, 0);
000539  } {}
000540  db null NULL
000541  do_execsql_test join8-17010 {
000542    SELECT * FROM t2 RIGHT JOIN t1 ON true;
000543  } {NULL 1 0 0}
000544  do_execsql_test join8-17020 {
000545    SELECT 99=id AND 0=y AS "truth" FROM t2 RIGHT JOIN t1 ON true;
000546  } {0}
000547  do_execsql_test join8-17030 {
000548    SELECT (99, 0)==(id, y) AS "truth" FROM t2 RIGHT JOIN t1;
000549  } {0}
000550  do_execsql_test join8-17040 {
000551    SELECT * FROM t2 RIGHT JOIN t1 WHERE 99=id AND 0=y;
000552  } {}
000553  do_execsql_test join8-17041 {
000554    SELECT * FROM t2 RIGHT JOIN t1 WHERE 99=+id AND 0=y;
000555  } {}
000556  do_execsql_test join8-17050 {
000557    SELECT * FROM t2 RIGHT JOIN t1 WHERE (99, 0)==(id,y);
000558  } {}
000559  do_execsql_test join8-17051 {
000560    SELECT * FROM t2 RIGHT JOIN t1 WHERE (99, 0)==(+id,y);
000561  } {}
000562  do_execsql_test join8-17060 {
000563    SELECT * FROM t2 RIGHT JOIN t1 WHERE 1=id AND 0=y;
000564  } {NULL 1 0 0}
000565  do_execsql_test join8-17061 {
000566    SELECT * FROM t2 RIGHT JOIN t1 WHERE 1=+id AND 0=y;
000567  } {NULL 1 0 0}
000568  do_execsql_test join8-17070 {
000569    SELECT * FROM t2 RIGHT JOIN t1 WHERE (1, 0)==(id,y);
000570  } {NULL 1 0 0}
000571  do_execsql_test join8-17071 {
000572    SELECT * FROM t2 RIGHT JOIN t1 WHERE (1, 0)==(+id,y);
000573  } {NULL 1 0 0}
000574  do_execsql_test join8-17080 {
000575    CREATE TABLE t3(a INTEGER PRIMARY KEY, b INT);
000576    CREATE TABLE t4(x INT, y INT);
000577    INSERT INTO t3(a,b) VALUES(1, 3);
000578  } {}
000579  do_execsql_test join8-17090 {
000580    SELECT t3.a FROM t4 RIGHT JOIN t3 ON (x=a) WHERE (b, 4)=(SELECT 3, 4);
000581  } {1}
000582  do_execsql_test join8-17091 {
000583    SELECT t3.a FROM t4 RIGHT JOIN t3 ON (x=a) WHERE (b, 4) IS (SELECT 3, 4);
000584  } {1}
000585  
000586  # 2022-06-06
000587  # https://sqlite.org/forum/forumpost/206d99a16dd9212f
000588  # tag-20191211-001
000589  #
000590  reset_db
000591  do_execsql_test join8-18000 {
000592    CREATE TABLE t1(a BOOLEAN); INSERT INTO t1 VALUES (false);
000593    CREATE TABLE t2(x INT);     INSERT INTO t2 VALUES (0);
000594    SELECT *, x NOTNULL, (x NOTNULL)=a FROM t2 RIGHT JOIN t1 ON true WHERE (x NOTNULL)=a;
000595  } {}
000596  do_execsql_test join8-18010 {
000597    CREATE INDEX t1a ON t1(a);
000598    SELECT *, x NOTNULL, (x NOTNULL)=a FROM t2 RIGHT JOIN t1 ON true WHERE (x NOTNULL)=a;
000599  } {}
000600  
000601  do_execsql_test join8-18020 {
000602    CREATE TABLE t3(z);
000603    INSERT INTO t3 VALUES('t3value');
000604    SELECT *, x NOTNULL, (x NOTNULL)=a FROM t2 RIGHT JOIN t1 ON true INNER JOIN t3 ON (x NOTNULL)=a;
000605  } {}
000606  
000607  ifcapable rtree {
000608    do_execsql_test join8-18030 {
000609      CREATE VIRTUAL TABLE rtree1 USING rtree(a, x1, x2);
000610      INSERT INTO rtree1 VALUES(0, 0, 0);
000611    }
000612    do_execsql_test join8-18040 {
000613      SELECT *, x NOTNULL, (x NOTNULL)=a FROM t2 
000614        RIGHT JOIN rtree1 ON true INNER JOIN t3 ON (x NOTNULL)=+a;
000615    } {}
000616    do_execsql_test join8-18050 {
000617      SELECT *, x NOTNULL, (x NOTNULL)=a FROM t2 
000618        RIGHT JOIN rtree1 ON true INNER JOIN t3 ON (x NOTNULL)=a;
000619    } {}
000620  }
000621  
000622  
000623  reset_db
000624  do_execsql_test join8-19000 {
000625    CREATE TABLE t1(a INT);
000626    CREATE TABLE t2(b INT, c INT);
000627    CREATE TABLE t3(d INT);
000628  
000629    INSERT INTO t1 VALUES(10);
000630    INSERT INTO t2 VALUES(50,51);
000631    INSERT INTO t3 VALUES(299);
000632  
000633    CREATE INDEX t2b ON t2( (b IS NOT NULL) );
000634  }
000635  
000636  do_execsql_test join8-19010 {
000637    SELECT * FROM t1 LEFT JOIN t2 ON true INNER JOIN t3 ON (b IS NOT NULL)=0;
000638  }
000639  
000640  # 2022-06-07
000641  # https://sqlite.org/forum/forumpost/323f86cc30
000642  reset_db
000643  do_execsql_test join8-20000 {
000644    CREATE TABLE t1(x TEXT);
000645    INSERT INTO t1(x) VALUES('aaa');
000646    CREATE VIEW v0(y) AS SELECT x FROM t1;
000647    CREATE TABLE t2(z TEXT);
000648  } {}
000649  db null -
000650  do_execsql_test join8-20010 {
000651    SELECT * FROM t2 JOIN v0 ON z<>'bbb' RIGHT JOIN t1 ON z<>'ccc';
000652  } {- - aaa}
000653  do_execsql_test join8-20020 {
000654    SELECT * FROM t2 JOIN v0 ON z<>'bbb' RIGHT JOIN t1 ON z<>'ccc' ORDER BY z;
000655  } {- - aaa}
000656  do_execsql_test join8-20030 {
000657    SELECT 99 as "m" FROM t2 JOIN v0 ON z<>'bbb' RIGHT JOIN t1 ON z<>'ccc';
000658  } {99}
000659  do_execsql_test join8-20040 {
000660    SELECT 99 as "m" FROM t2 JOIN v0 ON z<>'bbb' RIGHT JOIN t1 ON z<>'ccc' ORDER BY z;
000661  } {99}
000662  do_execsql_test join8-20050 {
000663    SELECT count(*)
000664      FROM (SELECT 99 as "m" FROM t2 JOIN v0 ON z<>'' RIGHT JOIN t1 ON z<>'') AS "t3";
000665  } {1}
000666  do_execsql_test join8-20060 {
000667    SELECT count(*) 
000668      FROM (SELECT 99 as "m" FROM t2 JOIN v0 ON z<>'' RIGHT JOIN t1 ON z<>'' ORDER BY z) AS "t3";
000669  } {1}
000670  
000671  # 2022-06-10
000672  # https://sqlite.org/forum/forumpost/8e4c352937e82929
000673  #
000674  # Do not allow constant propagation between ON and WHERE clause terms.
000675  # (Updated 2022-06-20) See also https://sqlite.org/forum/forumpost/57bdf2217d
000676  #
000677  reset_db
000678  do_execsql_test join8-21000 {
000679    CREATE TABLE t1(a INT,b BOOLEAN);
000680    CREATE TABLE t2(c INT);  INSERT INTO t2 VALUES(NULL);
000681    CREATE TABLE t3(d INT);
000682  }
000683  do_execsql_test join8-21010 {
000684    SELECT (b IS TRUE) FROM t1 JOIN t3 ON (b=TRUE) RIGHT JOIN t2 ON TRUE;
000685  } {0}
000686  do_execsql_test join8-22020 {
000687    SELECT * FROM t1 JOIN t3 ON (b=TRUE) RIGHT JOIN t2 ON TRUE WHERE (b IS TRUE);
000688  } {}
000689  do_execsql_test join8-22030 {
000690    DROP TABLE t1;
000691    DROP TABLE t2;
000692    DROP TABLE t3;
000693    CREATE TABLE t1(a INT);
000694    CREATE TABLE t2(b INT);
000695    CREATE TABLE t3(c INTEGER PRIMARY KEY, d INT);
000696    CREATE INDEX t3d ON t3(d);
000697    INSERT INTO t3 VALUES(0, 0);
000698  }
000699  do_catchsql_test join8-22031 {
000700    SELECT * FROM t1 JOIN t2 ON d>b RIGHT JOIN t3 ON true WHERE +d = 0;
000701  } {1 {ON clause references tables to its right}}
000702  do_catchsql_test join8-22040 {
000703    SELECT * FROM t1 JOIN t2 ON d>b RIGHT JOIN t3 ON true WHERE d = 0;
000704  } {1 {ON clause references tables to its right}}
000705  
000706  
000707  # 2022-06-10
000708  # https://sqlite.org/forum/forumpost/51e6959f61
000709  #
000710  # Restrictions on the usage of WHERE clause constraints by joins that are
000711  # involved with a RIGHT JOIN must also be applied to automatic indexes.
000712  #
000713  reset_db
000714  do_execsql_test join8-22000 {
000715    CREATE TABLE t1(a INT);
000716    CREATE TABLE t2(b INT);
000717    CREATE TABLE t3(c TEXT);  INSERT INTO t3 VALUES('x');
000718    CREATE TABLE t4(d TEXT);  INSERT INTO t4 VALUES('y');
000719    SELECT 99
000720      FROM t1
000721           LEFT JOIN t2 ON true
000722           RIGHT JOIN t3 ON true
000723           RIGHT JOIN t4 ON true
000724     WHERE a=b;
000725  } {}
000726  
000727  # 2022-06-13
000728  # https://sqlite.org/forum/forumpost/b40696f501
000729  #
000730  # This optimization that converts "x ISNULL" into "FALSE" when column "x" has a
000731  # NOT NULL constraint is too aggresive if the query contains RIGHT JOIN.
000732  #
000733  reset_db
000734  db null -
000735  do_execsql_test join8-23000 {
000736    CREATE TABLE t1(a TEXT);
000737    INSERT INTO t1 VALUES('c');
000738    CREATE TABLE t2(b TEXT, c TEXT NOT NULL);
000739    INSERT INTO t2 VALUES('a', 'b');
000740    CREATE TABLE t3(d TEXT);
000741    INSERT INTO t3 VALUES('x');
000742    CREATE TABLE t4(e TEXT);
000743    INSERT INTO t4 VALUES('y');
000744  }
000745  do_execsql_test join8-23010 {
000746    SELECT *
000747      FROM t1
000748           LEFT JOIN t2 ON TRUE
000749           JOIN t3 ON c=''
000750           RIGHT JOIN t4 ON b='';
000751  } {- - - - y}
000752  do_execsql_test join8-23020 {
000753    SELECT *
000754      FROM t1
000755           LEFT JOIN t2 ON TRUE
000756           JOIN t3 ON c=''
000757           RIGHT JOIN t4 ON b=''
000758     WHERE d ISNULL
000759  } {- - - - y}
000760  
000761  # 2022-06-14
000762  # dbsqlfuzz 2f3101834d14325a976f601b9267a0fd323d6bbd
000763  #
000764  # When the OP_NullRow opcode creates a new cursor, it must
000765  # set the cursor to no-reuse so that an OP_OpenEphemeral in
000766  # a subroutine does not try to reuse it.
000767  #
000768  reset_db
000769  db null -
000770  do_execsql_test join8-24000 {
000771    CREATE TABLE t4(b INT, c INT);
000772    CREATE TABLE t5(a INT, f INT);
000773    INSERT INTO t5 VALUES(1,2);
000774    WITH t7(x, y) AS (SELECT 100, 200 FROM t5)
000775      SELECT * FROM t4 JOIN t7 ON true RIGHT JOIN (SELECT y AS z FROM t7) AS t6 ON (x=z);
000776  } {- - - - 200}
000777  
000778  # 2022-06-20
000779  # forum/forumpost/6650cd40b5634f35
000780  #
000781  reset_db
000782  do_execsql_test join8-25000 {
000783    CREATE TABLE t1(a1 INT);
000784    CREATE TABLE t2(b2 INT);
000785    CREATE TABLE t3(c3 INT, d3 INT UNIQUE);
000786    CREATE TABLE t4(e4 INT, f4 TEXT);
000787    INSERT INTO t3(c3, d3) VALUES (2, 1);
000788    INSERT INTO t4(f4) VALUES ('x');
000789    CREATE INDEX i0 ON t3(c3) WHERE d3 ISNULL;
000790    ANALYZE main;
000791  }
000792  db null -
000793  do_execsql_test join8-25010 {
000794    SELECT * FROM t1 LEFT JOIN t2 ON true JOIN t3 ON (b2 IN (a1)) FULL JOIN t4 ON true;
000795  } {- - - - - x}
000796  do_execsql_test join8-25020 {
000797    SELECT 1 FROM t1 LEFT JOIN t2 ON true JOIN t3 ON (b2 IN (a1)) FULL JOIN t4 ON true;
000798  } {1}
000799  
000800  # 2022-07-13
000801  # forum/forumpost/174afeae57
000802  #
000803  reset_db
000804  db null -
000805  do_execsql_test join8-26000 {
000806    CREATE TABLE t1(a INT);
000807    CREATE TABLE t2(b INT, c INT);
000808    CREATE VIEW t3(d) AS SELECT NULL FROM t2 FULL OUTER JOIN t1 ON c=a UNION ALL SELECT b FROM t2;
000809    INSERT INTO t1(a) VALUES (NULL);
000810    INSERT INTO t2(b, c) VALUES (99, NULL);
000811    SELECT DISTINCT b, c, d FROM t2, t3 WHERE b<>0
000812     UNION SELECT DISTINCT b, c, d FROM t2, t3 WHERE b ISNULL;
000813  } {99 - - 99 - 99}
000814  
000815  finish_test