Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix SQLITE_OMIT_SUBQUERY builds. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | rowvalue |
Files: | files | file ages | folders |
SHA1: |
339f85f414a484e44d2502d1ff7281ca |
User & Date: | dan 2016-08-02 17:45:00.556 |
Context
2016-08-02
| ||
18:50 | Add tests and fixes for vector operations that use sub-queries with different combinations of LIMIT, OFFSET and ORDER BY clauses. (check-in: 092b1c5ff5 user: dan tags: rowvalue) | |
17:45 | Fix SQLITE_OMIT_SUBQUERY builds. (check-in: 339f85f414 user: dan tags: rowvalue) | |
17:07 | Fix a problem with vector range constraints and mixed ASC/DESC indexes. (check-in: e2ad30c8b5 user: dan tags: rowvalue) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | if( sqlite3ExprIsVector(pExpr)==0 ) return 1; if( pExpr->flags & EP_xIsSelect ){ return pExpr->x.pSelect->pEList->nExpr; } return pExpr->x.pList->nExpr; } /* ** If the expression passed as the first argument is a TK_VECTOR, return ** a pointer to the i'th field of the vector. Or, if the first argument ** points to a sub-select that returns more than one column, return a ** pointer to the i'th returned column value. Otherwise, return a copy ** of the first argument. */ static Expr *exprVectorField(Expr *pVector, int i){ assert( i<sqlite3ExprVectorSize(pVector) ); if( sqlite3ExprIsVector(pVector) ){ if( pVector->op==TK_SELECT ){ return pVector->x.pSelect->pEList->a[i].pExpr; }else{ return pVector->x.pList->a[i].pExpr; } } return pVector; } /* ** If expression pExpr is of type TK_SELECT, generate code to evaluate ** it. Return the register in which the result is stored (or, if the ** sub-select returns more than one column, the first in an array ** of registers in which the result is stored). ** ** If pExpr is not a TK_SELECT expression, return 0. */ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ int reg = 0; if( pExpr->op==TK_SELECT ){ reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); } return reg; } /* ** Argument pVector points to a vector expression - either a TK_VECTOR ** or TK_SELECT that returns more than one column. This function returns ** the register number of a register that contains the value of | > > > > | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | if( sqlite3ExprIsVector(pExpr)==0 ) return 1; if( pExpr->flags & EP_xIsSelect ){ return pExpr->x.pSelect->pEList->nExpr; } return pExpr->x.pList->nExpr; } #ifndef SQLITE_OMIT_SUBQUERY /* ** If the expression passed as the first argument is a TK_VECTOR, return ** a pointer to the i'th field of the vector. Or, if the first argument ** points to a sub-select that returns more than one column, return a ** pointer to the i'th returned column value. Otherwise, return a copy ** of the first argument. */ static Expr *exprVectorField(Expr *pVector, int i){ assert( i<sqlite3ExprVectorSize(pVector) ); if( sqlite3ExprIsVector(pVector) ){ if( pVector->op==TK_SELECT ){ return pVector->x.pSelect->pEList->a[i].pExpr; }else{ return pVector->x.pList->a[i].pExpr; } } return pVector; } #endif /* ** If expression pExpr is of type TK_SELECT, generate code to evaluate ** it. Return the register in which the result is stored (or, if the ** sub-select returns more than one column, the first in an array ** of registers in which the result is stored). ** ** If pExpr is not a TK_SELECT expression, return 0. */ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ int reg = 0; #ifndef SQLITE_OMIT_SUBQUERY if( pExpr->op==TK_SELECT ){ reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); } #endif return reg; } /* ** Argument pVector points to a vector expression - either a TK_VECTOR ** or TK_SELECT that returns more than one column. This function returns ** the register number of a register that contains the value of |
︙ | ︙ | |||
1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 | ** address of the new instruction. */ int sqlite3CodeOnce(Parse *pParse){ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); } /* ** Generate code that checks the left-most column of index table iCur to see if ** it contains any NULL entries. Cause the register at regHasNull to be set ** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull ** to be set to NULL if iCur contains one or more NULL values. */ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ int addr1; sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); VdbeComment((v, "first_entry_in(%d)", iCur)); sqlite3VdbeJumpHere(v, addr1); } #ifndef SQLITE_OMIT_SUBQUERY /* ** The argument is an IN operator with a list (not a subquery) on the ** right-hand side. Return TRUE if that list is constant. */ | > > | 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 | ** address of the new instruction. */ int sqlite3CodeOnce(Parse *pParse){ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++); } #ifndef SQLITE_OMIT_SUBQUERY /* ** Generate code that checks the left-most column of index table iCur to see if ** it contains any NULL entries. Cause the register at regHasNull to be set ** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull ** to be set to NULL if iCur contains one or more NULL values. */ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ int addr1; sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); VdbeComment((v, "first_entry_in(%d)", iCur)); sqlite3VdbeJumpHere(v, addr1); } #endif #ifndef SQLITE_OMIT_SUBQUERY /* ** The argument is an IN operator with a list (not a subquery) on the ** right-hand side. Return TRUE if that list is constant. */ |
︙ | ︙ | |||
2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 | n = sqlite3ExprVectorSize(pX->pLeft); for(i=0; i<n; i++) aiMap[i] = i; } return eType; } #endif /* ** Argument pExpr is an (?, ?...) IN(...) expression. This ** function allocates and returns a nul-terminated string containing ** the affinities to be used for each column of the comparison. ** ** It is the responsibility of the caller to ensure that the returned ** string is eventually freed using sqlite3DbFree(). | > | 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 | n = sqlite3ExprVectorSize(pX->pLeft); for(i=0; i<n; i++) aiMap[i] = i; } return eType; } #endif #ifndef SQLITE_OMIT_SUBQUERY /* ** Argument pExpr is an (?, ?...) IN(...) expression. This ** function allocates and returns a nul-terminated string containing ** the affinities to be used for each column of the comparison. ** ** It is the responsibility of the caller to ensure that the returned ** string is eventually freed using sqlite3DbFree(). |
︙ | ︙ | |||
2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 | zRet[i] = a; } } zRet[nVal] = '\0'; } return zRet; } #ifndef SQLITE_OMIT_SUBQUERY /* ** Load the Parse object passed as the first argument with an error ** message of the form: ** ** "sub-select returns N columns - expected M" | > | 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 | zRet[i] = a; } } zRet[nVal] = '\0'; } return zRet; } #endif #ifndef SQLITE_OMIT_SUBQUERY /* ** Load the Parse object passed as the first argument with an error ** message of the form: ** ** "sub-select returns N columns - expected M" |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
3940 3941 3942 3943 3944 3945 3946 | void sqlite3Reindex(Parse*, Token*, Token*); void sqlite3AlterFunctions(void); void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*); int sqlite3CodeSubselect(Parse*, Expr *, int, int); | < | 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 | void sqlite3Reindex(Parse*, Token*, Token*); void sqlite3AlterFunctions(void); void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*); int sqlite3CodeSubselect(Parse*, Expr *, int, int); void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); int sqlite3ResolveExprNames(NameContext*, Expr*); int sqlite3ResolveExprListNames(NameContext*, ExprList*); void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); |
︙ | ︙ | |||
3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 | char *sqlite3StrAccumFinish(StrAccum*); void sqlite3StrAccumReset(StrAccum*); void sqlite3SelectDestInit(SelectDest*,int,int); Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); void sqlite3BackupRestart(sqlite3_backup *); void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 void sqlite3AnalyzeFunctions(void); int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); | > > > > > > | 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 | char *sqlite3StrAccumFinish(StrAccum*); void sqlite3StrAccumReset(StrAccum*); void sqlite3SelectDestInit(SelectDest*,int,int); Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); void sqlite3BackupRestart(sqlite3_backup *); 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*,u8,int,int*); int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); void sqlite3Stat4ProbeFree(UnpackedRecord*); int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); |
︙ | ︙ |
Changes to src/wherecode.c.
︙ | ︙ | |||
356 357 358 359 360 361 362 363 364 365 366 367 368 369 | Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ Expr *pRight = pX->pRight; if( pRight->op==TK_SELECT_COLUMN ){ /* This case occurs for expressions like "(a, b) == (SELECT ...)". */ WhereLoop *pLoop = pLevel->pWLoop; int i; Expr *pSub = pRight->pLeft; assert( pSub->op==TK_SELECT ); for(i=pLoop->nSkip; i<iEq; i++){ | > | 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | Vdbe *v = pParse->pVdbe; int iReg; /* Register holding results */ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ Expr *pRight = pX->pRight; #ifndef SQLITE_OMIT_SUBQUERY if( pRight->op==TK_SELECT_COLUMN ){ /* This case occurs for expressions like "(a, b) == (SELECT ...)". */ WhereLoop *pLoop = pLevel->pWLoop; int i; Expr *pSub = pRight->pLeft; assert( pSub->op==TK_SELECT ); for(i=pLoop->nSkip; i<iEq; i++){ |
︙ | ︙ | |||
377 378 379 380 381 382 383 | Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight; if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ){ sqlite3VdbeAddOp2(v, OP_Copy, iReg+pExpr->iColumn, iTarget-iEq+i); } } } iReg = iTarget; | | > > | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | Expr *pExpr = pLoop->aLTerm[i]->pExpr->pRight; if( pExpr && pExpr->op==TK_SELECT_COLUMN && pExpr->pLeft==pSub ){ sqlite3VdbeAddOp2(v, OP_Copy, iReg+pExpr->iColumn, iTarget-iEq+i); } } } iReg = iTarget; }else #endif { iReg = sqlite3ExprCodeTarget(pParse, pRight, iTarget); } }else if( pX->op==TK_ISNULL ){ iReg = iTarget; sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ |
︙ | ︙ | |||
958 959 960 961 962 963 964 | ** If the expression is not a vector, then nReg must be passed 1. In ** this case, generate code to evaluate the expression and leave the ** result in register iReg. */ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); if( sqlite3ExprIsVector(p) ){ | > > > > > > > > | < < < < < | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | ** If the expression is not a vector, then nReg must be passed 1. In ** this case, generate code to evaluate the expression and leave the ** result in register iReg. */ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); if( sqlite3ExprIsVector(p) ){ #ifndef SQLITE_OMIT_SUBQUERY if( (p->flags & EP_xIsSelect) ){ Vdbe *v = pParse->pVdbe; int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0); sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); }else #endif { int i; ExprList *pList = p->x.pList; assert( nReg<=pList->nExpr ); for(i=0; i<nReg; i++){ sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i); } } }else{ assert( nReg==1 ); sqlite3ExprCode(pParse, p, iReg); } } |
︙ | ︙ |