Move the test for an (illegal) scalar sub-query that returns more than one column to earlier in SELECT processing in order to avoid an assert() that can happen later on.

FossilOrigin-Name: a55842cfb56b659c88832dce9ce7bafb50258211
This commit is contained in:
dan 2010-09-02 19:01:16 +00:00
parent 7ff2719e88
commit 74b617b22a
5 changed files with 100 additions and 36 deletions

View File

@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Fix\san\soff-by-one\serror\sin\sthe\sscratch\smemory\sallocator.
D 2010-09-02T18:13:01
C Move\sthe\stest\sfor\san\s(illegal)\sscalar\ssub-query\sthat\sreturns\smore\sthan\sone\scolumn\sto\searlier\sin\sSELECT\sprocessing\sin\sorder\sto\savoid\san\sassert()\sthat\scan\shappen\slater\son.
D 2010-09-02T19:01:16
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -174,7 +171,7 @@ F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c fb7008115d9ccd85f6b6934c15c204b7fe6bfc38
F src/select.c eb57331a0f37fbfff0b24824555ac70dbc996c4d
F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056
F src/sqlite.h.in b77b914f5f4c301ca00b2fc0fe253240ec177503
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
@ -349,7 +346,7 @@ F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d
F test/descidx3.test fe720e8b37d59f4cef808b0bf4e1b391c2e56b6f
F test/diskfull.test 0cede7ef9d8f415d9d3944005c76be7589bb5ebb
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
F test/e_expr.test 1d4437a740dcffa675aa33d50d3440be9805f922
F test/e_expr.test 1aef3ba4a140487cf5b452f04e261f26e99f9fe5
F test/e_fkey.test 6721a741c6499b3ab7e5385923233343c8f1ad05
F test/e_fts3.test 75bb0aee26384ef586165e21018a17f7cd843469
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
@ -443,7 +440,7 @@ F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c
F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/in.test d49419c6df515852f477fa513f3317181d46bc92
F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test 64f3cc1acde1b9161ccdd8e5bde3daefdb5b2617
@ -856,14 +853,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 2211486b69cf53f5efb1334aff8b403b26596102
R 58aa05496d4c88e93839c30ad7f0f12f
U drh
Z 9ab20b082ef4d5eb3039a58dec067745
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFMf+kwoxKgR168RlERArAIAJ44f+KasgThCWlpaivQQWtOA27OrACeL7/e
Ym5tzUVAgx/gSuZ7kCIQ05g=
=rGma
-----END PGP SIGNATURE-----
P 5a9591607a0a5ba4527bf2a90179651053244953
R 7b514d804097129d93b3bae4d77340bd
U dan
Z b5e46a0ab42bf67eb22bcfbf65812650

View File

@ -1 +1 @@
5a9591607a0a5ba4527bf2a90179651053244953
a55842cfb56b659c88832dce9ce7bafb50258211

View File

@ -3626,6 +3626,15 @@ int sqlite3Select(
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto select_end;
/* If writing to memory or generating a set
** only a single column may be output.
*/
#ifndef SQLITE_OMIT_SUBQUERY
if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
goto select_end;
}
#endif
/* Generate code for all sub-queries in the FROM clause
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
@ -3699,15 +3708,6 @@ int sqlite3Select(
}
#endif
/* If writing to memory or generating a set
** only a single column may be output.
*/
#ifndef SQLITE_OMIT_SUBQUERY
if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
goto select_end;
}
#endif
/* If possible, rewrite the query to use GROUP BY instead of DISTINCT.
** GROUP BY might use an index, DISTINCT never does.
*/

View File

@ -1729,11 +1729,56 @@ foreach {tn e1 e2} {
do_expr_test e_expr-34.5.${tn}b $e2 integer $res
}
#-------------------------------------------------------------------------
# Test statements related to the IN and NOT IN operators.
# Test statements related to scalar sub-queries.
#
catch { db close }
file delete -force test.db
sqlite3 db test.db
do_test e_expr-35.0 {
execsql {
CREATE TABLE t2(a, b);
INSERT INTO t2 VALUES('one', 'two');
INSERT INTO t2 VALUES('three', NULL);
INSERT INTO t2 VALUES(4, 5.0);
}
} {}
# EVIDENCE-OF: R-00980-39256 A SELECT statement enclosed in parentheses
# may appear as a scalar quantity.
#
# EVIDENCE-OF: R-56294-03966 All types of SELECT statement, including
# aggregate and compound SELECT queries (queries with keywords like
# UNION or EXCEPT) are allowed as scalar subqueries.
#
do_expr_test e_expr-35.1.1 { (SELECT 35) } integer 35
do_expr_test e_expr-35.1.2 { (SELECT NULL) } null {}
do_expr_test e_expr-35.1.3 { (SELECT count(*) FROM t2) } integer 3
do_expr_test e_expr-35.1.4 { (SELECT 4 FROM t2) } integer 4
do_expr_test e_expr-35.1.5 {
(SELECT b FROM t2 UNION SELECT a+1 FROM t2)
} null {}
do_expr_test e_expr-35.1.6 {
(SELECT a FROM t2 UNION SELECT COALESCE(b, 55) FROM t2 ORDER BY 1)
} integer 4
# EVIDENCE-OF: R-46899-53765 A SELECT used as a scalar quantity must
# return a result set with a single column.
#
set M {only a single result allowed for a SELECT that is part of an expression}
foreach {tn sql} {
1 { SELECT (SELECT * FROM t2 UNION SELECT a+1, b+1 FROM t2) }
2 { SELECT (SELECT * FROM t2 UNION SELECT a+1, b+1 FROM t2 ORDER BY 1) }
3 { SELECT (SELECT 1, 2) }
4 { SELECT (SELECT NULL, NULL, NULL) }
5 { SELECT (SELECT * FROM t2) }
6 { SELECT (SELECT * FROM (SELECT 1, 2, 3)) }
} {
do_catchsql_test e_expr-35.2.$tn $sql [list 1 $M]
}
finish_test

View File

@ -404,33 +404,62 @@ do_test in-12.5 {
do_test in-12.6 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
SELECT a, b FROM t3 UNION ALL SELECT a FROM t2
);
}
} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}}
do_test in-12.7 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 UNION SELECT a, b FROM t2
SELECT a, b FROM t3 UNION SELECT a FROM t2
);
}
} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}}
do_test in-12.8 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 EXCEPT SELECT a, b FROM t2
SELECT a, b FROM t3 EXCEPT SELECT a FROM t2
);
}
} {1 {SELECTs to the left and right of EXCEPT do not have the same number of result columns}}
do_test in-12.9 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 INTERSECT SELECT a, b FROM t2
SELECT a, b FROM t3 INTERSECT SELECT a FROM t2
);
}
} {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}}
}
do_test in-12.10 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 UNION ALL SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-12.11 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 UNION SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-12.12 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 EXCEPT SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
do_test in-12.13 {
catchsql {
SELECT * FROM t2 WHERE a IN (
SELECT a FROM t3 INTERSECT SELECT a, b FROM t2
);
}
} {1 {only a single result allowed for a SELECT that is part of an expression}}
#------------------------------------------------------------------------
# The following tests check that NULL is handled correctly when it