]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Progress toward fixing iproblems with compound selects. (CVS 1911)
authordrh <drh@noemail.net>
Sun, 29 Aug 2004 01:31:05 +0000 (01:31 +0000)
committerdrh <drh@noemail.net>
Sun, 29 Aug 2004 01:31:05 +0000 (01:31 +0000)
FossilOrigin-Name: 307478593d5d96b79386da222c7742ea2eaa5467

manifest
manifest.uuid
src/select.c

index bcfb3d07d3d62a09ff60b84964a9738d715579e2..ab7fa379ddc9e80c9e317c527307397c75e83ef9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sprototype\sin\ssqlite3.h\sfor\sthe\ssqlite3_libversion()\sfunction.\s(CVS\s1910)
-D 2004-08-28T18:21:21
+C Progress\stoward\sfixing\siproblems\swith\scompound\sselects.\s(CVS\s1911)
+D 2004-08-29T01:31:05
 F Makefile.in 65a7c43fcaf9a710d62f120b11b6e435eeb4a450
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -58,7 +58,7 @@ F src/parse.y 581a2ce014b843506805b2470c02b7865ad034d5
 F src/pragma.c a7cea75286fcff6666a5412b04478fcf0ecef5c4
 F src/printf.c 17b28a1eedfe8129b05de981719306c18c3f1327
 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
-F src/select.c 24b9ab865e34c0d5e7f2447558f93d1fe6f9d588
+F src/select.c 5fa9db32e24f4c0f0ead43cfa59a6cfc3a452a15
 F src/shell.c 42f65424a948f197f389e13bc7aaa3cf24dafd0c
 F src/sqlite.h.in d619f3dd276845c2ff3fbeaed1d037563fc419f0
 F src/sqliteInt.h c7ed161ecc40f9fd0f080fbcc00e34bd7d6735ee
@@ -244,7 +244,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 5f8d246852c7cefd5941b8c7bb22177dfc7157c5
-R 3f41463f2cecec8d057e1745a2da11b9
+P d50c47b4995bd9b58e1293aa6513361cffc6babe
+R e1fb8ddf0dd95f67094014c0c3248f2f
 U drh
-Z 4e0fa276b810f33b48f974651190c49f
+Z 1e45c8abb4ae3be9c92dd0026a2f0205
index b33d1c54b26db5054b69c5e2aaef8f846396a220..bcecb81456f697eed6f1dd3d0639ae07b3faf616 100644 (file)
@@ -1 +1 @@
-d50c47b4995bd9b58e1293aa6513361cffc6babe
\ No newline at end of file
+307478593d5d96b79386da222c7742ea2eaa5467
\ No newline at end of file
index 191ec4ba1c6285316782b96d9f18908cbdeb8079..8cf658b7f1758a0c5aa1a7944298a3f079ac55d9 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.203 2004/08/21 17:54:45 drh Exp $
+** $Id: select.c,v 1.204 2004/08/29 01:31:05 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -1279,26 +1279,54 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){
   return addr;
 }
 
