]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Match ORDER BY terms to columns using names in compound queries. Make sure
authordrh <drh@noemail.net>
Fri, 13 Apr 2007 16:06:32 +0000 (16:06 +0000)
committerdrh <drh@noemail.net>
Fri, 13 Apr 2007 16:06:32 +0000 (16:06 +0000)
this works for subqueries, especially in the right-hand side of an IN
operator. Ticket #2296. (CVS 3842)

FossilOrigin-Name: cfc6f933dc60ca88ae848f7f0c402e820437c2ff

manifest
manifest.uuid
src/expr.c
src/select.c
test/select1.test

index f1957e3058990f32a4db6ec1f2a2c959ac9a5167..38a871e2ee7f8c1ab8ea2f231a37229c69bd3fbb 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sbug\sin\sautovacuum\sintroduced\sby\s(3839).\s(CVS\s3841)
-D 2007-04-13T04:01:59
+C Match\sORDER\sBY\sterms\sto\scolumns\susing\snames\sin\scompound\squeries.\s\sMake\ssure\nthis\sworks\sfor\ssubqueries,\sespecially\sin\sthe\sright-hand\sside\sof\san\sIN\noperator.\sTicket\s#2296.\s(CVS\s3842)
+D 2007-04-13T16:06:33
 F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -66,7 +66,7 @@ F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675
 F src/date.c 74b76691bddf58b634f6bf4a77c8c58234268c6e
 F src/delete.c 151d08386bf9c9e7f92f6b9106c71efec2def184
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
-F src/expr.c a8740c24af3f39f2d502be1a1c640c96435eaac0
+F src/expr.c 2c32c546006627d70a7b941b318489980fd1912e
 F src/func.c 007d957c057bb42b0d37aa6ad4be0e1c67a8871b
 F src/hash.c 67b23e14f0257b69a3e8aa663e4eeadc1a2b6fd5
 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
@@ -93,7 +93,7 @@ F src/pragma.c 3b992b5b2640d6ae25cef05aa6a42cd1d6c43234
 F src/prepare.c 37207b2b2ccb41d379b01dd62231686bcc48ef1f
 F src/printf.c 0c6f40648770831341ac45ab32423a80b4c87f05
 F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
-F src/select.c bd1742051f3418c2f035371e0dcea741c1907842
+F src/select.c 4fa2b45a9c19988f295ea118d95ce68a56a00eb4
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c 3ae4654560e91220a95738a73d135d91d937cda1
 F src/sqlite.h.in e429f66f9245c7f8675db24b230c950b8672ad1c
@@ -302,7 +302,7 @@ F test/rowid.test 040a3bef06f970c45f5fcd14b2355f7f4d62f0cf
 F test/safety.test 4a06934e45d03b8b50ebcd8d174eb0367d2fd851
 F test/schema.test 8a2ae440fb15f5798a68059e8746402f3137be46
 F test/schema2.test d815923e57e90b8c60ddf5e0d8fd65075e94f57f
-F test/select1.test 1287b040f912b979ccc8d4b50ea585eeeacf1835
+F test/select1.test 1a35bf8201c8a42a44d65acc3e6c9796a9c43dfb
 F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3
 F test/select3.test 2d473f45c57c0526833e045fca0537badec0dd04
 F test/select4.test 305ba0a6e97efc5544def5e5cb49b54e1bf87fd9
@@ -458,7 +458,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 764e7262b93a7a5073128ecd4db265b0c728a701
-R 31c090858c1e13005c3e16c77f0df139
+P e39efa195a28f1cd7431b0811bd908dc7af3c8b1
+R b434a64adc5cd5e0bdd07ca7975fa65b
 U drh
-Z 533934c267007014330b5ce7d6a0b1a1
+Z 8bca189cccc6e2802e95c88c94744665
index 52e8e0649f1b2f9271f2333e0d91779a13046bbb..99eda3ad82d74095d8d1078977ea53ced89f25ca 100644 (file)
@@ -1 +1 @@
-e39efa195a28f1cd7431b0811bd908dc7af3c8b1
\ No newline at end of file
+cfc6f933dc60ca88ae848f7f0c402e820437c2ff
\ No newline at end of file
index 934f988406377110476157b7baf3ce4d49d29375..f4237b46afba7348a093c6fd847bb9f0f9b71ced 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.283 2007/03/27 13:36:37 drh Exp $
+** $Id: expr.c,v 1.284 2007/04/13 16:06:33 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1420,7 +1420,9 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
         int iParm = pExpr->iTable +  (((int)affinity)<<16);
         ExprList *pEList;
         assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
-        sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0);
+        if( sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0) ){
+          return;
+        }
         pEList = pExpr->pSelect->pEList;
         if( pEList && pEList->nExpr>0 ){ 
           keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft,
@@ -1491,7 +1493,9 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
       }
       sqlite3ExprDelete(pSel->pLimit);
       pSel->pLimit = sqlite3Expr(TK_INTEGER, 0, 0, &one);
