1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Fix for ticket #136: Added the OP_RenameCursor VDBE instruction and used it

to make cursor numbers right on nested subqueries.  Also added OP_Gosub and
OP_Return but have not actually used them for anything yet. (CVS 727)

FossilOrigin-Name: c602603e7cd8dc5c8bb9db2748eacab650de5bf0
This commit is contained in:
drh
2002-08-25 19:20:40 +00:00
parent d94a669894
commit 8c74a8ca5b
7 changed files with 278 additions and 190 deletions

View 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.109 2002/08/25 18:29:12 drh Exp $
** $Id: select.c,v 1.110 2002/08/25 19:20:40 drh Exp $
*/
#include "sqliteInt.h"
@@ -1403,7 +1403,13 @@ substExprList(ExprList *pList, int iTable, ExprList *pEList, int iSub){
** All of the expression analysis must occur on both the outer query and
** the subquery before this routine runs.
*/
int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
static int flattenSubquery(
Parse *pParse, /* The parsing context */
Select *p, /* The parent or outer SELECT statement */
int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
int isAgg, /* True if outer SELECT uses aggregate functions */
int subqueryIsAgg /* True if the subquery uses aggregate functions */
){
Select *pSub; /* The inner query or "subquery" */
SrcList *pSrc; /* The FROM clause of the outer query */
SrcList *pSubSrc; /* The FROM clause of the subquery */
@@ -1486,6 +1492,7 @@ int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
}
}
p->isDistinct = p->isDistinct || pSub->isDistinct;
if( pSub->nLimit>=0 ){
if( p->nLimit<0 ){
p->nLimit = pSub->nLimit;
@@ -1494,6 +1501,20 @@ int flattenSubquery(Select *p, int iFrom, int isAgg, int subqueryIsAgg){
}
}
p->nOffset += pSub->nOffset;
/* If the subquery contains subqueries of its own, that were not
** flattened, then code will have already been generated to put
** the results of those sub-subqueries into VDBE cursors relative
** to the subquery. We must translate the cursor number into values
** suitable for use by the outer query.
*/
for(i=0; i<pSubSrc->nSrc; i++){
Vdbe *v;
if( pSubSrc->a[i].pSelect==0 ) continue;
v = sqliteGetVdbe(pParse);
sqliteVdbeAddOp(v, OP_RenameCursor, pSub->base+i, p->base+i);
}
if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){
sqliteDeleteTable(0, pSrc->a[iFrom].pTab);
}
@@ -1883,7 +1904,7 @@ int sqliteSelect(
** If flattening is a possiblity, do so and return immediately.
*/
if( pParent && pParentAgg &&
flattenSubquery(pParent, parentTab, *pParentAgg, isAgg) ){
flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
if( isAgg ) *pParentAgg = 1;
return rc;
}