+/*
+** FIX ME:
+**    +  Omit the ppOpenTemp parameter from multiSelectOpenTempAddr().
+**    +  Attach pOpenList to the right-most term always.
+**    +  Make sure Select.ppOpenTemp is initialized to NULL
+*/
+
+/*
+** Add the address "addr" to the set of all opcode addresses contained
+** in the pOpenTemp list for the whole compound select.  If no pOpenTemp
+** list has been created yet, then create a new one and make *ppOpenTemp
+** point to it.  If the pOpenTemp list already exists, leave *ppOpenTemp
+** unchanged and just add the new address to the existing list.
+*/
 static int multiSelectOpenTempAddr(Select *p, int addr, IdList **ppOpenTemp){
+  IdList *pList;
   if( !p->ppOpenTemp ){
+    /* Create a new list */
     *ppOpenTemp = sqlite3IdListAppend(0, 0);
     p->ppOpenTemp = ppOpenTemp;
   }else{
+    /* Add a new element onto the end of the existing list */
     *p->ppOpenTemp = sqlite3IdListAppend(*p->ppOpenTemp, 0);
   }
-  if( !(*p->ppOpenTemp) ){
+  pList = *p->ppOpenTemp;
+  if( pList==0 ){
     return SQLITE_NOMEM;
   }
-  (*p->ppOpenTemp)->a[(*p->ppOpenTemp)->nId-1].idx = addr;
+  pList->a[pList->nId-1].idx = addr;
   return SQLITE_OK;
 }
 
+/*
+** Return the appropriate collating sequence for the iCol-th column of
+** the result set for the compound-select statement "p".  Return NULL if
+** the column has no default collating sequence.
+**
+** The collating sequence for the compound select is taken from the
+** left-most term of the select that has a collating sequence.
+*/
 static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
-  CollSeq *pRet = 0;
+  CollSeq *pRet;
   if( p->pPrior ){
     pRet = multiSelectCollSeq(pParse, p->pPrior, iCol);
+  }else{
+    pRet = 0;
   }
-  if( !pRet ){
+  if( pRet==0 ){
     pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr);
   }
   return pRet;
@@ -1335,19 +1363,19 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
 ** individual selects always group from left to right.
 */
 static int multiSelect(
-  Parse *pParse, 
-  Select *p, 
-  int eDest, 
-  int iParm, 
-  char *aff           /* If eDest is SRT_Union, the affinity string */
+  Parse *pParse,        /* Parsing context */
+  Select *p,            /* The right-most of SELECTs to be coded */
+  int eDest,            /* \___  Store query results as specified */
+  int iParm,            /* /     by these two parameters.         */
+  char *aff             /* If eDest is SRT_Union, the affinity string */
 ){
-  int rc = SQLITE_OK;  /* Success code from a subroutine */
-  Select *pPrior;     /* Another SELECT immediately to our left */
-  Vdbe *v;            /* Generate code to this VDBE */
-  IdList *pOpenTemp = 0;
+  int rc = SQLITE_OK;   /* Success code from a subroutine */
+  Select *pPrior;       /* Another SELECT immediately to our left */
+  Vdbe *v;              /* Generate code to this VDBE */
+  IdList *pOpenTemp = 0;/* OP_OpenTemp opcodes that need a KeyInfo */
 
   /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
-  ** the last SELECT in the series may have an ORDER BY or LIMIT.
+  ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
   */
   if( p==0 || p->pPrior==0 ){
     rc = 1;
@@ -1375,11 +1403,26 @@ static int multiSelect(
     goto multi_select_end;
   }
 
+  /* PART OF FIX:
+  */
+  if( p->ppOpenTemp==0 ){
+    p->ppOpenTemp = &pOpenTemp;
+  }
+  pPrior->ppOpenTemp = p->ppOpenTemp;
+
   /* Create the destination temporary table if necessary
   */
   if( eDest==SRT_TempTable ){
     assert( p->pEList );
     sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
+
+    /* FIX ME:
+    ** p->pEList->nExpr might contain a "*" and so might not be the 
+    ** correct number.  Go ahead and code the SetNumColumns instruction
+    ** here, but also record its address.   Change the P2 value of the
+    ** instruction to the number of columns after sqlite3Select() has
+    ** been called to code the subquery and has modified pEList->nExpr
+    ** to be the correct value. */
     sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, p->pEList->nExpr);
     eDest = SRT_Table;
   }
@@ -1391,7 +1434,7 @@ static int multiSelect(
       if( p->pOrderBy==0 ){
         pPrior->nLimit = p->nLimit;
         pPrior->nOffset = p->nOffset;
-        pPrior->ppOpenTemp = p->ppOpenTemp;
+        /* pPrior->ppOpenTemp = p->ppOpenTemp; // FIX */
         rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff);
         if( rc ){
           goto multi_select_end;
@@ -1448,7 +1491,7 @@ static int multiSelect(
 
       /* Code the SELECT statements to our left
       */
-      pPrior->ppOpenTemp = p->ppOpenTemp;
+      /* pPrior->ppOpenTemp = p->ppOpenTemp; // FIX */
       rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff);
       if( rc ){
         goto multi_select_end;
@@ -1536,7 +1579,7 @@ static int multiSelect(
 
       /* Code the SELECTs to our left into temporary table "tab1".
       */
-      pPrior->ppOpenTemp = p->ppOpenTemp;
+      /* pPrior->ppOpenTemp = p->ppOpenTemp; // FIX */
       rc = sqlite3Select(pParse, pPrior, SRT_Union, tab1, 0, 0, 0, aff);
       if( rc ){
         goto multi_select_end;
@@ -1599,10 +1642,17 @@ static int multiSelect(
     goto multi_select_end;
   }
 
+  /* Compute collating sequences used by either the ORDER BY clause or
+  ** by any temporary tables needed to implement the compound select.
+  ** Attach the KeyInfo structure to all temporary tables.  Invoke the
+  ** ORDER BY processing if there is an ORDER BY clause.
+  */
   if( p->pOrderBy || (pOpenTemp && pOpenTemp->nId>0) ){
-    int nCol = p->pEList->nExpr;
-    int i;
-    KeyInfo *pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*sizeof(CollSeq*));
+    int nCol = p->pEList->nExpr;  /* Number of columns in the result set */
+    int i;                        /* Loop counter */
+    KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
+
+    pKeyInfo = sqliteMalloc(sizeof(*pKeyInfo)+nCol*sizeof(CollSeq*));
     if( !pKeyInfo ){
       rc = SQLITE_NOMEM;
       goto multi_select_end;
@@ -1625,9 +1675,10 @@ static int multiSelect(
     }
 
     if( p->pOrderBy ){
-      for(i=0; i<p->pOrderBy->nExpr; i++){
-        Expr *pExpr = p->pOrderBy->a[i].pExpr;
-        char *zName = p->pOrderBy->a[i].zName;
+      struct ExprList_item *pOrderByTerm = p->pOrderBy->a;
+      for(i=0; i<p->pOrderBy->nExpr; i++, pOrderByTerm++){
+        Expr *pExpr = pOrderByTerm->pExpr;
+        char *zName = pOrderByTerm->zName;
         assert( pExpr->op==TK_COLUMN && pExpr->iColumn<nCol );
         assert( !pExpr->pColl );
         if( zName ){
@@ -2318,7 +2369,6 @@ int sqlite3Select(
     generateColumnNames(pParse, pTabList, pEList);
   }
 
-#if 1  /* I do not think we need the following code any more.... */
   /* If the destination is SRT_Union, then set the number of columns in
   ** the records that will be inserted into the temporary table. The caller
   ** couldn't do this, in case the select statement is of the form 
@@ -2333,7 +2383,6 @@ int sqlite3Select(
   if( eDest==SRT_Union ){
     sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, pEList->nExpr);
   }
-#endif
 
   /* Generate code for all sub-queries in the FROM clause
   */