diff --git a/manifest b/manifest index 9332d172a2..609f6bf027 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sfuzztest\sdata\susing\sthe\slatest\stest\svectors\sdiscovered\sby\sAFL. -D 2015-06-20T14:11:56.166 +C Test\sthat\sthe\sleft\sand\sright\ssides\sof\sa\scompound\sSELECT\soperator\shave\sthe\ssame\s\snumber\sof\sexpressions\sin\sthe\sexpanded\sexpression\slist\sbefore\sbeginning\sto\sgenerate\scode. +D 2015-06-23T12:19:55.597 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1063c58075b7400d93326b0eb332b48a54f53025 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -248,14 +248,14 @@ F src/pragma.h b8632d7cdda7b25323fa580e3e558a4f0d4502cc F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c db11b5960105ee661dcac690f2ae6276e49bf251 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708 +F src/resolve.c 2d47554370de8de6dd5be060cef9559eec315005 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 15a17aff39e161d97deb880edc7e0527f01b2324 +F src/select.c 09865f89997db6ec617a78440cc18d84855e3053 F src/shell.c 8af3cced094aebb5f57a8ad739b9dafc7867eed7 F src/sqlite.h.in 76d2f5637eb795b6300d9dd3c3ec3632ffafd721 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h be1a718b7d2ce40ceba725ae92c8eb5f18003066 -F src/sqliteInt.h 95b99b2821811af1f2a1190fa829ffb8e6c04135 +F src/sqliteInt.h d5df694bc33870e77fb08f389d12309597fe3059 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -668,7 +668,7 @@ F test/hexlit.test 1d312fa816dfd3650a3bb488093bc09a0c927f67 F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 -F test/in.test b52fa96bcf6cebc5c8829c822315d0f87af9c6c2 +F test/in.test 61a24ae38d4b64ec69f06ccdf022992f68a98176 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 @@ -875,7 +875,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 -F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d +F test/select7.test 71f06cd37cb6f65bb08ba1ccf8e2f5818c09329f F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7 @@ -1286,7 +1286,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7cdbae625eb029538a693d2bebec465a6f65fb90 -R 5add07a39efb3611e2cfa0ac20a2c5f5 -U drh -Z 71db4d574368380e4b14cadc01f6d8d0 +P b97f9cf73e503c7285ba3a801e1f932f222d96b2 +R 5d4925e11483f968b1575f6656e62b8a +U dan +Z 6c0c66a18bcc0b19ae618b4e0a65b57c diff --git a/manifest.uuid b/manifest.uuid index ad06e9f3b1..3a395d46f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b97f9cf73e503c7285ba3a801e1f932f222d96b2 \ No newline at end of file +4df852ce26c95d5d23c83dbe9c59d2c3435acddf \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 27eba9fd07..fd57fd7028 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1331,6 +1331,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } + /* If this is part of a compound SELECT, check that it has the right + ** number of expressions in the select list. */ + if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ + sqlite3SelectWrongNumTermsError(pParse, p->pNext); + return WRC_Abort; + } + /* Advance to the next term of the compound */ p = p->pPrior; diff --git a/src/select.c b/src/select.c index e24b93b4b8..b98bae8123 100644 --- a/src/select.c +++ b/src/select.c @@ -2093,7 +2093,7 @@ static int multiSelectOrderBy( ** Error message for when two or more terms of a compound select have different ** size result sets. */ -static void selectWrongNumTermsError(Parse *pParse, Select *p){ +void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ if( p->selFlags & SF_Values ){ sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); }else{ @@ -2119,7 +2119,6 @@ static int multiSelectValues( SelectDest *pDest /* What to do with query results */ ){ Select *pPrior; - int nExpr = p->pEList->nExpr; int nRow = 1; int rc = 0; assert( p->selFlags & SF_MultiValue ); @@ -2128,10 +2127,7 @@ static int multiSelectValues( assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) ); assert( p->pLimit==0 ); assert( p->pOffset==0 ); - if( p->pEList->nExpr!=nExpr ){ - selectWrongNumTermsError(pParse, p); - return 1; - } + assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr ); if( p->pPrior==0 ) break; assert( p->pPrior->pNext==p ); p = p->pPrior; @@ -2240,11 +2236,7 @@ static int multiSelect( ** in their result sets. */ assert( p->pEList && pPrior->pEList ); - if( p->pEList->nExpr!=pPrior->pEList->nExpr ){ - selectWrongNumTermsError(pParse, p); - rc = 1; - goto multi_select_end; - } + assert( p->pEList->nExpr==pPrior->pEList->nExpr ); #ifndef SQLITE_OMIT_CTE if( p->selFlags & SF_Recursive ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4812b89944..3ebd8deb80 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3570,6 +3570,7 @@ void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*); int sqlite3CodeSubselect(Parse *, Expr *, int, int); void sqlite3SelectPrep(Parse*, Select*, NameContext*); +void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); int sqlite3ResolveExprNames(NameContext*, Expr*); void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); diff --git a/test/in.test b/test/in.test index de38c22456..3a42e84b9a 100644 --- a/test/in.test +++ b/test/in.test @@ -450,28 +450,42 @@ do_test in-12.10 { 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}} +} {1 {SELECTs to the left and right of UNION ALL do not have the same number of result columns}} 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}} +} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}} 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}} +} {1 {SELECTs to the left and right of EXCEPT do not have the same number of result columns}} do_test in-12.13 { catchsql { SELECT * FROM t2 WHERE a IN ( SELECT a FROM t3 INTERSECT SELECT a, b FROM t2 ); } +} {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}} +do_test in-12.14 { + catchsql { + SELECT * FROM t2 WHERE a IN ( + SELECT a, b 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.15 { + catchsql { + SELECT * FROM t2 WHERE a IN ( + 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}} }; #ifcapable compound diff --git a/test/select7.test b/test/select7.test index 6816b9fcb9..9ed5357748 100644 --- a/test/select7.test +++ b/test/select7.test @@ -15,6 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix select7 ifcapable compound { @@ -201,4 +202,23 @@ do_test select7-7.7 { } } {text 123} +do_execsql_test 8.0 { + CREATE TABLE t01(x, y); + CREATE TABLE t02(x, y); +} + +do_catchsql_test 8.1 { + SELECT * FROM ( + SELECT * FROM t01 UNION SELECT x FROM t02 + ) WHERE y=1 +} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}} + +do_catchsql_test 8.2 { + CREATE VIEW v0 as SELECT x, y FROM t01 UNION SELECT x FROM t02; + EXPLAIN QUERY PLAN SELECT * FROM v0 WHERE x='0' OR y; +} {1 {SELECTs to the left and right of UNION do not have the same number of result columns}} + + finish_test + +