Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | New assert() statements to validate the parameters to sqlite3BtreeCursorHint(). Fix a problem with the construction of those parameters discovered by forum post 0b53708c95. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
4c5a3c5fb351cc1c2ce16c33314ce19c |
User & Date: | drh 2023-04-10 18:44:00 |
Context
2023-04-10
| ||
23:21 | For sha3 extension, mention NIST standard implemented. (check-in: 529ab138 user: larrybr tags: trunk) | |
18:44 | New assert() statements to validate the parameters to sqlite3BtreeCursorHint(). Fix a problem with the construction of those parameters discovered by forum post 0b53708c95. (check-in: 4c5a3c5f user: drh tags: trunk) | |
13:20 | Sync the vt02.c test virtual table with TH3, in order to pull in the fix for long delays when there are huge OFFSET values. (check-in: 49ba0300 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
942 943 944 945 946 947 948 | /* ** Provide hints to the cursor. The particular hint given (and the type ** and number of the varargs parameters) is determined by the eHintType ** parameter. See the definitions of the BTREE_HINT_* macros for details. */ void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ /* Used only by system that substitute their own storage engine */ | > > > > > > > > > > > > > > | | > > > | 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 | /* ** Provide hints to the cursor. The particular hint given (and the type ** and number of the varargs parameters) is determined by the eHintType ** parameter. See the definitions of the BTREE_HINT_* macros for details. */ void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ /* Used only by system that substitute their own storage engine */ #ifdef SQLITE_DEBUG if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){ va_list ap; Expr *pExpr; Walker w; memset(&w, 0, sizeof(w)); w.xExprCallback = sqlite3CursorRangeHintExprCheck; va_start(ap, eHintType); pExpr = va_arg(ap, Expr*); w.u.aMem = va_arg(ap, Mem*); va_end(ap); assert( pExpr!=0 ); assert( w.u.aMem!=0 ); sqlite3WalkExpr(&w, pExpr); } #endif /* SQLITE_DEBUG */ } #endif /* SQLITE_ENABLE_CURSOR_HINTS */ /* ** Provide flag hints to the cursor. */ void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); pCur->hints = x; |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 | struct WindowRewrite *pRewrite; /* Window rewrite context */ struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ SrcItem *pSrcItem; /* A single FROM clause item */ DbFixer *pFix; /* See sqlite3FixSelect() */ } u; }; /* ** The following structure contains information used by the sqliteFix... ** routines as they walk the parse tree to make database references ** explicit. | > | 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 | struct WindowRewrite *pRewrite; /* Window rewrite context */ struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ struct CoveringIndexCheck *pCovIdxCk; /* Check for covering index */ SrcItem *pSrcItem; /* A single FROM clause item */ DbFixer *pFix; /* See sqlite3FixSelect() */ Mem *aMem; /* See sqlite3BtreeCursorHint() */ } u; }; /* ** The following structure contains information used by the sqliteFix... ** routines as they walk the parse tree to make database references ** explicit. |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
398 399 400 401 402 403 404 405 406 | # define sqlite3VdbeScanStatusRange(a,b,c,d) # define sqlite3VdbeScanStatusCounters(a,b,c,d) #endif #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif #endif /* SQLITE_VDBE_H */ | > > > > | 398 399 400 401 402 403 404 405 406 407 408 409 410 | # define sqlite3VdbeScanStatusRange(a,b,c,d) # define sqlite3VdbeScanStatusCounters(a,b,c,d) #endif #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr); #endif #endif /* SQLITE_VDBE_H */ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 | pCtx->pFunc->zName, zContext); sqlite3_result_error(pCtx, zMsg, -1); sqlite3_free(zMsg); return 0; } return 1; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored ** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored ** in memory obtained from sqlite3DbMalloc). */ | > > > > > > > > > > > > > > | 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 | pCtx->pFunc->zName, zContext); sqlite3_result_error(pCtx, zMsg, -1); sqlite3_free(zMsg); return 0; } return 1; } #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) /* ** This Walker callback is used to help verify that calls to ** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have ** byte-code register values correctly initialized. */ int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_REGISTER ){ assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 ); } return WRC_Continue; } #endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored ** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored ** in memory obtained from sqlite3DbMalloc). */ |
︙ | ︙ |
Changes to src/wherecode.c.
︙ | ︙ | |||
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 | ** Also, if the node is a TK_COLUMN that does access the table idenified ** by pCCurHint.iTabCur, and an index is being used (which we will ** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into ** an access of the index rather than the original table. */ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; struct CCurHint *pHint = pWalker->u.pCCurHint; if( pExpr->op==TK_COLUMN ){ if( pExpr->iTable!=pHint->iTabCur ){ | > | | | < < < < < < < > > > > | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 | ** Also, if the node is a TK_COLUMN that does access the table idenified ** by pCCurHint.iTabCur, and an index is being used (which we will ** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into ** an access of the index rather than the original table. */ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; int reg; struct CCurHint *pHint = pWalker->u.pCCurHint; if( pExpr->op==TK_COLUMN ){ if( pExpr->iTable!=pHint->iTabCur ){ reg = ++pWalker->pParse->nMem; /* Register for column value */ reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ pExpr->iTable = pHint->iIdxCur; pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); assert( pExpr->iColumn>=0 ); } }else if( pExpr->pAggInfo ){ rc = WRC_Prune; reg = ++pWalker->pParse->nMem; /* Register for column value */ reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; } return rc; } /* ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ |
︙ | ︙ |
Changes to test/cursorhint.test.
︙ | ︙ | |||
175 176 177 178 179 180 181 182 183 | CREATE VIEW v2 AS SELECT 0 FROM v1 WHERE c1 IS '' OR c1 > ''; CREATE VIEW v3 AS SELECT 0 FROM v2 JOIN (v2 RIGHT JOIN v1); CREATE VIEW v4 AS SELECT 0 FROM v3, v3; SELECT * FROM v3 JOIN v3 AS a0, v4 AS a1, v4 AS a2, v3 AS a3, v3 AS a4, v4 AS a5 ORDER BY 1; } finish_test | > > > > > > > > > > > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | CREATE VIEW v2 AS SELECT 0 FROM v1 WHERE c1 IS '' OR c1 > ''; CREATE VIEW v3 AS SELECT 0 FROM v2 JOIN (v2 RIGHT JOIN v1); CREATE VIEW v4 AS SELECT 0 FROM v3, v3; SELECT * FROM v3 JOIN v3 AS a0, v4 AS a1, v4 AS a2, v3 AS a3, v3 AS a4, v4 AS a5 ORDER BY 1; } # 2023-04-10 https://sqlite.org/forum/forumpost/0b53708c95 # do_execsql_test 6.0 { CREATE TABLE t6(a TEXT UNIQUE, b TEXT); INSERT INTO t6(a,b) VALUES('uvw','xyz'),('abc','def'); WITH v1(a) AS (SELECT a COLLATE NOCASE FROM t6) SELECT v1.a, count(*) FROM t6 LEFT JOIN v1 ON true GROUP BY 1 HAVING (SELECT true FROM t6 AS aa LEFT JOIN t6 AS bb ON length(v1.a)>5); } {abc 2 uvw 2} finish_test |