| 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 |