diff options
author | drh <drh@noemail.net> | 2013-08-15 22:40:21 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2013-08-15 22:40:21 +0000 |
commit | 0af16ab2c2d5eec0eb01f512af96ef01909a095c (patch) | |
tree | 087313c0625e5751b5662e867ee1c103ab9f15fb | |
parent | e35463b312a5ec35ae5546d155a75380e0d03e64 (diff) | |
download | sqlite-0af16ab2c2d5eec0eb01f512af96ef01909a095c.tar.gz sqlite-0af16ab2c2d5eec0eb01f512af96ef01909a095c.zip |
Make sure that GROUP BY terms select input column names in preference to
output column names, in compliance with the SQL standard.
Ticket [1c69be2dafc28].
FossilOrigin-Name: f2d175f975cd0be63425424ec322a98fb650019e
-rw-r--r-- | manifest | 14 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/resolve.c | 18 | ||||
-rw-r--r-- | test/resolver01.test | 56 |
4 files changed, 74 insertions, 16 deletions
@@ -1,5 +1,5 @@ -C Bare\sidentifiers\sin\sORDER\sBY\sclauses\sbind\smore\stightly\sto\soutput\scolumn\sname,\nbut\sidentifiers\sin\sexpressions\sbind\smore\stightly\sto\sinput\scolumn\snames.\nThis\sis\sa\scompromise\sbetween\sSQL92\sand\sSQL99\sbehavior\sand\sis\swhat\nPostgreSQL\sand\sMS-SQL\sdo.\s\sTicket\s[f617ea3125e9c]. -D 2013-08-15T20:24:27.463 +C Make\ssure\sthat\sGROUP\sBY\sterms\sselect\sinput\scolumn\snames\sin\spreference\sto\noutput\scolumn\snames,\sin\scompliance\swith\sthe\sSQL\sstandard.\nTicket\s[1c69be2dafc28]. +D 2013-08-15T22:40:21.803 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,7 @@ F src/pragma.c 590c75750d93ec5a1f903e4bb0dc6d2a0845bf8b F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f F src/printf.c 41c49dac366a3a411190001a8ab495fa8887974e F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 -F src/resolve.c 2a760f369ddbcd951f176556c8ec05be04cdd0da +F src/resolve.c 9d53899cc6e1f4ec0b4632d07e97d57827bf63b9 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 8b148eb851f384412aea57091659d14b369918ca F src/shell.c 927e17b37b63b24461e372d982138fb22c4df321 @@ -733,7 +733,7 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 F test/releasetest.mk 2eced2f9ae701fd0a29e714a241760503ccba25a F test/releasetest.tcl 06d289d8255794073a58d2850742f627924545ce -F test/resolver01.test a98ed8a2e9f78600155d783389ad4e6537010285 +F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a F test/rollback.test a1b4784b864331eae8b2a98c189efa2a8b11ff07 F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48 @@ -1105,7 +1105,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P 53cd9ebfaf401c7932bf591e134a527c9962b88e -R b873391074dfe27843eed5ca71b0596f +P c78b357c00a35ed48ce2ffbc041de8d22570d1e2 +R 0cad26d57aaadc86e4d0689961c53035 U drh -Z 52475f320db5f901cc1dc06cbb7fef10 +Z 9ac8068bb659c66e2e7c0f0532626e1f diff --git a/manifest.uuid b/manifest.uuid index 1f70b2151..cb7ffe874 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c78b357c00a35ed48ce2ffbc041de8d22570d1e2
\ No newline at end of file +f2d175f975cd0be63425424ec322a98fb650019e
\ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index b41a7adda..43a3870e2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1043,14 +1043,16 @@ static int resolveOrderGroupBy( for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){ Expr *pE = pItem->pExpr; Expr *pE2 = sqlite3ExprSkipCollate(pE); - iCol = resolveAsName(pParse, pSelect->pEList, pE2); - if( iCol>0 ){ - /* If an AS-name match is found, mark this ORDER BY column as being - ** a copy of the iCol-th result-set column. The subsequent call to - ** sqlite3ResolveOrderGroupBy() will convert the expression to a - ** copy of the iCol-th result-set expression. */ - pItem->iOrderByCol = (u16)iCol; - continue; + if( zType[0]!='G' ){ + iCol = resolveAsName(pParse, pSelect->pEList, pE2); + if( iCol>0 ){ + /* If an AS-name match is found, mark this ORDER BY column as being + ** a copy of the iCol-th result-set column. The subsequent call to + ** sqlite3ResolveOrderGroupBy() will convert the expression to a + ** copy of the iCol-th result-set expression. */ + pItem->iOrderByCol = (u16)iCol; + continue; + } } if( sqlite3ExprIsInteger(pE2, &iCol) ){ /* The ORDER BY term is an integer constant. Again, set the column diff --git a/test/resolver01.test b/test/resolver01.test index 3bad26915..7d95a2132 100644 --- a/test/resolver01.test +++ b/test/resolver01.test @@ -149,4 +149,60 @@ do_execsql_test resolver01-4.1 { SELECT '3', substr(m,2) AS m FROM t4 ORDER BY lower(m); } {1 x 1 y 1 z 2 x 2 y 2 z 3 z 3 y 3 x} +########################################################################## +# Test cases for ticket [1c69be2dafc28]: Make sure the GROUP BY binds +# more tightly to the input tables in all cases. +# +# This first case case has been wrong in SQLite for time out of mind. +# For SQLite version 3.7.17 the answer was two rows, which is wrong. +# +do_execsql_test resolver01-5.1 { + CREATE TABLE t5(m CHAR(2)); + INSERT INTO t5 VALUES('ax'); + INSERT INTO t5 VALUES('bx'); + INSERT INTO t5 VALUES('cy'); + SELECT count(*), substr(m,2,1) AS m FROM t5 GROUP BY m ORDER BY 1, 2; +} {1 x 1 x 1 y} + +# This case is unambiguous and has always been correct. +# +do_execsql_test resolver01-5.2 { + SELECT count(*), substr(m,2,1) AS mx FROM t5 GROUP BY m ORDER BY 1, 2; +} {1 x 1 x 1 y} + +# This case is not allowed in standard SQL, but SQLite allows and does +# the sensible thing. +# +do_execsql_test resolver01-5.3 { + SELECT count(*), substr(m,2,1) AS mx FROM t5 GROUP BY mx ORDER BY 1, 2; +} {1 y 2 x} +do_execsql_test resolver01-5.4 { + SELECT count(*), substr(m,2,1) AS mx FROM t5 + GROUP BY substr(m,2,1) ORDER BY 1, 2; +} {1 y 2 x} + +# These test case weere provided in the 2013-08-14 email from Rob Golsteijn +# that originally reported the problem of ticket [1c69be2dafc28]. +# +do_execsql_test resolver01-6.1 { + CREATE TABLE t61(name); + SELECT min(name) FROM t61 GROUP BY lower(name); +} {} +do_execsql_test resolver01-6.2 { + SELECT min(name) AS name FROM t61 GROUP BY lower(name); +} {} +do_execsql_test resolver01-6.3 { + CREATE TABLE t63(name); + INSERT INTO t63 VALUES (NULL); + INSERT INTO t63 VALUES ('abc'); + SELECT count(), + NULLIF(name,'abc') AS name + FROM t63 + GROUP BY lower(name); +} {1 {} 1 {}} + + + + + finish_test |