Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a crash that could occur under certain circumstances if the vectors on either side of a comparison operator were of a different size. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | rowvalue |
Files: | files | file ages | folders |
SHA1: |
42670935aba152ba774c2a8bdcbe72b9 |
User & Date: | dan 2016-09-05 09:44:45.878 |
Context
2016-09-05
| ||
12:12 | Do vector comparison size checking early - at name resolution time - to forestall future problems. (check-in: ae127bcc0a user: drh tags: rowvalue) | |
09:44 | Fix a crash that could occur under certain circumstances if the vectors on either side of a comparison operator were of a different size. (check-in: 42670935ab user: dan tags: rowvalue) | |
2016-09-03
| ||
19:52 | Fix a problem causing the affinity of sub-select row-value elements to be ignored in some contextes. (check-in: 7d9bd22c07 user: dan tags: rowvalue) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
517 518 519 520 521 522 523 | int dest, /* Write results into this register */ u8 op, /* Comparison operator */ u8 p5 /* SQLITE_NULLEQ or zero */ ){ Vdbe *v = pParse->pVdbe; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; | < < | < | < < | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 | int dest, /* Write results into this register */ u8 op, /* Comparison operator */ u8 p5 /* SQLITE_NULLEQ or zero */ ){ Vdbe *v = pParse->pVdbe; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; if( sqlite3ExprCheckComparison(pParse, pLeft, pRight)==0 ){ int nLeft = sqlite3ExprVectorSize(pLeft); int i; int regLeft = 0; int regRight = 0; u8 opx = op; int addrDone = sqlite3VdbeMakeLabel(v); assert( pExpr->op==TK_EQ || pExpr->op==TK_NE |
︙ | ︙ | |||
2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 | sqlite3ErrorMsg(pParse, "row value misused"); } return 1; } return 0; } #endif #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code for an IN expression. ** ** x IN (SELECT ...) ** x IN (value, value, ...) | > > > > > > > > > > > > > > > > > > > > > > > | 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 | sqlite3ErrorMsg(pParse, "row value misused"); } return 1; } return 0; } #endif /* ** Expressions pLeft and pRight are the left and right sides of a comparison ** operator. If either pLeft or pRight is a vector and the other is not, or ** if they are both vectors but of a different size, leave an error message ** in the Parse object and return non-zero. Or, if there is no problem, ** return 0. */ int sqlite3ExprCheckComparison(Parse *pParse, Expr *pLeft, Expr *pRight){ int nLeft = sqlite3ExprVectorSize(pLeft); int nRight = sqlite3ExprVectorSize(pRight); if( nLeft!=nRight ){ if( (pRight->flags & EP_xIsSelect) ){ sqlite3SubselectError(pParse, nRight, nLeft); }else if( pLeft->flags & EP_xIsSelect ){ sqlite3SubselectError(pParse, nLeft, nRight); }else{ sqlite3ErrorMsg(pParse, "row value misused"); } return 1; } return 0; } #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code for an IN expression. ** ** x IN (SELECT ...) ** x IN (value, value, ...) |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 | void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); #ifndef SQLITE_OMIT_SUBQUERY int sqlite3ExprCheckIN(Parse*, Expr*); #else # define sqlite3ExprCheckIN(x,y) SQLITE_OK #endif #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 void sqlite3AnalyzeFunctions(void); int sqlite3Stat4ProbeSetValue( Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); | > | 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 | void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); #ifndef SQLITE_OMIT_SUBQUERY int sqlite3ExprCheckIN(Parse*, Expr*); #else # define sqlite3ExprCheckIN(x,y) SQLITE_OK #endif int sqlite3ExprCheckComparison(Parse*, Expr*, Expr*); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 void sqlite3AnalyzeFunctions(void); int sqlite3Stat4ProbeSetValue( Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); |
︙ | ︙ |
Changes to src/whereexpr.c.
︙ | ︙ | |||
947 948 949 950 951 952 953 954 955 956 957 958 959 960 | pTerm->iParent = -1; pTerm->eOperator = 0; if( allowedOp(op) ){ int iCur, iColumn; Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; if( pTerm->iField>0 ){ assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; } | > > > > | 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | pTerm->iParent = -1; pTerm->eOperator = 0; if( allowedOp(op) ){ int iCur, iColumn; Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; if( pRight && sqlite3ExprCheckComparison(pParse, pLeft, pRight) ){ return; } if( pTerm->iField>0 ){ assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; } |
︙ | ︙ |
Changes to test/rowvalue4.test.
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 3 "SELECT * FROM t1 WHERE NOT (b = (1, 2))" {row value misused} 4 "SELECT * FROM t1 LIMIT (1, 2)" {row value misused} 5 "SELECT (a, b) IN (SELECT * FROM t1) FROM t1" {sub-select returns 3 columns - expected 2} 6 "SELECT * FROM t1 WHERE (a, b) IN (SELECT * FROM t1)" {sub-select returns 3 columns - expected 2} } { do_catchsql_test 2.$tn "$s" [list 1 $error] } #------------------------------------------------------------------------- do_execsql_test 2.0 { CREATE TABLE t2(a, b, c, d); | > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 3 "SELECT * FROM t1 WHERE NOT (b = (1, 2))" {row value misused} 4 "SELECT * FROM t1 LIMIT (1, 2)" {row value misused} 5 "SELECT (a, b) IN (SELECT * FROM t1) FROM t1" {sub-select returns 3 columns - expected 2} 6 "SELECT * FROM t1 WHERE (a, b) IN (SELECT * FROM t1)" {sub-select returns 3 columns - expected 2} 7 "SELECT * FROM t1 WHERE (c, c) <= 1" {row value misused} 8 "SELECT * FROM t1 WHERE (b, b) <= 1" {row value misused} } { do_catchsql_test 2.$tn "$s" [list 1 $error] } #------------------------------------------------------------------------- do_execsql_test 2.0 { CREATE TABLE t2(a, b, c, d); |
︙ | ︙ |