]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Allow WHERE terms to be pushed down into sub-queries that contain window functions...
authordan <Dan Kennedy>
Tue, 23 Feb 2021 15:53:22 +0000 (15:53 +0000)
committerdan <Dan Kennedy>
Tue, 23 Feb 2021 15:53:22 +0000 (15:53 +0000)
FossilOrigin-Name: 20689468100aed264877111367b42837ca19e63e717fed2ebd4b20b908f13178

1  2 
manifest
manifest.uuid
test/windowpushd.test

diff --cc manifest
index ab0ad06cfb4a2aa65c62773b7e36c6c8a02c5a4a,f38e1b95ae1fe71dabe6cecfd895b5dc8383ce57..6ec713d5fa173a8f3b6c2f5a125b612a4e38424c
+++ b/manifest
@@@ -1,5 -1,5 +1,5 @@@
- C Add\sa\sfew\ssimple\stest\scases\sfor\sMATERIALIZED\sand\sNOT\sMATERIALIZED.
- D 2021-02-22T19:57:58.697
 -C Further\stests\sfor\sthe\spush-down\soptimization\swith\swindow\sfunctions.
 -D 2021-02-23T15:36:06.380
++C Allow\sWHERE\sterms\sto\sbe\spushed\sdown\sinto\ssub-queries\sthat\scontain\swindow\sfunctions,\sprovided\sthat\sthe\sWHERE\sterm\sis\smade\sup\sof\sentirely\sof\sconstants\sand\scopies\sof\sexpressions\sfound\sin\sthe\sPARTITION\sBY\sclauses\sof\sall\swindow\sfunctions\sin\sthe\ssub-query.
++D 2021-02-23T15:53:22.797
  F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
  F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
  F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@@ -1782,7 -1782,8 +1782,8 @@@ F test/windowA.test 6d63dc1260daa17141a
  F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5
  F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
  F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
- F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad
+ F test/windowfault.test d543d46571b32d19f198cb04b6505747fabf3cc369970daae47074ee793612be
 -F test/windowpushd.test 2f442e00639117aad235bcd576c85a9bb24d5b011e9e0be784062a9656921a40
++F test/windowpushd.test 5b9c114e8173c3addacf58a0fcd941437b14649f2033700184479a13f188ad00
  F test/with1.test 780be387f01e290e768bdfd1827280f9e37ba37223eb4736aba386864fac5a94
  F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
  F test/with3.test 85e059bf4c2ef5626411ee59f399b4bb4b4a0f009bcb7db86f254e570ed11831
@@@ -1906,7 -1907,7 +1907,8 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9
  F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
  F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
  F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
- P b5a0778cc5a98a864bea72670f83262da940aceb91fa4cdf46ec097337a38a95
- R a0e8651539d2046a2eacfb9a26cd3050
- U drh
- Z 9ff3dc4427ac90918959bed5bdbcba59
 -P dac51f303bba1a0aac7768c688b0c134deb7641062cce2071d546f2d8f241dec
 -R 01aa28d00e9dcb21c3691c72496bc468
++P 64878124c160f790bc5861fd799ada03bd7db0c4426b8abc3b7ad1f7aa181168 4b089f70117bfb440eaefd830c05576be0cc624d9d6018c869270dc68e44513e
++R 267c5ff70b9a1aed147827dba5df0c68
++T +closed 4b089f70117bfb440eaefd830c05576be0cc624d9d6018c869270dc68e44513e
+ U dan
 -Z 2da9e360e2569fcff88e5b35e5221c66
++Z f3731ba7b880bf6d7b3236243b9b4e61
diff --cc manifest.uuid
index afadf1dc1b337e68348ec08c279f7e8d0e024ad7,1a898e92c87649bd02db2d759b65b3867097557f..c99b49c75f85665789e064b94b93dcbefd0c2621
@@@ -1,1 -1,1 +1,1 @@@
- 64878124c160f790bc5861fd799ada03bd7db0c4426b8abc3b7ad1f7aa181168
 -4b089f70117bfb440eaefd830c05576be0cc624d9d6018c869270dc68e44513e
++20689468100aed264877111367b42837ca19e63e717fed2ebd4b20b908f13178
index 0000000000000000000000000000000000000000,256e291730fb1715dfa715ab198f0d899de99f56..4462a0b4b4adc617707c136514995bb5f684085e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,226 +1,237 @@@
 -    } {USING INDEX i2 (b=?)}
