OLD | NEW |
1 /* | 1 /* |
2 ** 2015-08-18 | 2 ** 2015-08-18 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 */ | 210 */ |
211 static int seriesEof(sqlite3_vtab_cursor *cur){ | 211 static int seriesEof(sqlite3_vtab_cursor *cur){ |
212 series_cursor *pCur = (series_cursor*)cur; | 212 series_cursor *pCur = (series_cursor*)cur; |
213 if( pCur->isDesc ){ | 213 if( pCur->isDesc ){ |
214 return pCur->iValue < pCur->mnValue; | 214 return pCur->iValue < pCur->mnValue; |
215 }else{ | 215 }else{ |
216 return pCur->iValue > pCur->mxValue; | 216 return pCur->iValue > pCur->mxValue; |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
| 220 /* True to cause run-time checking of the start=, stop=, and/or step= |
| 221 ** parameters. The only reason to do this is for testing the |
| 222 ** constraint checking logic for virtual tables in the SQLite core. |
| 223 */ |
| 224 #ifndef SQLITE_SERIES_CONSTRAINT_VERIFY |
| 225 # define SQLITE_SERIES_CONSTRAINT_VERIFY 0 |
| 226 #endif |
| 227 |
220 /* | 228 /* |
221 ** This method is called to "rewind" the series_cursor object back | 229 ** This method is called to "rewind" the series_cursor object back |
222 ** to the first row of output. This method is always called at least | 230 ** to the first row of output. This method is always called at least |
223 ** once prior to any call to seriesColumn() or seriesRowid() or | 231 ** once prior to any call to seriesColumn() or seriesRowid() or |
224 ** seriesEof(). | 232 ** seriesEof(). |
225 ** | 233 ** |
226 ** The query plan selected by seriesBestIndex is passed in the idxNum | 234 ** The query plan selected by seriesBestIndex is passed in the idxNum |
227 ** parameter. (idxStr is not used in this implementation.) idxNum | 235 ** parameter. (idxStr is not used in this implementation.) idxNum |
228 ** is a bitmask showing which constraints are available: | 236 ** is a bitmask showing which constraints are available: |
229 ** | 237 ** |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 idxNum |= 2; | 325 idxNum |= 2; |
318 break; | 326 break; |
319 case SERIES_COLUMN_STEP: | 327 case SERIES_COLUMN_STEP: |
320 stepIdx = i; | 328 stepIdx = i; |
321 idxNum |= 4; | 329 idxNum |= 4; |
322 break; | 330 break; |
323 } | 331 } |
324 } | 332 } |
325 if( startIdx>=0 ){ | 333 if( startIdx>=0 ){ |
326 pIdxInfo->aConstraintUsage[startIdx].argvIndex = ++nArg; | 334 pIdxInfo->aConstraintUsage[startIdx].argvIndex = ++nArg; |
327 pIdxInfo->aConstraintUsage[startIdx].omit = 1; | 335 pIdxInfo->aConstraintUsage[startIdx].omit= !SQLITE_SERIES_CONSTRAINT_VERIFY; |
328 } | 336 } |
329 if( stopIdx>=0 ){ | 337 if( stopIdx>=0 ){ |
330 pIdxInfo->aConstraintUsage[stopIdx].argvIndex = ++nArg; | 338 pIdxInfo->aConstraintUsage[stopIdx].argvIndex = ++nArg; |
331 pIdxInfo->aConstraintUsage[stopIdx].omit = 1; | 339 pIdxInfo->aConstraintUsage[stopIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; |
332 } | 340 } |
333 if( stepIdx>=0 ){ | 341 if( stepIdx>=0 ){ |
334 pIdxInfo->aConstraintUsage[stepIdx].argvIndex = ++nArg; | 342 pIdxInfo->aConstraintUsage[stepIdx].argvIndex = ++nArg; |
335 pIdxInfo->aConstraintUsage[stepIdx].omit = 1; | 343 pIdxInfo->aConstraintUsage[stepIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY; |
336 } | 344 } |
337 if( (idxNum & 3)==3 ){ | 345 if( (idxNum & 3)==3 ){ |
338 /* Both start= and stop= boundaries are available. This is the | 346 /* Both start= and stop= boundaries are available. This is the |
339 ** the preferred case */ | 347 ** the preferred case */ |
340 pIdxInfo->estimatedCost = (double)1; | 348 pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); |
341 pIdxInfo->estimatedRows = 1000; | 349 pIdxInfo->estimatedRows = 1000; |
342 if( pIdxInfo->nOrderBy==1 ){ | 350 if( pIdxInfo->nOrderBy==1 ){ |
343 if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; | 351 if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; |
344 pIdxInfo->orderByConsumed = 1; | 352 pIdxInfo->orderByConsumed = 1; |
345 } | 353 } |
346 }else{ | 354 }else{ |
347 /* If either boundary is missing, we have to generate a huge span | 355 /* If either boundary is missing, we have to generate a huge span |
348 ** of numbers. Make this case very expensive so that the query | 356 ** of numbers. Make this case very expensive so that the query |
349 ** planner will work hard to avoid it. */ | 357 ** planner will work hard to avoid it. */ |
350 pIdxInfo->estimatedCost = (double)2147483647; | 358 pIdxInfo->estimatedCost = (double)2147483647; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 #ifndef SQLITE_OMIT_VIRTUALTABLE | 404 #ifndef SQLITE_OMIT_VIRTUALTABLE |
397 if( sqlite3_libversion_number()<3008012 ){ | 405 if( sqlite3_libversion_number()<3008012 ){ |
398 *pzErrMsg = sqlite3_mprintf( | 406 *pzErrMsg = sqlite3_mprintf( |
399 "generate_series() requires SQLite 3.8.12 or later"); | 407 "generate_series() requires SQLite 3.8.12 or later"); |
400 return SQLITE_ERROR; | 408 return SQLITE_ERROR; |
401 } | 409 } |
402 rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0); | 410 rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0); |
403 #endif | 411 #endif |
404 return rc; | 412 return rc; |
405 } | 413 } |
OLD | NEW |