Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Take care when checking the table of a TK_COLUMN expression node to see if the table is a virtual table to first ensure that the Expr.y.pTab pointer is not null due to generated column optimizations. Ticket [4374860b29383380]. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
9d0d4ab95dc0c56e053c2924ed322a9e |
User & Date: | drh 2020-02-17 00:12:04 |
Context
2020-02-17
| ||
19:25 | A better (smaller and faster) solution to ticket [4374860b29383380]. (check-in: abc473fb user: drh tags: trunk) | |
00:12 | Take care when checking the table of a TK_COLUMN expression node to see if the table is a virtual table to first ensure that the Expr.y.pTab pointer is not null due to generated column optimizations. Ticket [4374860b29383380]. (check-in: 9d0d4ab9 user: drh tags: trunk) | |
2020-02-16
| ||
17:40 | Avoid an infinite recursion on an illegal recursive definition of an fts5vocab table. (check-in: 109ee074 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 | } break; } default: break; } return rc; } /* ** Return FALSE if there is no chance that the expression can be NULL. ** ** If the expression might be NULL or if the expression is too complex ** to tell return TRUE. ** | > > > > > > > > > | 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 | } break; } default: break; } return rc; } /* ** Return true if p is a Column node that references a virtual table. */ int sqlite3ExprIsVtabRef(Expr *p){ if( p->op!=TK_COLUMN ) return 0; if( p->y.pTab==0 ) return 0; return IsVirtual(p->y.pTab); } /* ** Return FALSE if there is no chance that the expression can be NULL. ** ** If the expression might be NULL or if the expression is too complex ** to tell return TRUE. ** |
︙ | ︙ | |||
5475 5476 5477 5478 5479 5480 5481 | case TK_GE: 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 ); | | | | 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 | case TK_GE: 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( sqlite3ExprIsVtabRef(pExpr->pLeft) || sqlite3ExprIsVtabRef(pExpr->pRight) ){ return WRC_Prune; } default: return WRC_Continue; } |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 | int sqlite3ExprIsConstantOrFunction(Expr*, u8); int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); int sqlite3ExprIsTableConstant(Expr*,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS int sqlite3ExprContainsSubquery(Expr*); #endif int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); | > | 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 | int sqlite3ExprIsConstantOrFunction(Expr*, u8); int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); int sqlite3ExprIsTableConstant(Expr*,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS int sqlite3ExprContainsSubquery(Expr*); #endif int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprIsVtabRef(Expr*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); |
︙ | ︙ |
Changes to src/whereexpr.c.
︙ | ︙ | |||
373 374 375 376 377 378 379 | ** virtual table on their second argument, which is the same as ** the left-hand side operand in their in-fix form. ** ** vtab_column MATCH expression ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; | | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | ** virtual table on their second argument, which is the same as ** the left-hand side operand in their in-fix form. ** ** vtab_column MATCH expression ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; if( sqlite3ExprIsVtabRef(pCol) ){ for(i=0; i<ArraySize(aOp); i++){ if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; *ppRight = pList->a[0].pExpr; *ppLeft = pCol; return 1; } |
︙ | ︙ | |||
395 396 397 398 399 400 401 | ** OVERLOADED(vtab_column,expression) ** ** Historically, xFindFunction expected to see lower-case function ** names. But for this use case, xFindFunction is expected to deal ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; | | | 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | ** OVERLOADED(vtab_column,expression) ** ** Historically, xFindFunction expected to see lower-case function ** names. But for this use case, xFindFunction is expected to deal ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; if( sqlite3ExprIsVtabRef(pCol) ){ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); void *pNotUsed; pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); |
︙ | ︙ | |||
418 419 420 421 422 423 424 | } } } }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; | | | | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | } } } }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; if( sqlite3ExprIsVtabRef(pLeft) ){ res++; } if( pRight && sqlite3ExprIsVtabRef(pRight) ){ res++; SWAP(Expr*, pLeft, pRight); } *ppLeft = pLeft; *ppRight = pRight; if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE; if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT; |
︙ | ︙ |