| https://sqlite.org/cgi/src/info/9d0d4ab95dc0c56e |
| https://sqlite.org/cgi/src/info/abc473fb8fb99900 |
| https://sqlite.org/cgi/src/info/5aeb5a2d295e10d5 |
| https://sqlite.org/cgi/src/info/a67cf5b7d37d5b14 |
| https://sqlite.org/cgi/src/info/c431b3fd8fd0f6a6 |
| |
| --- /sqlite3.c |
| +++ /sqlite3.c |
| @@ -17428,8 +17428,11 @@ |
| */ |
| #ifndef SQLITE_OMIT_VIRTUALTABLE |
| # define IsVirtual(X) ((X)->nModuleArg) |
| +# define ExprIsVtab(X) \ |
| + ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg) |
| #else |
| # define IsVirtual(X) 0 |
| +# define ExprIsVtab(X) 0 |
| #endif |
| |
| /* |
| @@ -97816,7 +97819,7 @@ |
| assert( !ExprHasProperty(pExpr, EP_Reduced) ); |
| /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", |
| ** and "x IS NOT FALSE". */ |
| - if( pRight->op==TK_ID ){ |
| + if( pRight && pRight->op==TK_ID ){ |
| int rc = resolveExprStep(pWalker, pRight); |
| if( rc==WRC_Abort ) return WRC_Abort; |
| if( pRight->op==TK_TRUEFALSE ){ |
| @@ -104133,19 +104136,25 @@ |
| case TK_LT: |
| case TK_LE: |
| case TK_GT: |
| - case TK_GE: |
| + case TK_GE: { |
| + Expr *pLeft = pExpr->pLeft; |
| + Expr *pRight = pExpr->pRight; |
| testcase( pExpr->op==TK_EQ ); |
| testcase( pExpr->op==TK_NE ); |
| testcase( pExpr->op==TK_LT ); |
| testcase( pExpr->op==TK_LE ); |
| testcase( pExpr->op==TK_GT ); |
| testcase( pExpr->op==TK_GE ); |
| - if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) |
| - || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) |
| + /* The y.pTab=0 assignment in wherecode.c always happens after the |
| + ** impliesNotNullRow() test */ |
| + if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0) |
| + && IsVirtual(pLeft->y.pTab)) |
| + || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0) |
| + && IsVirtual(pRight->y.pTab)) |
| ){ |
| - return WRC_Prune; |
| + return WRC_Prune; |
| } |
| - |
| + } |
| default: |
| return WRC_Continue; |
| } |
| @@ -130673,6 +130682,7 @@ |
| /* Generate code to take the intersection of the two temporary |
| ** tables. |
| */ |
| + if( rc ) break; |
| assert( p->pEList ); |
| iBreak = sqlite3VdbeMakeLabel(pParse); |
| iCont = sqlite3VdbeMakeLabel(pParse); |
| @@ -133015,7 +133025,7 @@ |
| pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); |
| sqlite3TokenInit(&sColname, zColname); |
| sqlite3ExprListSetName(pParse, pNew, &sColname, 0); |
| - if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ |
| + if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ |
| struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; |
| sqlite3DbFree(db, pX->zEName); |
| if( pSub ){ |
| @@ -142593,7 +142603,8 @@ |
| ** MATCH(expression,vtab_column) |
| */ |
| pCol = pList->a[1].pExpr; |
| - if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ |
| + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); |
| + if( ExprIsVtab(pCol) ){ |
| for(i=0; i<ArraySize(aOp); i++){ |
| if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ |
| *peOp2 = aOp[i].eOp2; |
| @@ -142615,7 +142626,8 @@ |
| ** with function names in an arbitrary case. |
| */ |
| pCol = pList->a[0].pExpr; |
| - if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ |
| + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); |
| + if( ExprIsVtab(pCol) ){ |
| sqlite3_vtab *pVtab; |
| sqlite3_module *pMod; |
| void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); |
| @@ -142638,10 +142650,12 @@ |
| int res = 0; |
| Expr *pLeft = pExpr->pLeft; |
| Expr *pRight = pExpr->pRight; |
| - if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ |
| + testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); |
| + if( ExprIsVtab(pLeft) ){ |
| res++; |
| } |
| - if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ |
| + testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); |
| + if( pRight && ExprIsVtab(pRight) ){ |
| res++; |
| SWAP(Expr*, pLeft, pRight); |
| } |