aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.c9
-rw-r--r--src/parse.y13
-rw-r--r--src/select.c8
-rw-r--r--src/sqliteInt.h3
4 files changed, 28 insertions, 5 deletions
diff --git a/src/expr.c b/src/expr.c
index 795f65052..51a1f22a0 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -891,6 +891,15 @@ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
/*
+** Set the error offset for an Expr node, if possible.
+*/
+void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){
+ if( pExpr==0 ) return;
+ if( NEVER(ExprUseWJoin(pExpr)) ) return;
+ pExpr->w.iOfst = iOfst;
+}
+
+/*
** This routine is the core allocator for Expr nodes.
**
** Construct a new expression node and return a pointer to it. Memory
diff --git a/src/parse.y b/src/parse.y
index 4dc064252..0b2562a1f 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -655,14 +655,17 @@ selcollist(A) ::= sclp(A) scanpt(B) expr(X) scanpt(Z) as(Y). {
if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1);
sqlite3ExprListSetSpan(pParse,A,B,Z);
}
-selcollist(A) ::= sclp(A) scanpt STAR. {
+selcollist(A) ::= sclp(A) scanpt STAR(X). {
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
+ sqlite3ExprSetErrorOffset(p, (int)(X.z - pParse->zTail));
A = sqlite3ExprListAppend(pParse, A, p);
}
-selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. {
- Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
- Expr *pLeft = tokenExpr(pParse, TK_ID, X);
- Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
+selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR(Y). {
+ Expr *pRight, *pLeft, *pDot;
+ pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
+ sqlite3ExprSetErrorOffset(pRight, (int)(Y.z - pParse->zTail));
+ pLeft = tokenExpr(pParse, TK_ID, X);
+ pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
A = sqlite3ExprListAppend(pParse,A, pDot);
}
diff --git a/src/select.c b/src/select.c
index b492d5374..71610484b 100644
--- a/src/select.c
+++ b/src/select.c
@@ -6108,10 +6108,16 @@ static int selectExpander(Walker *pWalker, Select *p){
** expanded. */
int tableSeen = 0; /* Set to 1 when TABLE matches */
char *zTName = 0; /* text of name of TABLE */
+ int iErrOfst;
if( pE->op==TK_DOT ){
assert( pE->pLeft!=0 );
assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
zTName = pE->pLeft->u.zToken;
+ assert( ExprUseWOfst(pE->pLeft) );
+ iErrOfst = pE->pRight->w.iOfst;
+ }else{
+ assert( ExprUseWOfst(pE) );
+ iErrOfst = pE->w.iOfst;
}
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab; /* Table for this data source */
@@ -6148,6 +6154,7 @@ static int selectExpander(Walker *pWalker, Select *p){
for(ii=0; ii<pUsing->nId; ii++){
const char *zUName = pUsing->a[ii].zName;
pRight = sqlite3Expr(db, TK_ID, zUName);
+ sqlite3ExprSetErrorOffset(pRight, iErrOfst);
pNew = sqlite3ExprListAppend(pParse, pNew, pRight);
if( pNew ){
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
@@ -6220,6 +6227,7 @@ static int selectExpander(Walker *pWalker, Select *p){
}else{
pExpr = pRight;
}
+ sqlite3ExprSetErrorOffset(pExpr, iErrOfst);
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
if( pNew==0 ){
break; /* OOM */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index d4e255ea2..4009d4f8d 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3023,6 +3023,8 @@ struct Expr {
*/
#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
#define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0)
+#define ExprUseWOfst(E) (((E)->flags&(EP_InnerON|EP_OuterON))==0)
+#define ExprUseWJoin(E) (((E)->flags&(EP_InnerON|EP_OuterON))!=0)
#define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0)
#define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0)
#define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0)
@@ -5491,6 +5493,7 @@ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
#define sqlite3SelectExprHeight(x) 0
#define sqlite3ExprCheckHeight(x,y)
#endif
+void sqlite3ExprSetErrorOffset(Expr*,int);
u32 sqlite3Get4byte(const u8*);
void sqlite3Put4byte(u8*, u32);