mirror of
				https://github.com/sqlite/sqlite.git
				synced 2025-10-31 18:11:01 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			237 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| # 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 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'
 | |
|     } {SEARCH t1 USING INDEX i2 (b=?)}
 | |
|     do_eqp_test 2.$tn.3.4 {
 | |
|       SELECT * FROM v3 WHERE b>'C'
 | |
|     } {SEARCH 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 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
 | 
