diff options
author | dan <Dan Kennedy> | 2021-07-07 13:53:55 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2021-07-07 13:53:55 +0000 |
commit | 74777f994d5735e0fb3020ef24f3d0229cdc7ca2 (patch) | |
tree | d3a7afd1d5be0b68ac064159080958d3b85e4069 /src | |
parent | cc516af4cc35c8db816aed7c69f7aef7d663e78e (diff) | |
download | sqlite-74777f994d5735e0fb3020ef24f3d0229cdc7ca2.tar.gz sqlite-74777f994d5735e0fb3020ef24f3d0229cdc7ca2.zip |
Improve the error message in cases where there is a row-value on the LHS of an IN() operator, the RHS is a list (not a sub-select) and at least one element of the list is not a row-value with the correct number of elements.
FossilOrigin-Name: 6b22f4e71dbc14c887ebbda67095b5faaa8079cac87cd4ab5a2ae90c71cd9633
Diffstat (limited to 'src')
-rw-r--r-- | src/expr.c | 34 | ||||
-rw-r--r-- | src/parse.y | 9 | ||||
-rw-r--r-- | src/sqliteInt.h | 2 |
3 files changed, 24 insertions, 21 deletions
diff --git a/src/expr.c b/src/expr.c index 8351723f0..44abb58e5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -948,37 +948,37 @@ void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ /* ** Expression list pEList is a list of vector values. This function ** converts the contents of pEList to a VALUES(...) Select statement -** returning 1 row for each element of the list. If there are any -** non-vector expressions in the list, the corresponding row returned -** by the values statement contains a single column, the value of -** the non-vector expression itself. +** returning 1 row for each element of the list. For example, the +** expression list: ** -** For example, the expression list: +** ( (1,2), (3,4) (5,6) ) ** -** ( (1, 2), 3, (3, 4, 5) ) +** is translated to the equivalent of: ** -** is translated to: +** VALUES(1,2), (3,4), (5,6) ** -** VALUES(1, 2), (3), (3, 4, 5) +** Each of the vector values in pEList must contain exactly nElem terms. +** If a list element that is not a vector or does not contain nElem terms, +** an error message is left in pParse. ** ** This is used as part of processing IN(...) expressions with a list ** of vectors on the RHS. e.g. "... IN ((1,2), (3,4), (5,6))". */ -Select *sqlite3ExprListToValues(Parse *pParse, ExprList *pEList){ +Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprList *pEList){ int ii; Select *pRet = 0; for(ii=0; ii<pEList->nExpr; ii++){ Select *pSel; - ExprList *pList; Expr *pExpr = pEList->a[ii].pExpr; - if( pExpr->op==TK_VECTOR ){ - pList = pExpr->x.pList; - pExpr->x.pList = 0; - }else{ - pList = sqlite3ExprListAppend(pParse, 0, pExpr); - pEList->a[ii].pExpr = 0; + int nExprElem = sqlite3ExprVectorSize(pExpr); + if( nExprElem!=nElem ){ + sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d", + nExprElem, nExprElem>1?"s":"", nElem + ); + break; } - pSel = sqlite3SelectNew(pParse, pList, 0, 0, 0, 0, 0, SF_Values, 0); + pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0); + pExpr->x.pList = 0; if( pSel ){ if( pRet ){ pSel->op = TK_ALL; diff --git a/src/parse.y b/src/parse.y index efc390ca0..7a0387336 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1256,15 +1256,18 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0"); }else{ Expr *pRHS = Y->a[0].pExpr; - if( Y->nExpr==1 && sqlite3ExprIsConstant(pRHS) && pRHS->op!=TK_VECTOR ){ + if( Y->nExpr==1 && sqlite3ExprIsConstant(pRHS) && A->op!=TK_VECTOR ){ Y->a[0].pExpr = 0; sqlite3ExprListDelete(pParse->db, Y); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); A = sqlite3PExpr(pParse, TK_EQ, A, pRHS); }else{ A = sqlite3PExpr(pParse, TK_IN, A, 0); - if( pRHS->op==TK_VECTOR || A==0 ){ - Select *pRHS = sqlite3ExprListToValues(pParse, Y); + if( A==0 ){ + sqlite3ExprListDelete(pParse->db, Y); + }else if( A->pLeft->op==TK_VECTOR ){ + int nExpr = A->pLeft->x.pList->nExpr; + Select *pRHS = sqlite3ExprListToValues(pParse, nExpr, Y); if( pRHS ){ parserDoubleLinkSelect(pParse, pRHS); sqlite3PExprAddSelect(pParse, A, pRHS); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 935ee0953..4d92703f1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4324,7 +4324,7 @@ void sqlite3ExprDeferredDelete(Parse*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); -Select *sqlite3ExprListToValues(Parse*, ExprList*); +Select *sqlite3ExprListToValues(Parse*, int, ExprList*); void sqlite3ExprListSetSortOrder(ExprList*,int,int); void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); |