diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/resolve.c | 21 | ||||
-rw-r--r-- | src/select.c | 92 | ||||
-rw-r--r-- | src/sqliteInt.h | 2 | ||||
-rw-r--r-- | src/update.c | 5 | ||||
-rw-r--r-- | src/where.c | 2 |
5 files changed, 68 insertions, 54 deletions
diff --git a/src/resolve.c b/src/resolve.c index 4090bdd6e..40aab3fac 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -395,6 +395,27 @@ lookupname_end: } /* +** Allocate and return a pointer to an expression to load the column iCol +** from datasource iSrc datasource in SrcList pSrc. +*/ +Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ + Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); + if( p ){ + struct SrcList_item *pItem = &pSrc->a[iSrc]; + p->pTab = pItem->pTab; + p->iTable = pItem->iCursor; + if( p->pTab->iPKey==iCol ){ + p->iColumn = -1; + }else{ + p->iColumn = iCol; + pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol); + } + ExprSetProperty(p, EP_Resolved); + } + return p; +} + +/* ** This routine is callback for sqlite3WalkExpr(). ** ** Resolve symbolic names into TK_COLUMN operators for the current diff --git a/src/select.c b/src/select.c index f470befaf..0f6a2b251 100644 --- a/src/select.c +++ b/src/select.c @@ -192,51 +192,45 @@ static int columnIndex(Table *pTab, const char *zCol){ } /* -** Create an expression node for an identifier with the name of zName -*/ -Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){ - return sqlite3Expr(pParse->db, TK_ID, zName); -} - -/* -** Add a term to the WHERE expression in *ppExpr that requires the -** zCol column to be equal in the two tables pTab1 and pTab2. +** This function is used to add terms implied by JOIN syntax to the +** WHERE clause expression of a SELECT statement. The new term, which +** is ANDed with the existing WHERE clause, is of the form: +** +** (tab1.col1 = tab2.col2) +** +** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the +** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is +** column iColRight of tab2. */ static void addWhereTerm( - Parse *pParse, /* Parsing context */ - const char *zCol, /* Name of the column */ - const Table *pTab1, /* First table */ - const char *zAlias1, /* Alias for first table. May be NULL */ - const Table *pTab2, /* Second table */ - const char *zAlias2, /* Alias for second table. May be NULL */ - int iRightJoinTable, /* VDBE cursor for the right table */ - Expr **ppExpr, /* Add the equality term to this expression */ - int isOuterJoin /* True if dealing with an OUTER join */ + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* List of tables in FROM clause */ + int iSrc, /* Index of first table to join in pSrc */ + int iColLeft, /* Index of column in first table */ + int iColRight, /* Index of column in second table */ + int isOuterJoin, /* True if this is an OUTER join */ + Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ ){ - Expr *pE1a, *pE1b, *pE1c; - Expr *pE2a, *pE2b, *pE2c; - Expr *pE; - - pE1a = sqlite3CreateIdExpr(pParse, zCol); - pE2a = sqlite3CreateIdExpr(pParse, zCol); - if( zAlias1==0 ){ - zAlias1 = pTab1->zName; - } - pE1b = sqlite3CreateIdExpr(pParse, zAlias1); - if( zAlias2==0 ){ - zAlias2 = pTab2->zName; - } - pE2b = sqlite3CreateIdExpr(pParse, zAlias2); - pE1c = sqlite3PExpr(pParse, TK_DOT, pE1b, pE1a, 0); - pE2c = sqlite3PExpr(pParse, TK_DOT, pE2b, pE2a, 0); - pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0); - if( pE && isOuterJoin ){ - ExprSetProperty(pE, EP_FromJoin); - assert( !ExprHasAnyProperty(pE, EP_TokenOnly|EP_Reduced) ); - ExprSetIrreducible(pE); - pE->iRightJoinTable = (i16)iRightJoinTable; + sqlite3 *db = pParse->db; + Expr *pE1; + Expr *pE2; + Expr *pEq; + + assert( pSrc->nSrc>(iSrc+1) ); + assert( pSrc->a[iSrc].pTab ); + assert( pSrc->a[iSrc+1].pTab ); + + pE1 = sqlite3CreateColumnExpr(db, pSrc, iSrc, iColLeft); + pE2 = sqlite3CreateColumnExpr(db, pSrc, iSrc+1, iColRight); + + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0); + if( pEq && isOuterJoin ){ + ExprSetProperty(pEq, EP_FromJoin); + assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetIrreducible(pEq); + pEq->iRightJoinTable = (i16)pE2->iTable; } - *ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE); + *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq); } /* @@ -318,11 +312,9 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ } for(j=0; j<pLeftTab->nCol; j++){ char *zName = pLeftTab->aCol[j].zName; - if( columnIndex(pRightTab, zName)>=0 ){ - addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, - pRightTab, pRight->zAlias, - pRight->iCursor, &p->pWhere, isOuter); - + int iRightCol = columnIndex(pRightTab, zName); + if( iRightCol>=0 ){ + addWhereTerm(pParse, pSrc, i, j, iRightCol, isOuter, &p->pWhere); } } } @@ -355,14 +347,14 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ IdList *pList = pRight->pUsing; for(j=0; j<pList->nId; j++){ char *zName = pList->a[j].zName; - if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){ + int iLeftCol = columnIndex(pLeftTab, zName); + int iRightCol = columnIndex(pRightTab, zName); + if( iLeftCol<0 || iRightCol<0 ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); return 1; } - addWhereTerm(pParse, zName, pLeftTab, pLeft->zAlias, - pRightTab, pRight->zAlias, - pRight->iCursor, &p->pWhere, isOuter); + addWhereTerm(pParse, pSrc, i, iLeftCol, iRightCol, isOuter, &p->pWhere); } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c2c947d12..49cf77c23 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2643,7 +2643,6 @@ int sqlite3ExprCompare(Expr*, Expr*); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*); -Expr *sqlite3CreateIdExpr(Parse *, const char*); void sqlite3PrngSaveState(void); void sqlite3PrngRestoreState(void); void sqlite3PrngResetState(void); @@ -2877,6 +2876,7 @@ void sqlite3StrAccumAppend(StrAccum*,const char*,int); char *sqlite3StrAccumFinish(StrAccum*); void sqlite3StrAccumReset(StrAccum*); void sqlite3SelectDestInit(SelectDest*,int,int); +Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); void sqlite3BackupRestart(sqlite3_backup *); void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); diff --git a/src/update.c b/src/update.c index 3703c1b59..3f5e15ff4 100644 --- a/src/update.c +++ b/src/update.c @@ -579,8 +579,7 @@ static void updateVirtualTable( /* Construct the SELECT statement that will find the new values for ** all updated rows. */ - pEList = sqlite3ExprListAppend(pParse, 0, - sqlite3CreateIdExpr(pParse, "_rowid_")); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_")); if( pRowid ){ pEList = sqlite3ExprListAppend(pParse, pEList, sqlite3ExprDup(db, pRowid, 0)); @@ -590,7 +589,7 @@ static void updateVirtualTable( if( aXRef[i]>=0 ){ pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0); }else{ - pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName); + pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName); } pEList = sqlite3ExprListAppend(pParse, pEList, pExpr); } diff --git a/src/where.c b/src/where.c index b4ad2ccd6..53ec26b84 100644 --- a/src/where.c +++ b/src/where.c @@ -2034,6 +2034,7 @@ static int whereRangeRegion( ** ** If an error occurs, return an error code. Otherwise, SQLITE_OK. */ +#ifdef SQLITE_ENABLE_STAT2 static int valueFromExpr( Parse *pParse, Expr *pExpr, @@ -2050,6 +2051,7 @@ static int valueFromExpr( } return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp); } +#endif /* ** This function is used to estimate the number of rows that will be visited |