aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/resolve.c21
-rw-r--r--src/select.c92
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/update.c5
-rw-r--r--src/where.c2
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