+ # 2021 February 23
+ #
+ # The author disclaims copyright to this source code.  In place of
+ # a legal notice, here is a blessing:
+ #
+ #    May you do good and not evil.
+ #    May you find forgiveness for yourself and forgive others.
+ #    May you share freely, never taking more than you give.
+ #
+ #***********************************************************************
+ # This file implements regression tests for SQLite library.  The
+ # focus of this file is testing the push-down optimization when
+ # WHERE constraints are pushed down into a sub-query that uses
+ # window functions.
+ #
+ set testdir [file dirname $argv0]
+ source $testdir/tester.tcl
+ set testprefix windowpushd
+ do_execsql_test 1.0 {
+   CREATE TABLE t1(id INTEGER PRIMARY KEY, grp_id);
+   CREATE INDEX i1 ON t1(grp_id);
+   CREATE VIEW lll AS SELECT
+     row_number() OVER (PARTITION BY grp_id), 
+     grp_id, id 
+   FROM t1
+ }
+ do_execsql_test 1.1 {
+   INSERT INTO t1 VALUES
+     (1, 2), (2, 3), (3, 3), (4, 1), (5, 1),
+     (6, 1), (7, 1), (8, 1), (9, 3), (10, 3), 
+     (11, 2), (12, 3), (13, 3), (14, 2), (15, 1),
+     (16, 2), (17, 1), (18, 2), (19, 3), (20, 2)
+ }
+ do_execsql_test 1.2 {
+   SELECT * FROM lll
+ } {
+   1 1 4 2 1 5 3 1 6 4 1 7 5 1 8 6 1 15 7 1 17 
+   1 2 1 2 2 11 3 2 14 4 2 16 5 2 18 6 2 20 
+   1 3 2 2 3 3 3 3 9 4 3 10 5 3 12 6 3 13 7 3 19
+ }
+ do_execsql_test 1.3 {
+   SELECT * FROM lll WHERE grp_id=2
+ } {
+   1 2 1 2 2 11 3 2 14 4 2 16 5 2 18 6 2 20 
+ }
+ do_eqp_test 1.4 {
+   SELECT * FROM lll WHERE grp_id=2
+ } {SEARCH TABLE t1 USING COVERING INDEX i1 (grp_id=?)}
+ #-------------------------------------------------------------------------
+ reset_db
+ do_execsql_test 2.0 {
+   CREATE TABLE t1(a, b, c, d);
+   INSERT INTO t1 VALUES('A', 'C', 1,  0.1);
+   INSERT INTO t1 VALUES('A', 'D', 2,  0.2);
+   INSERT INTO t1 VALUES('A', 'E', 3,  0.3);
+   INSERT INTO t1 VALUES('A', 'C', 4,  0.4);
+   INSERT INTO t1 VALUES('B', 'D', 5,  0.5);
+   INSERT INTO t1 VALUES('B', 'E', 6,  0.6);
+   INSERT INTO t1 VALUES('B', 'C', 7,  0.7);
+   INSERT INTO t1 VALUES('B', 'D', 8,  0.8);
+   INSERT INTO t1 VALUES('C', 'E', 9,  0.9);
+   INSERT INTO t1 VALUES('C', 'C', 10, 1.0);
+   INSERT INTO t1 VALUES('C', 'D', 11, 1.1);
+   INSERT INTO t1 VALUES('C', 'E', 12, 1.2);
+   CREATE INDEX i1 ON t1(a);
+   CREATE INDEX i2 ON t1(b);
+   CREATE VIEW v1 AS SELECT a, c, max(c) OVER (PARTITION BY a) FROM t1;
+   CREATE VIEW v2 AS SELECT a, c, 
+       max(c) OVER (PARTITION BY a),
+       row_number() OVER ()
+   FROM t1;
+   CREATE VIEW v3 AS SELECT b, d, 
+       max(d) OVER (PARTITION BY b),
+       row_number() OVER (PARTITION BY b)
+   FROM t1;
+   CREATE TABLE t2(x, y, z);
+   INSERT INTO t2 VALUES('W', 3, 1);
+   INSERT INTO t2 VALUES('W', 2, 2);
+   INSERT INTO t2 VALUES('X', 1, 4);
+   INSERT INTO t2 VALUES('X', 5, 7);
+   INSERT INTO t2 VALUES('Y', 1, 9);
+   INSERT INTO t2 VALUES('Y', 4, 2);
+   INSERT INTO t2 VALUES('Z', 3, 3);
+   INSERT INTO t2 VALUES('Z', 3, 4);
+ }
+ foreach tn {0 1} {
+   optimization_control db push-down $tn
+   do_execsql_test 2.$tn.1.1 {
+     SELECT * FROM v1;
+   } {
+     A 1 4   A 2 4   A 3 4   A 4 4
+     B 5 8   B 6 8   B 7 8   B 8 8
+     C 9 12  C 10 12 C 11 12 C 12 12
+   }
+   do_execsql_test 2.$tn.1.2 {
+     SELECT * FROM v1 WHERE a IN ('A', 'B');
+   } {
+     A 1 4   A 2 4   A 3 4   A 4 4
+     B 5 8   B 6 8   B 7 8   B 8 8
+   }
+   do_execsql_test 2.$tn.1.3 {
+     SELECT * FROM v1 WHERE a IS 'C'
+   } {
+     C 9 12  C 10 12 C 11 12 C 12 12
+   }
+   if {$tn==1} {
+     do_eqp_test 2.$tn.1.4 {
+       SELECT * FROM v1 WHERE a IN ('A', 'B');
+     } {USING INDEX i1 (a=?)}
+     do_eqp_test 2.$tn.1.5 {
+       SELECT * FROM v1 WHERE a = 'c' COLLATE nocase
+     } {USING INDEX i1}
+   }
+   do_execsql_test 2.$tn.2.1 {
+     SELECT * FROM v2;
+   } {
+     A 1 4 1    A 2 4 2     A 3 4 3      A 4 4 4
+     B 5 8 5    B 6 8 6     B 7 8 7      B 8 8 8
+     C 9 12 9   C 10 12 10  C 11 12 11   C 12 12 12
+   }
+   do_execsql_test 2.$tn.2.2 {
+     SELECT * FROM v2 WHERE a = 'C';
+   } {
+     C 9 12 9   C 10 12 10  C 11 12 11   C 12 12 12
+   }
+   do_execsql_test 2.$tn.3.1 { SELECT * FROM v3; } { 
+     C 0.1 1.0 1 C 0.4 1.0 2 C 0.7 1.0 3 C 1.0 1.0 4 
+     D 0.2 1.1 1 D 0.5 1.1 2 D 0.8 1.1 3 D 1.1 1.1 4 
+     E 0.3 1.2 1 E 0.6 1.2 2 E 0.9 1.2 3 E 1.2 1.2 4
+   }
+   do_execsql_test 2.$tn.3.2 { SELECT * FROM v3 WHERE b<'E' } { 
+     C 0.1 1.0 1 C 0.4 1.0 2 C 0.7 1.0 3 C 1.0 1.0 4 
+     D 0.2 1.1 1 D 0.5 1.1 2 D 0.8 1.1 3 D 1.1 1.1 4 
+   }
+   if {$tn==1} {
+     do_eqp_test 2.$tn.3.3 {
+       SELECT * FROM v3 WHERE b='E'
 -    } {USING INDEX i2 (b>?)}
++    } {SEARCH TABLE t1 USING INDEX i2 (b=?)}
+     do_eqp_test 2.$tn.3.4 {
+       SELECT * FROM v3 WHERE b>'C'
++    } {SEARCH TABLE t1 USING INDEX i2 (b>?)}
++  }
++
++  do_execsql_test 2.$tn.3.5 { SELECT * FROM v3 WHERE d<0.55; } { 
++    C 0.1 1.0 1 C 0.4 1.0 2
++    D 0.2 1.1 1 D 0.5 1.1 2
++    E 0.3 1.2 1
++  }
++  if {$tn==1} {
++    do_eqp_test 2.$tn.3.6 {
++      SELECT * FROM v3 WHERE d<0.55
++    } {SCAN TABLE t1 USING INDEX i2}
+   }
+   do_execsql_test 2.$tn.4.1 {
+     SELECT * FROM (
+       SELECT x, sum(y) AS s, max(z) AS m 
+       FROM t2 GROUP BY x
+     )
+   } {
+     W 5 2
+     X 6 7
+     Y 5 9
+     Z 6 4
+   }
+   do_execsql_test 2.$tn.4.1 {
+     SELECT * FROM (
+       SELECT x, sum(y) AS s, max(z) AS m,
+         max( max(z) ) OVER (PARTITION BY sum(y) 
+             ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+         )
+       FROM t2 GROUP BY x
+     )
+   } {
+     W 5 2   9
+     Y 5 9   9
+     X 6 7   7
+     Z 6 4   7
+   }
+   do_execsql_test 2.$tn.4.2 {
+     SELECT * FROM (
+       SELECT x, sum(y) AS s, max(z) AS m,
+         max( max(z) ) OVER (PARTITION BY sum(y) 
+             ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+         )
+       FROM t2 GROUP BY x
+     ) WHERE s=6
+   } {
+     X 6 7   7
+     Z 6 4   7
+   }
+   do_execsql_test 2.$tn.4.3 {
+     SELECT * FROM (
+       SELECT x, sum(y) AS s, max(z) AS m,
+         max( max(z) ) OVER (PARTITION BY sum(y) 
+             ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+         )
+       FROM t2 GROUP BY x
+     ) WHERE s<6
+   } {
+     W 5 2   9
+     Y 5 9   9
+   }
+ }
+ finish_test