-      sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0);
+      if( sqlite3Select(pParse, pSel, sop, iMem, 0, 0, 0, 0) ){
+        return;
+      }
       break;
     }
   }
index 041b9c862d7acb68599ce2d4aee38f99e91097c5..bc0c0ff520cfedb4bee56f23dcca6b0049e2ba5a 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.335 2007/04/12 21:25:02 drh Exp $
+** $Id: select.c,v 1.336 2007/04/13 16:06:33 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -1401,8 +1401,11 @@ static int matchOrderbyToColumn(
   }
   pEList = pSelect->pEList;
   for(i=0; i<pOrderBy->nExpr; i++){
+    struct ExprList_item *pItem;
     Expr *pE = pOrderBy->a[i].pExpr;
     int iCol = -1;
+    char *zLabel;
+
     if( pOrderBy->a[i].done ) continue;
     if( sqlite3ExprIsInteger(pE, &iCol) ){
       if( iCol<=0 || iCol>pEList->nExpr ){
@@ -1415,20 +1418,21 @@ static int matchOrderbyToColumn(
       if( !mustComplete ) continue;
       iCol--;
     }
-    for(j=0; iCol<0 && j<pEList->nExpr; j++){
-      if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
-        char *zName, *zLabel;
-        zName = pEList->a[j].zName;
-        zLabel = sqlite3NameFromToken(&pE->token);
-        assert( zLabel!=0 );
-        if( sqlite3StrICmp(zName, zLabel)==0 ){ 
+    if( iCol<0 && (zLabel = sqlite3NameFromToken(&pE->token))!=0 ){
+      for(j=0, pItem=pEList->a; j<pEList->nExpr; j++, pItem++){
+        char *zName;
+        if( pItem->zName ){
+          zName = sqlite3StrDup(pItem->zName);
+        }else{
+          zName = sqlite3NameFromToken(&pItem->pExpr->token);
+        }
+        if( zName && sqlite3StrICmp(zName, zLabel)==0 ){
           iCol = j;
+          break;
         }
-        sqliteFree(zLabel);
-      }
-      if( iCol<0 && sqlite3ExprCompare(pE, pEList->a[j].pExpr) ){
-        iCol = j;
+        sqliteFree(zName);
       }
+      sqliteFree(zLabel);
     }
     if( iCol>=0 ){
       pE->op = TK_COLUMN;
@@ -1436,8 +1440,7 @@ static int matchOrderbyToColumn(
       pE->iTable = iTable;
       pE->iAgg = -1;
       pOrderBy->a[i].done = 1;
-    }
-    if( iCol<0 && mustComplete ){
+    }else if( mustComplete ){
       sqlite3ErrorMsg(pParse,
         "ORDER BY term number %d does not match any result column", i+1);
       nErr++;
index 81fba4cdd6315d3409b5cb849e7a0ae447041380..c5ecd860cb54ada1961d4d8386b607de5f8f8790 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the SELECT statement.
 #
-# $Id: select1.test,v 1.52 2007/04/06 15:02:14 drh Exp $
+# $Id: select1.test,v 1.53 2007/04/13 16:06:34 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -495,7 +495,45 @@ do_test select1-6.11 {
     ORDER BY f2+100;
   }} msg]
   lappend v $msg
-} {0 {f1 11 f1 33 f1 122 f1 144}}
+} {1 {ORDER BY term number 1 does not match any result column}}
+
+# Ticket #2296
+do_test select1-6.20 {
+   execsql {
+     CREATE TABLE t6(a TEXT, b TEXT);
+     INSERT INTO t6 VALUES('a','0');
+     INSERT INTO t6 VALUES('b','1');
+     INSERT INTO t6 VALUES('c','2');
+     INSERT INTO t6 VALUES('d','3');
+     SELECT a FROM t6 WHERE b IN 
+        (SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
+                 ORDER BY 1 LIMIT 1)
+   }
+} {a}
+do_test select1-6.21 {
+   execsql {
+     SELECT a FROM t6 WHERE b IN 
+        (SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
+                 ORDER BY 1 DESC LIMIT 1)
+   }
+} {d}
+do_test select1-6.22 {
+   execsql {
+     SELECT a FROM t6 WHERE b IN 
+        (SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
+                 ORDER BY b LIMIT 2)
+     ORDER BY a;
+   }
+} {a b}
+do_test select1-6.23 {
+   execsql {
+     SELECT a FROM t6 WHERE b IN 
+        (SELECT b FROM t6 WHERE a<='b' UNION SELECT '3' AS x
+                 ORDER BY x DESC LIMIT 2)
+     ORDER BY a;
+   }
+} {b d}
+
 } ;#ifcapable compound
 
 do_test select1-7.1 {