mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Refactor the SrcItem object so that information about subqueries is stored
in a separately allocated Subquery object. This reduces the memory requirements for SrcItem and makes the code run faster. It also provides an expansion path for subquery processing that does not burden simple queries. The current checking mostly works, but there are still issues that need to be tracked down and fixed. FossilOrigin-Name: 8ff5dda8448d7e1a533d7f27db2573ce68fa9956b9d9847ced45e83c1f06bab0
This commit is contained in:
26
src/expr.c
26
src/expr.c
@@ -1877,18 +1877,30 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){
|
||||
SrcItem *pNewItem = &pNew->a[i];
|
||||
const SrcItem *pOldItem = &p->a[i];
|
||||
Table *pTab;
|
||||
if( pOldItem->fg.fixedSchema ){
|
||||
pNewItem->fg = pOldItem->fg;
|
||||
if( pOldItem->fg.isSubquery ){
|
||||
Subquery *pNewSubq = sqlite3DbMallocRaw(db, sizeof(Subquery));
|
||||
if( pNewSubq==0 ){
|
||||
assert( db->mallocFailed );
|
||||
pNewItem->fg.isSubquery = 0;
|
||||
}else{
|
||||
memcpy(pNewSubq, pOldItem->u4.pSubq, sizeof(*pNewSubq));
|
||||
pNewSubq->pSelect = sqlite3SelectDup(db, pNewSubq->pSelect, flags);
|
||||
if( pNewSubq->pSelect==0 ){
|
||||
sqlite3DbFree(db, pNewSubq);
|
||||
pNewSubq = 0;
|
||||
pNewItem->fg.isSubquery = 0;
|
||||
}
|
||||
}
|
||||
pNewItem->u4.pSubq = pNewSubq;
|
||||
}else if( pOldItem->fg.fixedSchema ){
|
||||
pNewItem->u4.pSchema = pOldItem->u4.pSchema;
|
||||
}else{
|
||||
pNewItem->u4.zDatabase = sqlite3DbStrDup(db, pOldItem->u4.zDatabase);
|
||||
}
|
||||
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
|
||||
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
|
||||
pNewItem->fg = pOldItem->fg;
|
||||
pNewItem->iCursor = pOldItem->iCursor;
|
||||
pNewItem->sq.addrFillSub = pOldItem->sq.addrFillSub;
|
||||
pNewItem->sq.regReturn = pOldItem->sq.regReturn;
|
||||
pNewItem->sq.regResult = pOldItem->sq.regResult;
|
||||
if( pNewItem->fg.isIndexedBy ){
|
||||
pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
|
||||
}else if( pNewItem->fg.isTabFunc ){
|
||||
@@ -1905,7 +1917,6 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){
|
||||
if( pTab ){
|
||||
pTab->nTabRef++;
|
||||
}
|
||||
pNewItem->sq.pSelect = sqlite3SelectDup(db, pOldItem->sq.pSelect, flags);
|
||||
if( pOldItem->fg.isUsing ){
|
||||
assert( pNewItem->fg.isUsing );
|
||||
pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
|
||||
@@ -1979,7 +1990,6 @@ Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
|
||||
pp = &pNew->pPrior;
|
||||
pNext = pNew;
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
#else
|
||||
@@ -2999,7 +3009,7 @@ static Select *isCandidateForInOpt(const Expr *pX){
|
||||
pSrc = p->pSrc;
|
||||
assert( pSrc!=0 );
|
||||
if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
|
||||
if( pSrc->a[0].sq.pSelect ) return 0; /* FROM is not a subquery or view */
|
||||
if( pSrc->a[0].fg.isSubquery) return 0;/* FROM is not a subquery or view */
|
||||
pTab = pSrc->a[0].pSTab;
|
||||
assert( pTab!=0 );
|
||||
assert( !IsView(pTab) ); /* FROM clause is not a view */
|
||||
|
Reference in New Issue
Block a user