From: drh Date: Sun, 29 Aug 2004 01:31:05 +0000 (+0000) Subject: Progress toward fixing iproblems with compound selects. (CVS 1911) X-Git-Tag: version-3.6.10~4235 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fbc4ee7b70ffb225f668f867d3de91660a77b02e;p=thirdparty%2Fsqlite.git Progress toward fixing iproblems with compound selects. (CVS 1911) FossilOrigin-Name: 307478593d5d96b79386da222c7742ea2eaa5467 --- diff --git a/manifest b/manifest index bcfb3d07d3..ab7fa379dd 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index b33d1c54b2..bcecb81456 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d50c47b4995bd9b58e1293aa6513361cffc6babe \ No newline at end of file +307478593d5d96b79386da222c7742ea2eaa5467 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 191ec4ba1c..8cf658b7f1 100644 --- a/src/select.c +++ b/src/select.c @@ -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; ipOrderBy->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; ipOrderBy->nExpr; i++, pOrderByTerm++){ + Expr *pExpr = pOrderByTerm->pExpr; + char *zName = pOrderByTerm->zName; assert( pExpr->op==TK_COLUMN && pExpr->iColumnpColl ); 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 */