Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update SQLite to the latest trunk code. Add managed virtual table support for the estimatedRows field. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | win32heap |
Files: | files | file ages | folders |
SHA1: |
dfa2a55bad2d1c8729a3caa66b83bada |
User & Date: | mistachkin 2013-11-11 20:41:07.272 |
Context
2013-11-11
| ||
20:51 | Merge all recent memory management (and other) enhancements to trunk. check-in: 8f8f493cbf user: mistachkin tags: trunk | |
20:41 | Update SQLite to the latest trunk code. Add managed virtual table support for the estimatedRows field. Closed-Leaf check-in: dfa2a55bad user: mistachkin tags: win32heap | |
02:18 | Update SQLite core library to the latest trunk code. Refer to the Win32-specific core library functions only when it is likely they will be available. check-in: 76131c4fc9 user: mistachkin tags: win32heap | |
Changes
Changes to SQLite.Interop/src/core/sqlite3.c.
︙ | ︙ | |||
133 134 135 136 137 138 139 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.2" #define SQLITE_VERSION_NUMBER 3008002 | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.2" #define SQLITE_VERSION_NUMBER 3008002 #define SQLITE_SOURCE_ID "2013-11-11 19:56:35 f58d57017199421167dae8ebc67db2f19be45082" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
5319 5320 5321 5322 5323 5324 5325 | ** ^[sqlite3_free()] is used to free idxPtr if and only if ** needToFreeIdxPtr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** | | > | > | | > > > > > > > > > > | 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 | ** ^[sqlite3_free()] is used to free idxPtr if and only if ** needToFreeIdxPtr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** ** ^The estimatedCost value is an estimate of the cost of a particular ** strategy. A cost of N indicates that the cost of the strategy is similar ** to a linear scan of an SQLite table with N rows. A cost of log(N) ** indicates that the expense of the operation is similar to that of a ** binary search on a unique indexed field of an SQLite table with N rows. ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info ** structure for SQLite version 3.8.2. If a virtual table extension is ** used with an SQLite version earlier than 3.8.2, the results of attempting ** to read or write the estimatedRows field are undefined (but are likely ** to included crashing the application). The estimatedRows field should ** therefore only be used if [sqlite3_libversion_number()] returns a ** value greater than or equal to 3008002. */ struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { int iColumn; /* Column on left-hand side of constraint */ unsigned char op; /* Constraint operator */ |
︙ | ︙ | |||
5347 5348 5349 5350 5351 5352 5353 | int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *aConstraintUsage; int idxNum; /* Number used to identify the index */ char *idxStr; /* String, possibly obtained from sqlite3_malloc */ int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ | | > | 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 | int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *aConstraintUsage; int idxNum; /* Number used to identify the index */ char *idxStr; /* String, possibly obtained from sqlite3_malloc */ int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ }; /* ** CAPI3REF: Virtual Table Constraint Operator Codes ** ** These macros defined the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents |
︙ | ︙ | |||
35292 35293 35294 35295 35296 35297 35298 | sqlite3_vfs *pVfs, /* Used to get maximum path name length */ const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ int flags, /* Open mode flags */ int *pOutFlags /* Status return flags */ ){ HANDLE h; | | | 35305 35306 35307 35308 35309 35310 35311 35312 35313 35314 35315 35316 35317 35318 35319 | sqlite3_vfs *pVfs, /* Used to get maximum path name length */ const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ int flags, /* Open mode flags */ int *pOutFlags /* Status return flags */ ){ HANDLE h; DWORD lastErrno = 0; DWORD dwDesiredAccess; DWORD dwShareMode; DWORD dwCreationDisposition; DWORD dwFlagsAndAttributes = 0; #if SQLITE_OS_WINCE int isTemp = 0; #endif |
︙ | ︙ | |||
35583 35584 35585 35586 35587 35588 35589 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ int cnt = 0; int rc; DWORD attr; | | | 35596 35597 35598 35599 35600 35601 35602 35603 35604 35605 35606 35607 35608 35609 35610 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ int cnt = 0; int rc; DWORD attr; DWORD lastErrno = 0; void *zConverted; UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(syncDir); SimulateIOError(return SQLITE_IOERR_DELETE); OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
︙ | ︙ | |||
35691 35692 35693 35694 35695 35696 35697 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ ){ DWORD attr; int rc = 0; | | | 35704 35705 35706 35707 35708 35709 35710 35711 35712 35713 35714 35715 35716 35717 35718 | sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ ){ DWORD attr; int rc = 0; DWORD lastErrno = 0; void *zConverted; UNUSED_PARAMETER(pVfs); SimulateIOError( return SQLITE_IOERR_ACCESS; ); OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", zFilename, flags, pResOut)); |
︙ | ︙ | |||
61440 61441 61442 61443 61444 61445 61446 | int i; VdbeOpList const *pIn = aOp; for(i=0; i<nOp; i++, pIn++){ int p2 = pIn->p2; VdbeOp *pOut = &p->aOp[i+addr]; pOut->opcode = pIn->opcode; pOut->p1 = pIn->p1; | > | | 61453 61454 61455 61456 61457 61458 61459 61460 61461 61462 61463 61464 61465 61466 61467 61468 | int i; VdbeOpList const *pIn = aOp; for(i=0; i<nOp; i++, pIn++){ int p2 = pIn->p2; VdbeOp *pOut = &p->aOp[i+addr]; pOut->opcode = pIn->opcode; pOut->p1 = pIn->p1; if( p2<0 ){ assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP ); pOut->p2 = addr + ADDR(p2); }else{ pOut->p2 = p2; } pOut->p3 = pIn->p3; pOut->p4type = P4_NOTUSED; pOut->p4.p = 0; |
︙ | ︙ | |||
67324 67325 67326 67327 67328 67329 67330 67331 67332 67333 67334 67335 67336 | testcase( pOp->p5==2 ); testcase( pOp->p5==3 ); testcase( pOp->p5==4 ); u.ab.zType = azType[pOp->p5-1]; }else{ u.ab.zType = 0; } u.ab.zLogFmt = "abort at %d in [%s]: %s"; if( u.ab.zType && pOp->p4.z ){ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s", u.ab.zType, pOp->p4.z); }else if( pOp->p4.z ){ sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); | > | < < | 67338 67339 67340 67341 67342 67343 67344 67345 67346 67347 67348 67349 67350 67351 67352 67353 67354 67355 67356 67357 67358 67359 67360 | testcase( pOp->p5==2 ); testcase( pOp->p5==3 ); testcase( pOp->p5==4 ); u.ab.zType = azType[pOp->p5-1]; }else{ u.ab.zType = 0; } assert( u.ab.zType!=0 || pOp->p4.z!=0 ); u.ab.zLogFmt = "abort at %d in [%s]: %s"; if( u.ab.zType && pOp->p4.z ){ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s", u.ab.zType, pOp->p4.z); }else if( pOp->p4.z ){ sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); }else{ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", u.ab.zType); } sqlite3_log(pOp->p1, u.ab.zLogFmt, pc, p->zSql, p->zErrMsg); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); if( rc==SQLITE_BUSY ){ p->rc = rc = SQLITE_BUSY; |
︙ | ︙ | |||
68773 68774 68775 68776 68777 68778 68779 | assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 ); u.ap.payloadSize = (u32)u.ap.payloadSize64; }else{ assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) ); VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.payloadSize); assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ } | > | < < < | 68786 68787 68788 68789 68790 68791 68792 68793 68794 68795 68796 68797 68798 68799 68800 68801 68802 68803 68804 68805 68806 68807 68808 68809 68810 68811 68812 68813 | assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 ); u.ap.payloadSize = (u32)u.ap.payloadSize64; }else{ assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) ); VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.payloadSize); assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ } }else{ assert( u.ap.pC->pseudoTableReg>0 ); u.ap.pReg = &aMem[u.ap.pC->pseudoTableReg]; if( u.ap.pC->multiPseudo ){ sqlite3VdbeMemShallowCopy(u.ap.pDest, u.ap.pReg+u.ap.p2, MEM_Ephem); Deephemeralize(u.ap.pDest); goto op_column_out; } assert( u.ap.pReg->flags & MEM_Blob ); assert( memIsValid(u.ap.pReg) ); u.ap.payloadSize = u.ap.pReg->n; u.ap.zRec = u.ap.pReg->z; u.ap.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; assert( u.ap.payloadSize==0 || u.ap.zRec!=0 ); } /* If u.ap.payloadSize is 0, then just store a NULL. This can happen because of ** nullRow or because of a corrupt database. */ if( u.ap.payloadSize==0 ){ MemSetTypeFlag(u.ap.pDest, MEM_Null); goto op_column_out; |
︙ | ︙ | |||
69186 69187 69188 69189 69190 69191 69192 | case OP_Count: { /* out2-prerelease */ #if 0 /* local variables moved into u.as */ i64 nEntry; BtCursor *pCrsr; #endif /* local variables moved into u.as */ u.as.pCrsr = p->apCsr[pOp->p1]->pCursor; | | | < < < | 69197 69198 69199 69200 69201 69202 69203 69204 69205 69206 69207 69208 69209 69210 69211 69212 | case OP_Count: { /* out2-prerelease */ #if 0 /* local variables moved into u.as */ i64 nEntry; BtCursor *pCrsr; #endif /* local variables moved into u.as */ u.as.pCrsr = p->apCsr[pOp->p1]->pCursor; assert( u.as.pCrsr ); rc = sqlite3BtreeCount(u.as.pCrsr, &u.as.nEntry); pOut->u.i = u.as.nEntry; break; } #endif /* Opcode: Savepoint P1 * * P4 * ** |
︙ | ︙ | |||
70023 70024 70025 70026 70027 70028 70029 | u.bd.pC = p->apCsr[pOp->p1]; assert( u.bd.pC!=0 ); assert( u.bd.pC->pseudoTableReg==0 ); assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGt == OP_SeekLt+3 ); assert( u.bd.pC->isOrdered ); | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < < < < | 70031 70032 70033 70034 70035 70036 70037 70038 70039 70040 70041 70042 70043 70044 70045 70046 70047 70048 70049 70050 70051 70052 70053 70054 70055 70056 70057 70058 70059 70060 70061 70062 70063 70064 70065 70066 70067 70068 70069 70070 70071 70072 70073 70074 70075 70076 70077 70078 70079 70080 70081 70082 70083 70084 70085 70086 70087 70088 70089 70090 70091 70092 70093 70094 70095 70096 70097 70098 70099 70100 70101 70102 70103 70104 70105 70106 70107 70108 70109 70110 70111 70112 70113 70114 70115 70116 70117 70118 70119 70120 70121 70122 70123 70124 70125 70126 70127 70128 70129 70130 70131 70132 70133 70134 70135 70136 70137 70138 70139 70140 70141 70142 70143 70144 70145 70146 70147 70148 70149 70150 70151 70152 70153 70154 70155 70156 70157 70158 70159 70160 70161 70162 70163 70164 | u.bd.pC = p->apCsr[pOp->p1]; assert( u.bd.pC!=0 ); assert( u.bd.pC->pseudoTableReg==0 ); assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGt == OP_SeekLt+3 ); assert( u.bd.pC->isOrdered ); assert( u.bd.pC->pCursor!=0 ); u.bd.oc = pOp->opcode; u.bd.pC->nullRow = 0; if( u.bd.pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ pIn3 = &aMem[pOp->p3]; applyNumericAffinity(pIn3); u.bd.iKey = sqlite3VdbeIntValue(pIn3); u.bd.pC->rowidIsValid = 0; /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ if( (pIn3->flags & MEM_Int)==0 ){ if( (pIn3->flags & MEM_Real)==0 ){ /* If the P3 value cannot be converted into any kind of a number, ** then the seek is not possible, so jump to P2 */ pc = pOp->p2 - 1; break; } /* If we reach this point, then the P3 value must be a floating ** point number. */ assert( (pIn3->flags & MEM_Real)!=0 ); if( u.bd.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bd.iKey || pIn3->r>0) ){ /* The P3 value is too large in magnitude to be expressed as an ** integer. */ u.bd.res = 1; if( pIn3->r<0 ){ if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt ); rc = sqlite3BtreeFirst(u.bd.pC->pCursor, &u.bd.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } }else{ if( u.bd.oc<=OP_SeekLe ){ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe ); rc = sqlite3BtreeLast(u.bd.pC->pCursor, &u.bd.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } if( u.bd.res ){ pc = pOp->p2 - 1; } break; }else if( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekGe ){ /* Use the ceiling() function to convert real->int */ if( pIn3->r > (double)u.bd.iKey ) u.bd.iKey++; }else{ /* Use the floor() function to convert real->int */ assert( u.bd.oc==OP_SeekLe || u.bd.oc==OP_SeekGt ); if( pIn3->r < (double)u.bd.iKey ) u.bd.iKey--; } } rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } if( u.bd.res==0 ){ u.bd.pC->rowidIsValid = 1; u.bd.pC->lastRowid = u.bd.iKey; } }else{ u.bd.nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); assert( u.bd.nField>0 ); u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo; u.bd.r.nField = (u16)u.bd.nField; /* The next line of code computes as follows, only faster: ** if( u.bd.oc==OP_SeekGt || u.bd.oc==OP_SeekLe ){ ** u.bd.r.flags = UNPACKED_INCRKEY; ** }else{ ** u.bd.r.flags = 0; ** } */ u.bd.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bd.oc - OP_SeekLt))); assert( u.bd.oc!=OP_SeekGt || u.bd.r.flags==UNPACKED_INCRKEY ); assert( u.bd.oc!=OP_SeekLe || u.bd.r.flags==UNPACKED_INCRKEY ); assert( u.bd.oc!=OP_SeekGe || u.bd.r.flags==0 ); assert( u.bd.oc!=OP_SeekLt || u.bd.r.flags==0 ); u.bd.r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); } #endif ExpandBlob(u.bd.r.aMem); rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, &u.bd.r, 0, 0, &u.bd.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } u.bd.pC->rowidIsValid = 0; } u.bd.pC->deferredMoveto = 0; u.bd.pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt ); if( u.bd.res<0 || (u.bd.res==0 && u.bd.oc==OP_SeekGt) ){ rc = sqlite3BtreeNext(u.bd.pC->pCursor, &u.bd.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; u.bd.pC->rowidIsValid = 0; }else{ u.bd.res = 0; } }else{ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe ); if( u.bd.res>0 || (u.bd.res==0 && u.bd.oc==OP_SeekLt) ){ rc = sqlite3BtreePrevious(u.bd.pC->pCursor, &u.bd.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; u.bd.pC->rowidIsValid = 0; }else{ /* u.bd.res might be negative because the table is empty. Check to ** see if this is the case. */ u.bd.res = sqlite3BtreeEof(u.bd.pC->pCursor); } } assert( pOp->p2>0 ); if( u.bd.res ){ pc = pOp->p2 - 1; } break; } /* Opcode: Seek P1 P2 * * * ** Synopsis: intkey=r[P2] |
︙ | ︙ | |||
70173 70174 70175 70176 70177 70178 70179 | #if 0 /* local variables moved into u.be */ VdbeCursor *pC; #endif /* local variables moved into u.be */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.be.pC = p->apCsr[pOp->p1]; assert( u.be.pC!=0 ); | | | | | | | | < | 70174 70175 70176 70177 70178 70179 70180 70181 70182 70183 70184 70185 70186 70187 70188 70189 70190 70191 70192 70193 70194 | #if 0 /* local variables moved into u.be */ VdbeCursor *pC; #endif /* local variables moved into u.be */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.be.pC = p->apCsr[pOp->p1]; assert( u.be.pC!=0 ); assert( u.be.pC->pCursor!=0 ); assert( u.be.pC->isTable ); u.be.pC->nullRow = 0; pIn2 = &aMem[pOp->p2]; u.be.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); u.be.pC->rowidIsValid = 0; u.be.pC->deferredMoveto = 1; break; } /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** |
︙ | ︙ | |||
70256 70257 70258 70259 70260 70261 70262 | u.bf.alreadyExists = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p4type==P4_INT32 ); u.bf.pC = p->apCsr[pOp->p1]; assert( u.bf.pC!=0 ); pIn3 = &aMem[pOp->p3]; | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | 70256 70257 70258 70259 70260 70261 70262 70263 70264 70265 70266 70267 70268 70269 70270 70271 70272 70273 70274 70275 70276 70277 70278 70279 70280 70281 70282 70283 70284 70285 70286 70287 70288 70289 70290 70291 70292 70293 70294 70295 70296 70297 70298 70299 70300 70301 70302 70303 70304 70305 70306 70307 70308 70309 70310 70311 70312 70313 70314 70315 70316 70317 70318 70319 | u.bf.alreadyExists = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p4type==P4_INT32 ); u.bf.pC = p->apCsr[pOp->p1]; assert( u.bf.pC!=0 ); pIn3 = &aMem[pOp->p3]; assert( u.bf.pC->pCursor!=0 ); assert( u.bf.pC->isTable==0 ); if( pOp->p4.i>0 ){ u.bf.r.pKeyInfo = u.bf.pC->pKeyInfo; u.bf.r.nField = (u16)pOp->p4.i; u.bf.r.aMem = pIn3; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.bf.r.nField; i++){ assert( memIsValid(&u.bf.r.aMem[i]) ); if( i ) REGISTER_TRACE(pOp->p3+i, &u.bf.r.aMem[i]); } } #endif u.bf.r.flags = UNPACKED_PREFIX_MATCH; u.bf.pIdxKey = &u.bf.r; }else{ u.bf.pIdxKey = sqlite3VdbeAllocUnpackedRecord( u.bf.pC->pKeyInfo, u.bf.aTempRec, sizeof(u.bf.aTempRec), &u.bf.pFree ); if( u.bf.pIdxKey==0 ) goto no_mem; assert( pIn3->flags & MEM_Blob ); assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */ sqlite3VdbeRecordUnpack(u.bf.pC->pKeyInfo, pIn3->n, pIn3->z, u.bf.pIdxKey); u.bf.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; } if( pOp->opcode==OP_NoConflict ){ /* For the OP_NoConflict opcode, take the jump if any of the ** input fields are NULL, since any key with a NULL will not ** conflict */ for(u.bf.ii=0; u.bf.ii<u.bf.r.nField; u.bf.ii++){ if( u.bf.r.aMem[u.bf.ii].flags & MEM_Null ){ pc = pOp->p2 - 1; break; } } } rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, u.bf.pIdxKey, 0, 0, &u.bf.res); if( pOp->p4.i==0 ){ sqlite3DbFree(db, u.bf.pFree); } if( rc!=SQLITE_OK ){ break; } u.bf.pC->seekResult = u.bf.res; u.bf.alreadyExists = (u.bf.res==0); u.bf.pC->nullRow = 1-u.bf.alreadyExists; u.bf.pC->deferredMoveto = 0; u.bf.pC->cacheStatus = CACHE_STALE; if( pOp->opcode==OP_Found ){ if( u.bf.alreadyExists ) pc = pOp->p2 - 1; }else{ if( !u.bf.alreadyExists ) pc = pOp->p2 - 1; } break; } |
︙ | ︙ | |||
70346 70347 70348 70349 70350 70351 70352 | assert( pIn3->flags & MEM_Int ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bg.pC = p->apCsr[pOp->p1]; assert( u.bg.pC!=0 ); assert( u.bg.pC->isTable ); assert( u.bg.pC->pseudoTableReg==0 ); u.bg.pCrsr = u.bg.pC->pCursor; | | | | | | | | | | | | | | | < < < < < < < < | 70344 70345 70346 70347 70348 70349 70350 70351 70352 70353 70354 70355 70356 70357 70358 70359 70360 70361 70362 70363 70364 70365 70366 70367 70368 70369 70370 70371 | assert( pIn3->flags & MEM_Int ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bg.pC = p->apCsr[pOp->p1]; assert( u.bg.pC!=0 ); assert( u.bg.pC->isTable ); assert( u.bg.pC->pseudoTableReg==0 ); u.bg.pCrsr = u.bg.pC->pCursor; assert( u.bg.pCrsr!=0 ); u.bg.res = 0; u.bg.iKey = pIn3->u.i; rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res); u.bg.pC->lastRowid = pIn3->u.i; u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0; u.bg.pC->nullRow = 0; u.bg.pC->cacheStatus = CACHE_STALE; u.bg.pC->deferredMoveto = 0; if( u.bg.res!=0 ){ pc = pOp->p2 - 1; assert( u.bg.pC->rowidIsValid==0 ); } u.bg.pC->seekResult = u.bg.res; break; } /* Opcode: Sequence P1 P2 * * * ** Synopsis: r[P2]=rowid ** ** Find the next available sequence number for cursor P1. |
︙ | ︙ | |||
70965 70966 70967 70968 70969 70970 70971 | #endif /* local variables moved into u.bp */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bp.pC = p->apCsr[pOp->p1]; assert( u.bp.pC!=0 ); u.bp.pCrsr = u.bp.pC->pCursor; u.bp.res = 0; | | | < | 70955 70956 70957 70958 70959 70960 70961 70962 70963 70964 70965 70966 70967 70968 70969 70970 | #endif /* local variables moved into u.bp */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bp.pC = p->apCsr[pOp->p1]; assert( u.bp.pC!=0 ); u.bp.pCrsr = u.bp.pC->pCursor; u.bp.res = 0; assert( u.bp.pCrsr!=0 ); rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res); u.bp.pC->nullRow = (u8)u.bp.res; u.bp.pC->deferredMoveto = 0; u.bp.pC->rowidIsValid = 0; u.bp.pC->cacheStatus = CACHE_STALE; if( pOp->p2>0 && u.bp.res ){ pc = pOp->p2 - 1; } |
︙ | ︙ | |||
71140 71141 71142 71143 71144 71145 71146 | u.bs.pC = p->apCsr[pOp->p1]; assert( u.bs.pC!=0 ); assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); u.bs.pCrsr = u.bs.pC->pCursor; if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; | | | | | | | | | | | | | | | < | < | > | | | | | | | | | | | < | 71129 71130 71131 71132 71133 71134 71135 71136 71137 71138 71139 71140 71141 71142 71143 71144 71145 71146 71147 71148 71149 71150 71151 71152 71153 71154 71155 71156 71157 71158 71159 71160 71161 71162 71163 71164 71165 71166 71167 71168 71169 71170 71171 71172 71173 71174 71175 71176 71177 71178 71179 71180 71181 71182 71183 71184 71185 71186 71187 71188 71189 71190 71191 71192 71193 71194 71195 71196 71197 | u.bs.pC = p->apCsr[pOp->p1]; assert( u.bs.pC!=0 ); assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) ); pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); u.bs.pCrsr = u.bs.pC->pCursor; if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; assert( u.bs.pCrsr!=0 ); assert( u.bs.pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ if( isSorter(u.bs.pC) ){ rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2); }else{ u.bs.nKey = pIn2->n; u.bs.zKey = pIn2->z; rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0) ); assert( u.bs.pC->deferredMoveto==0 ); u.bs.pC->cacheStatus = CACHE_STALE; } } break; } /* Opcode: IdxDelete P1 P2 P3 * * ** Synopsis: key=r[P2@P3] ** ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { #if 0 /* local variables moved into u.bt */ VdbeCursor *pC; BtCursor *pCrsr; int res; UnpackedRecord r; #endif /* local variables moved into u.bt */ assert( pOp->p3>0 ); assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bt.pC = p->apCsr[pOp->p1]; assert( u.bt.pC!=0 ); u.bt.pCrsr = u.bt.pC->pCursor; assert( u.bt.pCrsr!=0 ); assert( pOp->p5==0 ); u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; u.bt.r.nField = (u16)pOp->p3; u.bt.r.flags = UNPACKED_PREFIX_MATCH; u.bt.r.aMem = &aMem[pOp->p2]; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); } #endif rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res); if( rc==SQLITE_OK && u.bt.res==0 ){ rc = sqlite3BtreeDelete(u.bt.pCrsr); } assert( u.bt.pC->deferredMoveto==0 ); u.bt.pC->cacheStatus = CACHE_STALE; break; } /* Opcode: IdxRowid P1 P2 * * * ** Synopsis: r[P2]=rowid ** ** Write into register P2 an integer which is the last entry in the record at |
︙ | ︙ | |||
71220 71221 71222 71223 71224 71225 71226 71227 | i64 rowid; #endif /* local variables moved into u.bu */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bu.pC = p->apCsr[pOp->p1]; assert( u.bu.pC!=0 ); u.bu.pCrsr = u.bu.pC->pCursor; pOut->flags = MEM_Null; | > < | | | | | | | | | | | < | 71207 71208 71209 71210 71211 71212 71213 71214 71215 71216 71217 71218 71219 71220 71221 71222 71223 71224 71225 71226 71227 71228 71229 71230 71231 71232 71233 | i64 rowid; #endif /* local variables moved into u.bu */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bu.pC = p->apCsr[pOp->p1]; assert( u.bu.pC!=0 ); u.bu.pCrsr = u.bu.pC->pCursor; assert( u.bu.pCrsr!=0 ); pOut->flags = MEM_Null; rc = sqlite3VdbeCursorMoveto(u.bu.pC); if( NEVER(rc) ) goto abort_due_to_error; assert( u.bu.pC->deferredMoveto==0 ); assert( u.bu.pC->isTable==0 ); if( !u.bu.pC->nullRow ){ rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pOut->u.i = u.bu.rowid; pOut->flags = MEM_Int; } break; } /* Opcode: IdxGE P1 P2 P3 P4 P5 ** Synopsis: key=r[P3@P4] ** |
︙ | ︙ | |||
71278 71279 71280 71281 71282 71283 71284 | UnpackedRecord r; #endif /* local variables moved into u.bv */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bv.pC = p->apCsr[pOp->p1]; assert( u.bv.pC!=0 ); assert( u.bv.pC->isOrdered ); | | | | | | | | | | | | | | | | | | | | | | | < | 71264 71265 71266 71267 71268 71269 71270 71271 71272 71273 71274 71275 71276 71277 71278 71279 71280 71281 71282 71283 71284 71285 71286 71287 71288 71289 71290 71291 71292 71293 71294 71295 71296 71297 71298 71299 71300 71301 | UnpackedRecord r; #endif /* local variables moved into u.bv */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); u.bv.pC = p->apCsr[pOp->p1]; assert( u.bv.pC!=0 ); assert( u.bv.pC->isOrdered ); assert( u.bv.pC->pCursor!=0); assert( u.bv.pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo; u.bv.r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH; }else{ u.bv.r.flags = UNPACKED_PREFIX_MATCH; } u.bv.r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); } #endif rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res); if( pOp->opcode==OP_IdxLT ){ u.bv.res = -u.bv.res; }else{ assert( pOp->opcode==OP_IdxGE ); u.bv.res++; } if( u.bv.res>0 ){ pc = pOp->p2 - 1 ; } break; } /* Opcode: Destroy P1 P2 P3 * * ** ** Delete an entire database table or index whose root page in the database |
︙ | ︙ | |||
88450 88451 88452 88453 88454 88455 88456 | }else{ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ assert( sqlite3KeyInfoIsWriteable(pKey) ); for(i=0; i<nCol; i++){ char *zColl = pIdx->azColl[i]; | | | 88435 88436 88437 88438 88439 88440 88441 88442 88443 88444 88445 88446 88447 88448 88449 | }else{ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ assert( sqlite3KeyInfoIsWriteable(pKey) ); for(i=0; i<nCol; i++){ char *zColl = pIdx->azColl[i]; if( NEVER(zColl==0) ) zColl = "BINARY"; pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl); pKey->aSortOrder[i] = pIdx->aSortOrder[i]; } if( pParse->nErr ){ sqlite3KeyInfoUnref(pKey); }else{ pIdx->pKeyInfo = pKey; |
︙ | ︙ | |||
94375 94376 94377 94378 94379 94380 94381 | if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); } if( ipkTop ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1); sqlite3VdbeJumpHere(v, ipkBottom); } | < | < | 94360 94361 94362 94363 94364 94365 94366 94367 94368 94369 94370 94371 94372 94373 94374 | if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); } if( ipkTop ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1); sqlite3VdbeJumpHere(v, ipkBottom); } *pbMayReplace = seenReplace; VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); } /* ** This routine generates code to finish the INSERT or UPDATE operation ** that was started by a prior call to sqlite3GenerateConstraintChecks. ** A consecutive range of registers starting at regNewData contains the |
︙ | ︙ | |||
94419 94420 94421 94422 94423 94424 94425 | if( aRegIdx[i]==0 ) continue; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); pik_flags = 0; if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; | | > | 94402 94403 94404 94405 94406 94407 94408 94409 94410 94411 94412 94413 94414 94415 94416 94417 | if( aRegIdx[i]==0 ) continue; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); pik_flags = 0; if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; if( pIdx->autoIndex==2 && !HasRowid(pTab) ){ assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; } if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; regData = regNewData + 1; regRec = sqlite3GetTempReg(pParse); |
︙ | ︙ | |||
106088 106089 106090 106091 106092 106093 106094 | } } } for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iThisCur = iIdxCur+i; assert( aRegIdx ); if( (openAll || aRegIdx[i]>0) | < > | 106072 106073 106074 106075 106076 106077 106078 106079 106080 106081 106082 106083 106084 106085 106086 106087 106088 | } } } for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iThisCur = iIdxCur+i; assert( aRegIdx ); if( (openAll || aRegIdx[i]>0) && iThisCur!=aiCurOnePass[1] ){ assert( iThisCur!=aiCurOnePass[0] ); sqlite3VdbeAddOp3(v, OP_OpenWrite, iThisCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); assert( pParse->nTab>iThisCur ); VdbeComment((v, "%s", pIdx->zName)); if( okOnePass && pPk && iThisCur==iDataCur ){ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); |
︙ | ︙ | |||
109886 109887 109888 109889 109890 109891 109892 109893 109894 109895 109896 109897 109898 109899 | p->aConstraintUsage[i].argvIndex, p->aConstraintUsage[i].omit); } sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); } #else #define TRACE_IDX_INPUTS(A) #define TRACE_IDX_OUTPUTS(A) #endif #ifndef SQLITE_OMIT_AUTOMATIC_INDEX | > | 109870 109871 109872 109873 109874 109875 109876 109877 109878 109879 109880 109881 109882 109883 109884 | p->aConstraintUsage[i].argvIndex, p->aConstraintUsage[i].omit); } sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); } #else #define TRACE_IDX_INPUTS(A) #define TRACE_IDX_OUTPUTS(A) #endif #ifndef SQLITE_OMIT_AUTOMATIC_INDEX |
︙ | ︙ | |||
112695 112696 112697 112698 112699 112700 112701 112702 112703 112704 112705 112706 112707 112708 | memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr); pIdxInfo->idxStr = 0; pIdxInfo->idxNum = 0; pIdxInfo->needToFreeIdxStr = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; rc = vtabBestIndex(pParse, pTab, pIdxInfo); if( rc ) goto whereLoopAddVtab_exit; pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; pNew->prereq = 0; mxTerm = -1; assert( pNew->nLSlot>=nConstraint ); for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0; | > | 112680 112681 112682 112683 112684 112685 112686 112687 112688 112689 112690 112691 112692 112693 112694 | memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr); pIdxInfo->idxStr = 0; pIdxInfo->idxNum = 0; pIdxInfo->needToFreeIdxStr = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; rc = vtabBestIndex(pParse, pTab, pIdxInfo); if( rc ) goto whereLoopAddVtab_exit; pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; pNew->prereq = 0; mxTerm = -1; assert( pNew->nLSlot>=nConstraint ); for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0; |
︙ | ︙ | |||
112754 112755 112756 112757 112758 112759 112760 | pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; pIdxInfo->needToFreeIdxStr = 0; pNew->u.vtab.idxStr = pIdxInfo->idxStr; pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0) && pIdxInfo->orderByConsumed); pNew->rSetup = 0; pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); | < | | 112740 112741 112742 112743 112744 112745 112746 112747 112748 112749 112750 112751 112752 112753 112754 | pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; pIdxInfo->needToFreeIdxStr = 0; pNew->u.vtab.idxStr = pIdxInfo->idxStr; pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0) && pIdxInfo->orderByConsumed); pNew->rSetup = 0; pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); whereLoopInsert(pBuilder, pNew); if( pNew->u.vtab.needFree ){ sqlite3_free(pNew->u.vtab.idxStr); pNew->u.vtab.needFree = 0; } } } |
︙ | ︙ | |||
113975 113976 113977 113978 113979 113980 113981 | }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } if( pLoop->wsFlags & WHERE_INDEXED ){ Index *pIx = pLoop->u.btree.pIndex; int iIndexCur; int op = OP_OpenRead; | > > | | 113960 113961 113962 113963 113964 113965 113966 113967 113968 113969 113970 113971 113972 113973 113974 113975 113976 | }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } if( pLoop->wsFlags & WHERE_INDEXED ){ Index *pIx = pLoop->u.btree.pIndex; int iIndexCur; int op = OP_OpenRead; /* iIdxCur is always set if to a positive value if ONEPASS is possible */ assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 ); if( pWInfo->okOnePass ){ Index *pJ = pTabItem->pTab->pIndex; iIndexCur = iIdxCur; assert( wctrlFlags & WHERE_ONEPASS_DESIRED ); while( ALWAYS(pJ) && pJ!=pIx ){ iIndexCur++; pJ = pJ->pNext; } |
︙ | ︙ | |||
141053 141054 141055 141056 141057 141058 141059 141060 141061 141062 141063 141064 141065 141066 141067 141068 141069 141070 141071 141072 141073 141074 141075 141076 141077 141078 141079 141080 | /* Size of hash table Rtree.aHash. This hash table is not expected to ** ever contain very many entries, so a fixed number of buckets is ** used. */ #define HASHSIZE 128 /* ** An rtree virtual-table object. */ struct Rtree { sqlite3_vtab base; sqlite3 *db; /* Host database connection */ int iNodeSize; /* Size in bytes of each node in the node table */ int nDim; /* Number of dimensions */ int nBytesPerCell; /* Bytes consumed per cell */ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ int nBusy; /* Current number of users of this structure */ /* List of nodes removed during a CondenseTree operation. List is ** linked together via the pointer normally used for hash chains - ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree ** headed by the node (leaf nodes have RtreeNode.iNode==0). */ RtreeNode *pDeleted; | > > > > > > > > > > > | 141040 141041 141042 141043 141044 141045 141046 141047 141048 141049 141050 141051 141052 141053 141054 141055 141056 141057 141058 141059 141060 141061 141062 141063 141064 141065 141066 141067 141068 141069 141070 141071 141072 141073 141074 141075 141076 141077 141078 | /* Size of hash table Rtree.aHash. This hash table is not expected to ** ever contain very many entries, so a fixed number of buckets is ** used. */ #define HASHSIZE 128 /* The xBestIndex method of this virtual table requires an estimate of ** the number of rows in the virtual table to calculate the costs of ** various strategies. If possible, this estimate is loaded from the ** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum). ** Otherwise, if no sqlite_stat1 entry is available, use ** RTREE_DEFAULT_ROWEST. */ #define RTREE_DEFAULT_ROWEST 1048576 #define RTREE_MIN_ROWEST 100 /* ** An rtree virtual-table object. */ struct Rtree { sqlite3_vtab base; sqlite3 *db; /* Host database connection */ int iNodeSize; /* Size in bytes of each node in the node table */ int nDim; /* Number of dimensions */ int nBytesPerCell; /* Bytes consumed per cell */ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ int nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ /* List of nodes removed during a CondenseTree operation. List is ** linked together via the pointer normally used for hash chains - ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree ** headed by the node (leaf nodes have RtreeNode.iNode==0). */ RtreeNode *pDeleted; |
︙ | ︙ | |||
142258 142259 142260 142261 142262 142263 142264 142265 142266 142267 142268 142269 142270 142271 | assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) ); } } rtreeRelease(pRtree); return rc; } /* ** Rtree virtual table module xBestIndex method. There are three ** table scan strategies to choose from (in order from most to ** least desirable): ** ** idxNum idxStr Strategy | > > > > > > > > > > > > > | 142256 142257 142258 142259 142260 142261 142262 142263 142264 142265 142266 142267 142268 142269 142270 142271 142272 142273 142274 142275 142276 142277 142278 142279 142280 142281 142282 | assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) ); } } rtreeRelease(pRtree); return rc; } /* ** Set the pIdxInfo->estimatedRows variable to nRow. Unless this ** extension is currently being used by a version of SQLite too old to ** support estimatedRows. In that case this function is a no-op. */ static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ #if SQLITE_VERSION_NUMBER>=3008002 if( sqlite3_libversion_number()>=3008002 ){ pIdxInfo->estimatedRows = nRow; } #endif } /* ** Rtree virtual table module xBestIndex method. There are three ** table scan strategies to choose from (in order from most to ** least desirable): ** ** idxNum idxStr Strategy |
︙ | ︙ | |||
142294 142295 142296 142297 142298 142299 142300 142301 142302 142303 142304 142305 142306 | ** ---------------------- ** ** The second of each pair of bytes identifies the coordinate column ** to which the constraint applies. The leftmost coordinate column ** is 'a', the second from the left 'b' etc. */ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int rc = SQLITE_OK; int ii; int iIdx = 0; char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; memset(zIdxStr, 0, sizeof(zIdxStr)); | > > < | > | > | 142305 142306 142307 142308 142309 142310 142311 142312 142313 142314 142315 142316 142317 142318 142319 142320 142321 142322 142323 142324 142325 142326 142327 142328 142329 142330 142331 142332 142333 142334 142335 142336 142337 142338 142339 142340 142341 142342 142343 142344 142345 142346 142347 142348 142349 142350 | ** ---------------------- ** ** The second of each pair of bytes identifies the coordinate column ** to which the constraint applies. The leftmost coordinate column ** is 'a', the second from the left 'b' etc. */ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ Rtree *pRtree = (Rtree*)tab; int rc = SQLITE_OK; int ii; i64 nRow; /* Estimated rows returned by this scan */ int iIdx = 0; char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; memset(zIdxStr, 0, sizeof(zIdxStr)); assert( pIdxInfo->idxStr==0 ); for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ /* We have an equality constraint on the rowid. Use strategy 1. */ int jj; for(jj=0; jj<ii; jj++){ pIdxInfo->aConstraintUsage[jj].argvIndex = 0; pIdxInfo->aConstraintUsage[jj].omit = 0; } pIdxInfo->idxNum = 1; pIdxInfo->aConstraintUsage[ii].argvIndex = 1; pIdxInfo->aConstraintUsage[jj].omit = 1; /* This strategy involves a two rowid lookups on an B-Tree structures ** and then a linear search of an R-Tree node. This should be ** considered almost as quick as a direct rowid lookup (for which ** sqlite uses an internal cost of 0.0). It is expected to return ** a single row. */ pIdxInfo->estimatedCost = 30.0; setEstimatedRows(pIdxInfo, 1); return SQLITE_OK; } if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ u8 op; switch( p->op ){ case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; |
︙ | ︙ | |||
142351 142352 142353 142354 142355 142356 142357 | } pIdxInfo->idxNum = 2; pIdxInfo->needToFreeIdxStr = 1; if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ return SQLITE_NOMEM; } | | > | > > | 142365 142366 142367 142368 142369 142370 142371 142372 142373 142374 142375 142376 142377 142378 142379 142380 142381 142382 142383 | } pIdxInfo->idxNum = 2; pIdxInfo->needToFreeIdxStr = 1; if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ return SQLITE_NOMEM; } nRow = pRtree->nRowEst / (iIdx + 1); pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; setEstimatedRows(pIdxInfo, nRow); return rc; } /* ** Return the N-dimensional volumn of the cell stored in *p. */ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ |
︙ | ︙ | |||
143826 143827 143828 143829 143830 143831 143832 143833 143834 143835 143836 143837 143838 143839 | ); if( zSql ){ rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } static sqlite3_module rtreeModule = { 0, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ rtreeDisconnect, /* xDisconnect - Disconnect from a table */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 143843 143844 143845 143846 143847 143848 143849 143850 143851 143852 143853 143854 143855 143856 143857 143858 143859 143860 143861 143862 143863 143864 143865 143866 143867 143868 143869 143870 143871 143872 143873 143874 143875 143876 143877 143878 143879 143880 143881 143882 143883 143884 143885 143886 143887 | ); if( zSql ){ rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } /* ** This function populates the pRtree->nRowEst variable with an estimate ** of the number of rows in the virtual table. If possible, this is based ** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. */ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'"; sqlite3_stmt *p; int rc; i64 nRow = 0; rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); if( rc==SQLITE_OK ){ sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC); if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); rc = sqlite3_finalize(p); }else if( rc!=SQLITE_NOMEM ){ rc = SQLITE_OK; } if( rc==SQLITE_OK ){ if( nRow==0 ){ pRtree->nRowEst = RTREE_DEFAULT_ROWEST; }else{ pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); } } return rc; } static sqlite3_module rtreeModule = { 0, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ rtreeDisconnect, /* xDisconnect - Disconnect from a table */ |
︙ | ︙ | |||
143912 143913 143914 143915 143916 143917 143918 143919 143920 143921 143922 143923 143924 143925 | appStmt[3] = &pRtree->pReadRowid; appStmt[4] = &pRtree->pWriteRowid; appStmt[5] = &pRtree->pDeleteRowid; appStmt[6] = &pRtree->pReadParent; appStmt[7] = &pRtree->pWriteParent; appStmt[8] = &pRtree->pDeleteParent; for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){ char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix); if( zSql ){ rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); }else{ rc = SQLITE_NOMEM; } | > | 143960 143961 143962 143963 143964 143965 143966 143967 143968 143969 143970 143971 143972 143973 143974 | appStmt[3] = &pRtree->pReadRowid; appStmt[4] = &pRtree->pWriteRowid; appStmt[5] = &pRtree->pDeleteRowid; appStmt[6] = &pRtree->pReadParent; appStmt[7] = &pRtree->pWriteParent; appStmt[8] = &pRtree->pDeleteParent; rc = rtreeQueryStat1(db, pRtree); for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){ char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix); if( zSql ){ rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); }else{ rc = SQLITE_NOMEM; } |
︙ | ︙ |
Changes to SQLite.Interop/src/core/sqlite3.h.
︙ | ︙ | |||
105 106 107 108 109 110 111 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.2" #define SQLITE_VERSION_NUMBER 3008002 | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.2" #define SQLITE_VERSION_NUMBER 3008002 #define SQLITE_SOURCE_ID "2013-11-11 19:56:35 f58d57017199421167dae8ebc67db2f19be45082" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
5291 5292 5293 5294 5295 5296 5297 | ** ^[sqlite3_free()] is used to free idxPtr if and only if ** needToFreeIdxPtr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** | | > | > | | > > > > > > > > > > | 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 | ** ^[sqlite3_free()] is used to free idxPtr if and only if ** needToFreeIdxPtr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** ** ^The estimatedCost value is an estimate of the cost of a particular ** strategy. A cost of N indicates that the cost of the strategy is similar ** to a linear scan of an SQLite table with N rows. A cost of log(N) ** indicates that the expense of the operation is similar to that of a ** binary search on a unique indexed field of an SQLite table with N rows. ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info ** structure for SQLite version 3.8.2. If a virtual table extension is ** used with an SQLite version earlier than 3.8.2, the results of attempting ** to read or write the estimatedRows field are undefined (but are likely ** to included crashing the application). The estimatedRows field should ** therefore only be used if [sqlite3_libversion_number()] returns a ** value greater than or equal to 3008002. */ struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { int iColumn; /* Column on left-hand side of constraint */ unsigned char op; /* Constraint operator */ |
︙ | ︙ | |||
5319 5320 5321 5322 5323 5324 5325 | int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *aConstraintUsage; int idxNum; /* Number used to identify the index */ char *idxStr; /* String, possibly obtained from sqlite3_malloc */ int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ | | > | 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 | int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *aConstraintUsage; int idxNum; /* Number used to identify the index */ char *idxStr; /* String, possibly obtained from sqlite3_malloc */ int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ }; /* ** CAPI3REF: Virtual Table Constraint Operator Codes ** ** These macros defined the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents |
︙ | ︙ |
Changes to System.Data.SQLite/SQLiteModule.cs.
︙ | ︙ | |||
961 962 963 964 965 966 967 968 969 970 971 972 973 974 | { constraintUsages = new SQLiteIndexConstraintUsage[nConstraint]; } #endregion /////////////////////////////////////////////////////////////////////// #region Public Properties private SQLiteIndexConstraintUsage[] constraintUsages; /// <summary> /// An array of <see cref="SQLiteIndexConstraintUsage" /> object /// instances, each containing information to be supplied to the SQLite /// core library. /// </summary> | > > > > > > > > > > > > > > > > > > | 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 989 990 991 992 | { constraintUsages = new SQLiteIndexConstraintUsage[nConstraint]; } #endregion /////////////////////////////////////////////////////////////////////// /// <summary> /// Determines if the native estimatedRows field can be used, based on /// the available version of the SQLite core library. /// </summary> /// <returns> /// Non-zero if the <see cref="EstimatedRows" /> property is supported /// by the SQLite core library. /// </returns> public bool CanUseEstimatedRows() { if (UnsafeNativeMethods.sqlite3_libversion_number() >= 3008002) return true; return false; } /////////////////////////////////////////////////////////////////////// #region Public Properties private SQLiteIndexConstraintUsage[] constraintUsages; /// <summary> /// An array of <see cref="SQLiteIndexConstraintUsage" /> object /// instances, each containing information to be supplied to the SQLite /// core library. /// </summary> |
︙ | ︙ | |||
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | /// indicates that a default estimated cost value should be used. /// </summary> public double? EstimatedCost { get { return estimatedCost; } set { estimatedCost = value; } } #endregion } #endregion /////////////////////////////////////////////////////////////////////////// #region SQLiteIndex Helper Class /// <summary> /// This class represents the various inputs and outputs used with the /// <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </summary> public sealed class SQLiteIndex { | > > > > > > > > > > > > > < < < < < < < < < < | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 | /// indicates that a default estimated cost value should be used. /// </summary> public double? EstimatedCost { get { return estimatedCost; } set { estimatedCost = value; } } /////////////////////////////////////////////////////////////////////// private long? estimatedRows; /// <summary> /// Estimated number of rows returned. Using a null value here /// indicates that a default estimated rows value should be used. /// </summary> public long? EstimatedRows { get { return estimatedRows; } set { estimatedRows = value; } } #endregion } #endregion /////////////////////////////////////////////////////////////////////////// #region SQLiteIndex Helper Class /// <summary> /// This class represents the various inputs and outputs used with the /// <see cref="ISQLiteManagedModule.BestIndex" /> method. /// </summary> public sealed class SQLiteIndex { #region Internal Constructors /// <summary> /// Constructs an instance of this class. /// </summary> /// <param name="nConstraint"> /// The number of <see cref="SQLiteIndexConstraint" /> (and /// <see cref="SQLiteIndexConstraintUsage" />) instances to |
︙ | ︙ | |||
1265 1266 1267 1268 1269 1270 1271 | SQLiteMarshal.WriteInt32(pIndex, offset, index.Outputs.OrderByConsumed); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), sizeof(double)); | > > | | > > > > > > > > | 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 | SQLiteMarshal.WriteInt32(pIndex, offset, index.Outputs.OrderByConsumed); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), sizeof(double)); if (index.Outputs.EstimatedCost.HasValue) { SQLiteMarshal.WriteDouble(pIndex, offset, index.Outputs.EstimatedCost.GetValueOrDefault()); } if (index.Outputs.CanUseEstimatedRows() && index.Outputs.EstimatedRows.HasValue) { SQLiteMarshal.WriteInt64(pIndex, offset, index.Outputs.EstimatedRows.GetValueOrDefault()); } } #endregion /////////////////////////////////////////////////////////////////////// #region Public Properties private SQLiteIndexInputs inputs; |
︙ | ︙ | |||
4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 | #else Marshal.WriteInt32(IntPtrForOffset(pointer, offset), value); #endif } /////////////////////////////////////////////////////////////////////// /// <summary> /// Writes a <see cref="Double" /> value to the specified memory /// location. /// </summary> /// <param name="pointer"> /// The <see cref="IntPtr" /> object instance representing the base /// memory location. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 | #else Marshal.WriteInt32(IntPtrForOffset(pointer, offset), value); #endif } /////////////////////////////////////////////////////////////////////// /// <summary> /// Writes an <see cref="Int64" /> value to the specified memory /// location. /// </summary> /// <param name="pointer"> /// The <see cref="IntPtr" /> object instance representing the base /// memory location. /// </param> /// <param name="offset"> /// The integer offset from the base memory location where the /// <see cref="Int64" /> value to be written is located. /// </param> /// <param name="value"> /// The <see cref="Int64" /> value to write. /// </param> public static void WriteInt64( IntPtr pointer, int offset, long value ) { #if !PLATFORM_COMPACTFRAMEWORK Marshal.WriteInt64(pointer, offset, value); #else Marshal.WriteInt64(IntPtrForOffset(pointer, offset), value); #endif } /////////////////////////////////////////////////////////////////////// /// <summary> /// Writes a <see cref="Double" /> value to the specified memory /// location. /// </summary> /// <param name="pointer"> /// The <see cref="IntPtr" /> object instance representing the base /// memory location. |
︙ | ︙ | |||
6837 6838 6839 6840 6841 6842 6843 | /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the specified estimated cost. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <param name="estimatedCost"> | | > | | 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 | /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the specified estimated cost. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <param name="estimatedCost"> /// The estimated cost value to use. Using a null value means that the /// default value provided by the SQLite core library should be used. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedCost( SQLiteIndex index, double? estimatedCost ) { if ((index == null) || (index.Outputs == null)) return false; index.Outputs.EstimatedCost = estimatedCost; return true; |
︙ | ︙ | |||
6870 6871 6872 6873 6874 6875 6876 | /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedCost( SQLiteIndex index ) { | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 | /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedCost( SQLiteIndex index ) { return SetEstimatedCost(index, null); } /////////////////////////////////////////////////////////////////////// /// <summary> /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the specified estimated rows. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <param name="estimatedRows"> /// The estimated rows value to use. Using a null value means that the /// default value provided by the SQLite core library should be used. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedRows( SQLiteIndex index, long? estimatedRows ) { if ((index == null) || (index.Outputs == null)) return false; index.Outputs.EstimatedRows = estimatedRows; return true; } /////////////////////////////////////////////////////////////////////// /// <summary> /// Modifies the specified <see cref="SQLiteIndex" /> object instance /// to contain the default estimated rows. /// </summary> /// <param name="index"> /// The <see cref="SQLiteIndex" /> object instance to modify. /// </param> /// <returns> /// Non-zero upon success. /// </returns> protected virtual bool SetEstimatedRows( SQLiteIndex index ) { return SetEstimatedRows(index, null); } #endregion #endregion /////////////////////////////////////////////////////////////////////// #region Public Properties |
︙ | ︙ |