| | @@ -1495,12 +1495,12 @@ |
| 1495 | 1495 | v = (v<<4) + x; |
| 1496 | 1496 | zArg++; |
| 1497 | 1497 | } |
| 1498 | 1498 | }else{ |
| 1499 | 1499 | while( IsDigit(zArg[0]) ){ |
| 1500 | | - if( v>=922337203685477580 ){ |
| 1501 | | - if( v>922337203685477580 || zArg[0]>='8' ) goto integer_overflow; |
| 1500 | + if( v>=922337203685477580LL ){ |
| 1501 | + if( v>922337203685477580LL || zArg[0]>='8' ) goto integer_overflow; |
| 1502 | 1502 | } |
| 1503 | 1503 | v = v*10 + (zArg[0] - '0'); |
| 1504 | 1504 | zArg++; |
| 1505 | 1505 | } |
| 1506 | 1506 | } |
| | @@ -6125,23 +6125,24 @@ |
| 6125 | 6125 | ** Examples: |
| 6126 | 6126 | ** |
| 6127 | 6127 | ** SELECT * FROM generate_series(0,100,5); |
| 6128 | 6128 | ** |
| 6129 | 6129 | ** The query above returns integers from 0 through 100 counting by steps |
| 6130 | | -** of 5. |
| 6130 | +** of 5. In other words, 0, 5, 10, 15, ..., 90, 95, 100. There are a total |
| 6131 | +** of 21 rows. |
| 6131 | 6132 | ** |
| 6132 | 6133 | ** SELECT * FROM generate_series(0,100); |
| 6133 | 6134 | ** |
| 6134 | | -** Integers from 0 through 100 with a step size of 1. |
| 6135 | +** Integers from 0 through 100 with a step size of 1. 101 rows. |
| 6135 | 6136 | ** |
| 6136 | 6137 | ** SELECT * FROM generate_series(20) LIMIT 10; |
| 6137 | 6138 | ** |
| 6138 | | -** Integers 20 through 29. |
| 6139 | +** Integers 20 through 29. 10 rows. |
| 6139 | 6140 | ** |
| 6140 | 6141 | ** SELECT * FROM generate_series(0,-100,-5); |
| 6141 | 6142 | ** |
| 6142 | | -** Integers 0 -5 -10 ... -100. |
| 6143 | +** Integers 0 -5 -10 ... -100. 21 rows. |
| 6143 | 6144 | ** |
| 6144 | 6145 | ** SELECT * FROM generate_series(0,-1); |
| 6145 | 6146 | ** |
| 6146 | 6147 | ** Empty sequence. |
| 6147 | 6148 | ** |
| | @@ -6213,143 +6214,92 @@ |
| 6213 | 6214 | #include <string.h> |
| 6214 | 6215 | #include <limits.h> |
| 6215 | 6216 | #include <math.h> |
| 6216 | 6217 | |
| 6217 | 6218 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 6218 | | -/* |
| 6219 | | -** Return that member of a generate_series(...) sequence whose 0-based |
| 6220 | | -** index is ix. The 0th member is given by smBase. The sequence members |
| 6221 | | -** progress per ix increment by smStep. |
| 6222 | | -*/ |
| 6223 | | -static sqlite3_int64 genSeqMember( |
| 6224 | | - sqlite3_int64 smBase, |
| 6225 | | - sqlite3_int64 smStep, |
| 6226 | | - sqlite3_uint64 ix |
| 6227 | | -){ |
| 6228 | | - static const sqlite3_uint64 mxI64 = |
| 6229 | | - ((sqlite3_uint64)0x7fffffff)<<32 | 0xffffffff; |
| 6230 | | - if( ix>=mxI64 ){ |
| 6231 | | - /* Get ix into signed i64 range. */ |
| 6232 | | - ix -= mxI64; |
| 6233 | | - /* With 2's complement ALU, this next can be 1 step, but is split into |
| 6234 | | - * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */ |
| 6235 | | - smBase += (mxI64/2) * smStep; |
| 6236 | | - smBase += (mxI64 - mxI64/2) * smStep; |
| 6237 | | - } |
| 6238 | | - /* Under UBSAN (or on 1's complement machines), must do this last term |
| 6239 | | - * in steps to avoid the dreaded (and harmless) signed multiply overflow. */ |
| 6240 | | - if( ix>=2 ){ |
| 6241 | | - sqlite3_int64 ix2 = (sqlite3_int64)ix/2; |
| 6242 | | - smBase += ix2*smStep; |
| 6243 | | - ix -= ix2; |
| 6244 | | - } |
| 6245 | | - return smBase + ((sqlite3_int64)ix)*smStep; |
| 6246 | | -} |
| 6247 | | - |
| 6248 | | -/* typedef unsigned char u8; */ |
| 6249 | | - |
| 6250 | | -typedef struct SequenceSpec { |
| 6251 | | - sqlite3_int64 iOBase; /* Original starting value ("start") */ |
| 6252 | | - sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ |
| 6253 | | - sqlite3_int64 iBase; /* Starting value to actually use */ |
| 6254 | | - sqlite3_int64 iTerm; /* Terminal value to actually use */ |
| 6255 | | - sqlite3_int64 iStep; /* Increment ("step") */ |
| 6256 | | - sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */ |
| 6257 | | - sqlite3_uint64 uSeqIndexNow; /* Current index during generation */ |
| 6258 | | - sqlite3_int64 iValueNow; /* Current value during generation */ |
| 6259 | | - u8 isNotEOF; /* Sequence generation not exhausted */ |
| 6260 | | - u8 isReversing; /* Sequence is being reverse generated */ |
| 6261 | | -} SequenceSpec; |
| 6262 | | - |
| 6263 | | -/* |
| 6264 | | -** Prepare a SequenceSpec for use in generating an integer series |
| 6265 | | -** given initialized iBase, iTerm and iStep values. Sequence is |
| 6266 | | -** initialized per given isReversing. Other members are computed. |
| 6267 | | -*/ |
| 6268 | | -static void setupSequence( SequenceSpec *pss ){ |
| 6269 | | - int bSameSigns; |
| 6270 | | - pss->uSeqIndexMax = 0; |
| 6271 | | - pss->isNotEOF = 0; |
| 6272 | | - bSameSigns = (pss->iBase < 0)==(pss->iTerm < 0); |
| 6273 | | - if( pss->iTerm < pss->iBase ){ |
| 6274 | | - sqlite3_uint64 nuspan = 0; |
| 6275 | | - if( bSameSigns ){ |
| 6276 | | - nuspan = (sqlite3_uint64)(pss->iBase - pss->iTerm); |
| 6277 | | - }else{ |
| 6278 | | - /* Under UBSAN (or on 1's complement machines), must do this in steps. |
| 6279 | | - * In this clause, iBase>=0 and iTerm<0 . */ |
| 6280 | | - nuspan = 1; |
| 6281 | | - nuspan += pss->iBase; |
| 6282 | | - nuspan += -(pss->iTerm+1); |
| 6283 | | - } |
| 6284 | | - if( pss->iStep<0 ){ |
| 6285 | | - pss->isNotEOF = 1; |
| 6286 | | - if( nuspan==ULONG_MAX ){ |
| 6287 | | - pss->uSeqIndexMax = ( pss->iStep>LLONG_MIN )? nuspan/-pss->iStep : 1; |
| 6288 | | - }else if( pss->iStep>LLONG_MIN ){ |
| 6289 | | - pss->uSeqIndexMax = nuspan/-pss->iStep; |
| 6290 | | - } |
| 6291 | | - } |
| 6292 | | - }else if( pss->iTerm > pss->iBase ){ |
| 6293 | | - sqlite3_uint64 puspan = 0; |
| 6294 | | - if( bSameSigns ){ |
| 6295 | | - puspan = (sqlite3_uint64)(pss->iTerm - pss->iBase); |
| 6296 | | - }else{ |
| 6297 | | - /* Under UBSAN (or on 1's complement machines), must do this in steps. |
| 6298 | | - * In this clause, iTerm>=0 and iBase<0 . */ |
| 6299 | | - puspan = 1; |
| 6300 | | - puspan += pss->iTerm; |
| 6301 | | - puspan += -(pss->iBase+1); |
| 6302 | | - } |
| 6303 | | - if( pss->iStep>0 ){ |
| 6304 | | - pss->isNotEOF = 1; |
| 6305 | | - pss->uSeqIndexMax = puspan/pss->iStep; |
| 6306 | | - } |
| 6307 | | - }else if( pss->iTerm == pss->iBase ){ |
| 6308 | | - pss->isNotEOF = 1; |
| 6309 | | - pss->uSeqIndexMax = 0; |
| 6310 | | - } |
| 6311 | | - pss->uSeqIndexNow = (pss->isReversing)? pss->uSeqIndexMax : 0; |
| 6312 | | - pss->iValueNow = (pss->isReversing) |
| 6313 | | - ? genSeqMember(pss->iBase, pss->iStep, pss->uSeqIndexMax) |
| 6314 | | - : pss->iBase; |
| 6315 | | -} |
| 6316 | | - |
| 6317 | | -/* |
| 6318 | | -** Progress sequence generator to yield next value, if any. |
| 6319 | | -** Leave its state to either yield next value or be at EOF. |
| 6320 | | -** Return whether there is a next value, or 0 at EOF. |
| 6321 | | -*/ |
| 6322 | | -static int progressSequence( SequenceSpec *pss ){ |
| 6323 | | - if( !pss->isNotEOF ) return 0; |
| 6324 | | - if( pss->isReversing ){ |
| 6325 | | - if( pss->uSeqIndexNow > 0 ){ |
| 6326 | | - pss->uSeqIndexNow--; |
| 6327 | | - pss->iValueNow -= pss->iStep; |
| 6328 | | - }else{ |
| 6329 | | - pss->isNotEOF = 0; |
| 6330 | | - } |
| 6331 | | - }else{ |
| 6332 | | - if( pss->uSeqIndexNow < pss->uSeqIndexMax ){ |
| 6333 | | - pss->uSeqIndexNow++; |
| 6334 | | - pss->iValueNow += pss->iStep; |
| 6335 | | - }else{ |
| 6336 | | - pss->isNotEOF = 0; |
| 6337 | | - } |
| 6338 | | - } |
| 6339 | | - return pss->isNotEOF; |
| 6340 | | -} |
| 6341 | 6219 | |
| 6342 | 6220 | /* series_cursor is a subclass of sqlite3_vtab_cursor which will |
| 6343 | 6221 | ** serve as the underlying representation of a cursor that scans |
| 6344 | | -** over rows of the result |
| 6222 | +** over rows of the result. |
| 6223 | +** |
| 6224 | +** iOBase, iOTerm, and iOStep are the original values of the |
| 6225 | +** start=, stop=, and step= constraints on the query. These are |
| 6226 | +** the values reported by the start, stop, and step columns of the |
| 6227 | +** virtual table. |
| 6228 | +** |
| 6229 | +** iBase, iTerm, iStep, and bDescp are the actual values used to generate |
| 6230 | +** the sequence. These might be different from the iOxxxx values. |
| 6231 | +** For example in |
| 6232 | +** |
| 6233 | +** SELECT value FROM generate_series(1,11,2) |
| 6234 | +** WHERE value BETWEEN 4 AND 8; |
| 6235 | +** |
| 6236 | +** The iOBase is 1, but the iBase is 5. iOTerm is 11 but iTerm is 7. |
| 6237 | +** Another example: |
| 6238 | +** |
| 6239 | +** SELECT value FROM generate_series(1,15,3) ORDER BY value DESC; |
| 6240 | +** |
| 6241 | +** The cursor initialization for the above query is: |
| 6242 | +** |
| 6243 | +** iOBase = 1 iBase = 13 |
| 6244 | +** iOTerm = 15 iTerm = 1 |
| 6245 | +** iOStep = 3 iStep = 3 bDesc = 1 |
| 6246 | +** |
| 6247 | +** The actual step size is unsigned so that can have a value of |
| 6248 | +** +9223372036854775808 which is needed for querys like this: |
| 6249 | +** |
| 6250 | +** SELECT value |
| 6251 | +** FROM generate_series(9223372036854775807, |
| 6252 | +** -9223372036854775808, |
| 6253 | +** -9223372036854775808) |
| 6254 | +** ORDER BY value ASC; |
| 6255 | +** |
| 6256 | +** The setup for the previous query will be: |
| 6257 | +** |
| 6258 | +** iOBase = 9223372036854775807 iBase = -1 |
| 6259 | +** iOTerm = -9223372036854775808 iTerm = 9223372036854775807 |
| 6260 | +** iOStep = -9223372036854775808 iStep = 9223372036854775808 bDesc = 0 |
| 6345 | 6261 | */ |
| 6262 | +/* typedef unsigned char u8; */ |
| 6346 | 6263 | typedef struct series_cursor series_cursor; |
| 6347 | 6264 | struct series_cursor { |
| 6348 | 6265 | sqlite3_vtab_cursor base; /* Base class - must be first */ |
| 6349 | | - SequenceSpec ss; /* (this) Derived class data */ |
| 6266 | + sqlite3_int64 iOBase; /* Original starting value ("start") */ |
| 6267 | + sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ |
| 6268 | + sqlite3_int64 iOStep; /* Original step value */ |
| 6269 | + sqlite3_int64 iBase; /* Starting value to actually use */ |
| 6270 | + sqlite3_int64 iTerm; /* Terminal value to actually use */ |
| 6271 | + sqlite3_uint64 iStep; /* The step size */ |
| 6272 | + sqlite3_int64 iValue; /* Current value */ |
| 6273 | + u8 bDesc; /* iStep is really negative */ |
| 6274 | + u8 bDone; /* True if stepped past last element */ |
| 6350 | 6275 | }; |
| 6276 | + |
| 6277 | +/* |
| 6278 | +** Computed the difference between two 64-bit signed integers using a |
| 6279 | +** convoluted computation designed to work around the silly restriction |
| 6280 | +** against signed integer overflow in C. |
| 6281 | +*/ |
| 6282 | +static sqlite3_uint64 span64(sqlite3_int64 a, sqlite3_int64 b){ |
| 6283 | + assert( a>=b ); |
| 6284 | + return (*(sqlite3_uint64*)&a) - (*(sqlite3_uint64*)&b); |
| 6285 | +} |
| 6286 | + |
| 6287 | +/* |
| 6288 | +** Add or substract an unsigned 64-bit integer from a signed 64-bit integer |
| 6289 | +** and return the new signed 64-bit integer. |
| 6290 | +*/ |
| 6291 | +static sqlite3_int64 add64(sqlite3_int64 a, sqlite3_uint64 b){ |
| 6292 | + sqlite3_uint64 x = *(sqlite3_uint64*)&a; |
| 6293 | + x += b; |
| 6294 | + return *(sqlite3_int64*)&x; |
| 6295 | +} |
| 6296 | +static sqlite3_int64 sub64(sqlite3_int64 a, sqlite3_uint64 b){ |
| 6297 | + sqlite3_uint64 x = *(sqlite3_uint64*)&a; |
| 6298 | + x -= b; |
| 6299 | + return *(sqlite3_int64*)&x; |
| 6300 | +} |
| 6351 | 6301 | |
| 6352 | 6302 | /* |
| 6353 | 6303 | ** The seriesConnect() method is invoked to create a new |
| 6354 | 6304 | ** series_vtab that describes the generate_series virtual table. |
| 6355 | 6305 | ** |
| | @@ -6427,11 +6377,19 @@ |
| 6427 | 6377 | /* |
| 6428 | 6378 | ** Advance a series_cursor to its next row of output. |
| 6429 | 6379 | */ |
| 6430 | 6380 | static int seriesNext(sqlite3_vtab_cursor *cur){ |
| 6431 | 6381 | series_cursor *pCur = (series_cursor*)cur; |
| 6432 | | - progressSequence( & pCur->ss ); |
| 6382 | + if( pCur->iValue==pCur->iTerm ){ |
| 6383 | + pCur->bDone = 1; |
| 6384 | + }else if( pCur->bDesc ){ |
| 6385 | + pCur->iValue = sub64(pCur->iValue, pCur->iStep); |
| 6386 | + assert( pCur->iValue>=pCur->iTerm ); |
| 6387 | + }else{ |
| 6388 | + pCur->iValue = add64(pCur->iValue, pCur->iStep); |
| 6389 | + assert( pCur->iValue<=pCur->iTerm ); |
| 6390 | + } |
| 6433 | 6391 | return SQLITE_OK; |
| 6434 | 6392 | } |
| 6435 | 6393 | |
| 6436 | 6394 | /* |
| 6437 | 6395 | ** Return values of columns for the row at which the series_cursor |
| | @@ -6443,50 +6401,64 @@ |
| 6443 | 6401 | int i /* Which column to return */ |
| 6444 | 6402 | ){ |
| 6445 | 6403 | series_cursor *pCur = (series_cursor*)cur; |
| 6446 | 6404 | sqlite3_int64 x = 0; |
| 6447 | 6405 | switch( i ){ |
| 6448 | | - case SERIES_COLUMN_START: x = pCur->ss.iOBase; break; |
| 6449 | | - case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break; |
| 6450 | | - case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; |
| 6451 | | - default: x = pCur->ss.iValueNow; break; |
| 6406 | + case SERIES_COLUMN_START: x = pCur->iOBase; break; |
| 6407 | + case SERIES_COLUMN_STOP: x = pCur->iOTerm; break; |
| 6408 | + case SERIES_COLUMN_STEP: x = pCur->iOStep; break; |
| 6409 | + default: x = pCur->iValue; break; |
| 6452 | 6410 | } |
| 6453 | 6411 | sqlite3_result_int64(ctx, x); |
| 6454 | 6412 | return SQLITE_OK; |
| 6455 | 6413 | } |
| 6456 | 6414 | |
| 6457 | 6415 | #ifndef LARGEST_UINT64 |
| 6458 | | -#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) |
| 6459 | | -#define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32)) |
| 6460 | | -#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) |
| 6416 | +#define LARGEST_INT64 ((sqlite3_int64)0x7fffffffffffffffLL) |
| 6417 | +#define LARGEST_UINT64 ((sqlite3_uint64)0xffffffffffffffffULL) |
| 6418 | +#define SMALLEST_INT64 ((sqlite3_int64)0x8000000000000000LL) |
| 6461 | 6419 | #endif |
| 6462 | 6420 | |
| 6463 | 6421 | /* |
| 6464 | 6422 | ** The rowid is the same as the value. |
| 6465 | 6423 | */ |
| 6466 | 6424 | static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ |
| 6467 | 6425 | series_cursor *pCur = (series_cursor*)cur; |
| 6468 | | - *pRowid = pCur->ss.iValueNow; |
| 6426 | + *pRowid = pCur->iValue; |
| 6469 | 6427 | return SQLITE_OK; |
| 6470 | 6428 | } |
| 6471 | 6429 | |
| 6472 | 6430 | /* |
| 6473 | 6431 | ** Return TRUE if the cursor has been moved off of the last |
| 6474 | 6432 | ** row of output. |
| 6475 | 6433 | */ |
| 6476 | 6434 | static int seriesEof(sqlite3_vtab_cursor *cur){ |
| 6477 | 6435 | series_cursor *pCur = (series_cursor*)cur; |
| 6478 | | - return !pCur->ss.isNotEOF; |
| 6436 | + return pCur->bDone; |
| 6479 | 6437 | } |
| 6480 | 6438 | |
| 6481 | 6439 | /* True to cause run-time checking of the start=, stop=, and/or step= |
| 6482 | 6440 | ** parameters. The only reason to do this is for testing the |
| 6483 | 6441 | ** constraint checking logic for virtual tables in the SQLite core. |
| 6484 | 6442 | */ |
| 6485 | 6443 | #ifndef SQLITE_SERIES_CONSTRAINT_VERIFY |
| 6486 | 6444 | # define SQLITE_SERIES_CONSTRAINT_VERIFY 0 |
| 6487 | 6445 | #endif |
| 6446 | + |
| 6447 | +/* |
| 6448 | +** Return the number of steps between pCur->iBase and pCur->iTerm if |
| 6449 | +** the step width is pCur->iStep. |
| 6450 | +*/ |
| 6451 | +static sqlite3_uint64 seriesSteps(series_cursor *pCur){ |
| 6452 | + if( pCur->bDesc ){ |
| 6453 | + assert( pCur->iBase >= pCur->iTerm ); |
| 6454 | + return span64(pCur->iBase, pCur->iTerm)/pCur->iStep; |
| 6455 | + }else{ |
| 6456 | + assert( pCur->iBase <= pCur->iTerm ); |
| 6457 | + return span64(pCur->iTerm, pCur->iBase)/pCur->iStep; |
| 6458 | + } |
| 6459 | +} |
| 6488 | 6460 | |
| 6489 | 6461 | /* |
| 6490 | 6462 | ** This method is called to "rewind" the series_cursor object back |
| 6491 | 6463 | ** to the first row of output. This method is always called at least |
| 6492 | 6464 | ** once prior to any call to seriesColumn() or seriesRowid() or |
| | @@ -6517,189 +6489,244 @@ |
| 6517 | 6489 | sqlite3_vtab_cursor *pVtabCursor, |
| 6518 | 6490 | int idxNum, const char *idxStrUnused, |
| 6519 | 6491 | int argc, sqlite3_value **argv |
| 6520 | 6492 | ){ |
| 6521 | 6493 | series_cursor *pCur = (series_cursor *)pVtabCursor; |
| 6522 | | - int i = 0; |
| 6523 | | - int returnNoRows = 0; |
| 6524 | | - sqlite3_int64 iMin = SMALLEST_INT64; |
| 6525 | | - sqlite3_int64 iMax = LARGEST_INT64; |
| 6526 | | - sqlite3_int64 iLimit = 0; |
| 6527 | | - sqlite3_int64 iOffset = 0; |
| 6494 | + int iArg = 0; /* Arguments used so far */ |
| 6495 | + int i; /* Loop counter */ |
| 6496 | + sqlite3_int64 iMin = SMALLEST_INT64; /* Smallest allowed output value */ |
| 6497 | + sqlite3_int64 iMax = LARGEST_INT64; /* Largest allowed output value */ |
| 6498 | + sqlite3_int64 iLimit = 0; /* if >0, the value of the LIMIT */ |
| 6499 | + sqlite3_int64 iOffset = 0; /* if >0, the value of the OFFSET */ |
| 6528 | 6500 | |
| 6529 | 6501 | (void)idxStrUnused; |
| 6502 | + |
| 6503 | + /* If any constraints have a NULL value, then return no rows. |
| 6504 | + ** See ticket https://sqlite.org/src/info/fac496b61722daf2 |
| 6505 | + */ |
| 6506 | + for(i=0; i<argc; i++){ |
| 6507 | + if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ |
| 6508 | + goto series_no_rows; |
| 6509 | + } |
| 6510 | + } |
| 6511 | + |
| 6512 | + /* Capture the three HIDDEN parameters to the virtual table and insert |
| 6513 | + ** default values for any parameters that are omitted. |
| 6514 | + */ |
| 6530 | 6515 | if( idxNum & 0x01 ){ |
| 6531 | | - pCur->ss.iBase = sqlite3_value_int64(argv[i++]); |
| 6516 | + pCur->iOBase = sqlite3_value_int64(argv[iArg++]); |
| 6532 | 6517 | }else{ |
| 6533 | | - pCur->ss.iBase = 0; |
| 6518 | + pCur->iOBase = 0; |
| 6534 | 6519 | } |
| 6535 | 6520 | if( idxNum & 0x02 ){ |
| 6536 | | - pCur->ss.iTerm = sqlite3_value_int64(argv[i++]); |
| 6521 | + pCur->iOTerm = sqlite3_value_int64(argv[iArg++]); |
| 6537 | 6522 | }else{ |
| 6538 | | - pCur->ss.iTerm = 0xffffffff; |
| 6523 | + pCur->iOTerm = 0xffffffff; |
| 6539 | 6524 | } |
| 6540 | 6525 | if( idxNum & 0x04 ){ |
| 6541 | | - pCur->ss.iStep = sqlite3_value_int64(argv[i++]); |
| 6542 | | - if( pCur->ss.iStep==0 ){ |
| 6543 | | - pCur->ss.iStep = 1; |
| 6544 | | - }else if( pCur->ss.iStep<0 ){ |
| 6545 | | - if( (idxNum & 0x10)==0 ) idxNum |= 0x08; |
| 6546 | | - } |
| 6526 | + pCur->iOStep = sqlite3_value_int64(argv[iArg++]); |
| 6527 | + if( pCur->iOStep==0 ) pCur->iOStep = 1; |
| 6547 | 6528 | }else{ |
| 6548 | | - pCur->ss.iStep = 1; |
| 6529 | + pCur->iOStep = 1; |
| 6549 | 6530 | } |
| 6550 | 6531 | |
| 6551 | 6532 | /* If there are constraints on the value column but there are |
| 6552 | 6533 | ** no constraints on the start, stop, and step columns, then |
| 6553 | 6534 | ** initialize the default range to be the entire range of 64-bit signed |
| 6554 | 6535 | ** integers. This range will contracted by the value column constraints |
| 6555 | 6536 | ** further below. |
| 6556 | 6537 | */ |
| 6557 | 6538 | if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ |
| 6558 | | - pCur->ss.iBase = SMALLEST_INT64; |
| 6539 | + pCur->iOBase = SMALLEST_INT64; |
| 6559 | 6540 | } |
| 6560 | 6541 | if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ |
| 6561 | | - pCur->ss.iTerm = LARGEST_INT64; |
| 6542 | + pCur->iOTerm = LARGEST_INT64; |
| 6562 | 6543 | } |
| 6563 | | - pCur->ss.iOBase = pCur->ss.iBase; |
| 6564 | | - pCur->ss.iOTerm = pCur->ss.iTerm; |
| 6544 | + pCur->iBase = pCur->iOBase; |
| 6545 | + pCur->iTerm = pCur->iOTerm; |
| 6546 | + if( pCur->iOStep>0 ){ |
| 6547 | + pCur->iStep = pCur->iOStep; |
| 6548 | + }else if( pCur->iOStep>SMALLEST_INT64 ){ |
| 6549 | + pCur->iStep = -pCur->iOStep; |
| 6550 | + }else{ |
| 6551 | + pCur->iStep = LARGEST_INT64; |
| 6552 | + pCur->iStep++; |
| 6553 | + } |
| 6554 | + pCur->bDesc = pCur->iOStep<0; |
| 6555 | + if( pCur->bDesc==0 && pCur->iBase>pCur->iTerm ){ |
| 6556 | + goto series_no_rows; |
| 6557 | + } |
| 6558 | + if( pCur->bDesc!=0 && pCur->iBase<pCur->iTerm ){ |
| 6559 | + goto series_no_rows; |
| 6560 | + } |
| 6565 | 6561 | |
| 6566 | 6562 | /* Extract the LIMIT and OFFSET values, but do not apply them yet. |
| 6567 | 6563 | ** The range must first be constrained by the limits on value. |
| 6568 | 6564 | */ |
| 6569 | 6565 | if( idxNum & 0x20 ){ |
| 6570 | | - iLimit = sqlite3_value_int64(argv[i++]); |
| 6566 | + iLimit = sqlite3_value_int64(argv[iArg++]); |
| 6571 | 6567 | if( idxNum & 0x40 ){ |
| 6572 | | - iOffset = sqlite3_value_int64(argv[i++]); |
| 6568 | + iOffset = sqlite3_value_int64(argv[iArg++]); |
| 6573 | 6569 | } |
| 6574 | 6570 | } |
| 6575 | 6571 | |
| 6572 | + /* Narrow the range of iMin and iMax (the minimum and maximum outputs) |
| 6573 | + ** based on equality and inequality constraints on the "value" column. |
| 6574 | + */ |
| 6576 | 6575 | if( idxNum & 0x3380 ){ |
| 6577 | | - /* Extract the maximum range of output values determined by |
| 6578 | | - ** constraints on the "value" column. |
| 6579 | | - */ |
| 6580 | | - if( idxNum & 0x0080 ){ |
| 6581 | | - if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ |
| 6582 | | - double r = sqlite3_value_double(argv[i++]); |
| 6583 | | - if( r==ceil(r) ){ |
| 6576 | + if( idxNum & 0x0080 ){ /* value=X */ |
| 6577 | + if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ |
| 6578 | + double r = sqlite3_value_double(argv[iArg++]); |
| 6579 | + if( r==ceil(r) |
| 6580 | + && r>=(double)SMALLEST_INT64 |
| 6581 | + && r<=(double)LARGEST_INT64 |
| 6582 | + ){ |
| 6584 | 6583 | iMin = iMax = (sqlite3_int64)r; |
| 6585 | 6584 | }else{ |
| 6586 | | - returnNoRows = 1; |
| 6585 | + goto series_no_rows; |
| 6587 | 6586 | } |
| 6588 | 6587 | }else{ |
| 6589 | | - iMin = iMax = sqlite3_value_int64(argv[i++]); |
| 6588 | + iMin = iMax = sqlite3_value_int64(argv[iArg++]); |
| 6590 | 6589 | } |
| 6591 | 6590 | }else{ |
| 6592 | | - if( idxNum & 0x0300 ){ |
| 6593 | | - if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ |
| 6594 | | - double r = sqlite3_value_double(argv[i++]); |
| 6595 | | - if( idxNum & 0x0200 && r==ceil(r) ){ |
| 6591 | + if( idxNum & 0x0300 ){ /* value>X or value>=X */ |
| 6592 | + if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ |
| 6593 | + double r = sqlite3_value_double(argv[iArg++]); |
| 6594 | + if( r<(double)SMALLEST_INT64 ){ |
| 6595 | + iMin = SMALLEST_INT64; |
| 6596 | + }else if( (idxNum & 0x0200)!=0 && r==ceil(r) ){ |
| 6596 | 6597 | iMin = (sqlite3_int64)ceil(r+1.0); |
| 6597 | 6598 | }else{ |
| 6598 | 6599 | iMin = (sqlite3_int64)ceil(r); |
| 6599 | 6600 | } |
| 6600 | 6601 | }else{ |
| 6601 | | - iMin = sqlite3_value_int64(argv[i++]); |
| 6602 | | - if( idxNum & 0x0200 ){ |
| 6602 | + iMin = sqlite3_value_int64(argv[iArg++]); |
| 6603 | + if( (idxNum & 0x0200)!=0 ){ |
| 6603 | 6604 | if( iMin==LARGEST_INT64 ){ |
| 6604 | | - returnNoRows = 1; |
| 6605 | + goto series_no_rows; |
| 6605 | 6606 | }else{ |
| 6606 | 6607 | iMin++; |
| 6607 | 6608 | } |
| 6608 | 6609 | } |
| 6609 | 6610 | } |
| 6610 | 6611 | } |
| 6611 | | - if( idxNum & 0x3000 ){ |
| 6612 | | - if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){ |
| 6613 | | - double r = sqlite3_value_double(argv[i++]); |
| 6614 | | - if( (idxNum & 0x2000)!=0 && r==floor(r) ){ |
| 6612 | + if( idxNum & 0x3000 ){ /* value<X or value<=X */ |
| 6613 | + if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ |
| 6614 | + double r = sqlite3_value_double(argv[iArg++]); |
| 6615 | + if( r>(double)LARGEST_INT64 ){ |
| 6616 | + iMax = LARGEST_INT64; |
| 6617 | + }else if( (idxNum & 0x2000)!=0 && r==floor(r) ){ |
| 6615 | 6618 | iMax = (sqlite3_int64)(r-1.0); |
| 6616 | 6619 | }else{ |
| 6617 | 6620 | iMax = (sqlite3_int64)floor(r); |
| 6618 | 6621 | } |
| 6619 | 6622 | }else{ |
| 6620 | | - iMax = sqlite3_value_int64(argv[i++]); |
| 6623 | + iMax = sqlite3_value_int64(argv[iArg++]); |
| 6621 | 6624 | if( idxNum & 0x2000 ){ |
| 6622 | 6625 | if( iMax==SMALLEST_INT64 ){ |
| 6623 | | - returnNoRows = 1; |
| 6626 | + goto series_no_rows; |
| 6624 | 6627 | }else{ |
| 6625 | 6628 | iMax--; |
| 6626 | 6629 | } |
| 6627 | 6630 | } |
| 6628 | 6631 | } |
| 6629 | 6632 | } |
| 6630 | 6633 | if( iMin>iMax ){ |
| 6631 | | - returnNoRows = 1; |
| 6634 | + goto series_no_rows; |
| 6632 | 6635 | } |
| 6633 | 6636 | } |
| 6634 | 6637 | |
| 6635 | 6638 | /* Try to reduce the range of values to be generated based on |
| 6636 | 6639 | ** constraints on the "value" column. |
| 6637 | 6640 | */ |
| 6638 | | - if( pCur->ss.iStep>0 ){ |
| 6639 | | - sqlite3_int64 szStep = pCur->ss.iStep; |
| 6640 | | - if( pCur->ss.iBase<iMin ){ |
| 6641 | | - sqlite3_uint64 d = iMin - pCur->ss.iBase; |
| 6642 | | - pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep; |
| 6643 | | - } |
| 6644 | | - if( pCur->ss.iTerm>iMax ){ |
| 6645 | | - pCur->ss.iTerm = iMax; |
| 6641 | + if( pCur->bDesc==0 ){ |
| 6642 | + if( pCur->iBase<iMin ){ |
| 6643 | + sqlite3_uint64 span = span64(iMin,pCur->iBase); |
| 6644 | + pCur->iBase = add64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); |
| 6645 | + if( pCur->iBase<iMin ){ |
| 6646 | + if( pCur->iBase > sub64(LARGEST_INT64, pCur->iStep) ){ |
| 6647 | + goto series_no_rows; |
| 6648 | + } |
| 6649 | + pCur->iBase = add64(pCur->iBase, pCur->iStep); |
| 6650 | + } |
| 6651 | + } |
| 6652 | + if( pCur->iTerm>iMax ){ |
| 6653 | + pCur->iTerm = iMax; |
| 6646 | 6654 | } |
| 6647 | 6655 | }else{ |
| 6648 | | - sqlite3_int64 szStep = -pCur->ss.iStep; |
| 6649 | | - assert( szStep>0 ); |
| 6650 | | - if( pCur->ss.iBase>iMax ){ |
| 6651 | | - sqlite3_uint64 d = pCur->ss.iBase - iMax; |
| 6652 | | - pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep; |
| 6653 | | - } |
| 6654 | | - if( pCur->ss.iTerm<iMin ){ |
| 6655 | | - pCur->ss.iTerm = iMin; |
| 6656 | + if( pCur->iBase>iMax ){ |
| 6657 | + sqlite3_uint64 span = span64(pCur->iBase,iMax); |
| 6658 | + pCur->iBase = sub64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); |
| 6659 | + if( pCur->iBase>iMax ){ |
| 6660 | + if( pCur->iBase < add64(SMALLEST_INT64, pCur->iStep) ){ |
| 6661 | + goto series_no_rows; |
| 6662 | + } |
| 6663 | + pCur->iBase = sub64(pCur->iBase, pCur->iStep); |
| 6664 | + } |
| 6665 | + } |
| 6666 | + if( pCur->iTerm<iMin ){ |
| 6667 | + pCur->iTerm = iMin; |
| 6656 | 6668 | } |
| 6657 | 6669 | } |
| 6658 | 6670 | } |
| 6671 | + |
| 6672 | + /* Adjust iTerm so that it is exactly the last value of the series. |
| 6673 | + */ |
| 6674 | + if( pCur->bDesc==0 ){ |
| 6675 | + if( pCur->iBase>pCur->iTerm ){ |
| 6676 | + goto series_no_rows; |
| 6677 | + } |
| 6678 | + pCur->iTerm = sub64(pCur->iTerm, |
| 6679 | + span64(pCur->iTerm,pCur->iBase) % pCur->iStep); |
| 6680 | + }else{ |
| 6681 | + if( pCur->iBase<pCur->iTerm ){ |
| 6682 | + goto series_no_rows; |
| 6683 | + } |
| 6684 | + pCur->iTerm = add64(pCur->iTerm, |
| 6685 | + span64(pCur->iBase,pCur->iTerm) % pCur->iStep); |
| 6686 | + } |
| 6687 | + |
| 6688 | + /* Transform the series generator to output values in the requested |
| 6689 | + ** order. |
| 6690 | + */ |
| 6691 | + if( ((idxNum & 0x0008)!=0 && pCur->bDesc==0) |
| 6692 | + || ((idxNum & 0x0010)!=0 && pCur->bDesc!=0) |
| 6693 | + ){ |
| 6694 | + sqlite3_int64 tmp = pCur->iBase; |
| 6695 | + pCur->iBase = pCur->iTerm; |
| 6696 | + pCur->iTerm = tmp; |
| 6697 | + pCur->bDesc = !pCur->bDesc; |
| 6698 | + } |
| 6659 | 6699 | |
| 6660 | 6700 | /* Apply LIMIT and OFFSET constraints, if any */ |
| 6701 | + assert( pCur->iStep!=0 ); |
| 6661 | 6702 | if( idxNum & 0x20 ){ |
| 6703 | + sqlite3_uint64 nStep; |
| 6662 | 6704 | if( iOffset>0 ){ |
| 6663 | | - pCur->ss.iBase += pCur->ss.iStep*iOffset; |
| 6664 | | - } |
| 6665 | | - if( iLimit>=0 ){ |
| 6666 | | - sqlite3_int64 iTerm; |
| 6667 | | - sqlite3_int64 mxLimit; |
| 6668 | | - assert( pCur->ss.iStep>0 ); |
| 6669 | | - mxLimit = (LARGEST_INT64 - pCur->ss.iBase)/pCur->ss.iStep; |
| 6670 | | - if( iLimit>mxLimit ) iLimit = mxLimit; |
| 6671 | | - iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep; |
| 6672 | | - if( pCur->ss.iStep<0 ){ |
| 6673 | | - if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; |
| 6674 | | - }else{ |
| 6675 | | - if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; |
| 6676 | | - } |
| 6677 | | - } |
| 6678 | | - } |
| 6679 | | - |
| 6680 | | - |
| 6681 | | - for(i=0; i<argc; i++){ |
| 6682 | | - if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ |
| 6683 | | - /* If any of the constraints have a NULL value, then return no rows. |
| 6684 | | - ** See ticket https://sqlite.org/src/info/fac496b61722daf2 */ |
| 6685 | | - returnNoRows = 1; |
| 6686 | | - break; |
| 6687 | | - } |
| 6688 | | - } |
| 6689 | | - if( returnNoRows ){ |
| 6690 | | - pCur->ss.iBase = 1; |
| 6691 | | - pCur->ss.iTerm = 0; |
| 6692 | | - pCur->ss.iStep = 1; |
| 6693 | | - } |
| 6694 | | - if( idxNum & 0x08 ){ |
| 6695 | | - pCur->ss.isReversing = pCur->ss.iStep > 0; |
| 6696 | | - }else{ |
| 6697 | | - pCur->ss.isReversing = pCur->ss.iStep < 0; |
| 6698 | | - } |
| 6699 | | - setupSequence( &pCur->ss ); |
| 6705 | + if( seriesSteps(pCur) < (sqlite3_uint64)iOffset ){ |
| 6706 | + goto series_no_rows; |
| 6707 | + }else if( pCur->bDesc ){ |
| 6708 | + pCur->iBase = sub64(pCur->iBase, pCur->iStep*iOffset); |
| 6709 | + }else{ |
| 6710 | + pCur->iBase = add64(pCur->iBase, pCur->iStep*iOffset); |
| 6711 | + } |
| 6712 | + } |
| 6713 | + if( iLimit>=0 && (nStep = seriesSteps(pCur)) > (sqlite3_uint64)iLimit ){ |
| 6714 | + pCur->iTerm = add64(pCur->iBase, (iLimit - 1)*pCur->iStep); |
| 6715 | + } |
| 6716 | + } |
| 6717 | + pCur->iValue = pCur->iBase; |
| 6718 | + pCur->bDone = 0; |
| 6700 | 6719 | return SQLITE_OK; |
| 6720 | + |
| 6721 | +series_no_rows: |
| 6722 | + pCur->iBase = 0; |
| 6723 | + pCur->iTerm = 0; |
| 6724 | + pCur->iStep = 1; |
| 6725 | + pCur->bDesc = 0; |
| 6726 | + pCur->bDone = 1; |
| 6727 | + return SQLITE_OK; |
| 6701 | 6728 | } |
| 6702 | 6729 | |
| 6703 | 6730 | /* |
| 6704 | 6731 | ** SQLite will invoke this method one or more times while planning a query |
| 6705 | 6732 | ** that uses the generate_series virtual table. This routine needs to create |
| | @@ -9384,18 +9411,20 @@ |
| 9384 | 9411 | if( idxNum & 1 ){ |
| 9385 | 9412 | pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); |
| 9386 | 9413 | if( pCur->nPrefix>0 ){ |
| 9387 | 9414 | pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 9388 | 9415 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 9416 | + pCur->nPrefix = (int)strlen(pCur->zPrefix); |
| 9389 | 9417 | } |
| 9390 | 9418 | iArg = 1; |
| 9391 | 9419 | } |
| 9392 | 9420 | if( idxNum & 2 ){ |
| 9393 | 9421 | pCur->nLine = sqlite3_value_bytes(argv[iArg]); |
| 9394 | 9422 | if( pCur->nLine>0 ){ |
| 9395 | 9423 | pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); |
| 9396 | 9424 | if( pCur->zLine==0 ) return SQLITE_NOMEM; |
| 9425 | + pCur->nLine = (int)strlen(pCur->zLine); |
| 9397 | 9426 | } |
| 9398 | 9427 | } |
| 9399 | 9428 | if( pCur->zLine!=0 && pCur->zPrefix==0 ){ |
| 9400 | 9429 | int i = pCur->nLine; |
| 9401 | 9430 | while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ |
| | @@ -9403,10 +9432,11 @@ |
| 9403 | 9432 | } |
| 9404 | 9433 | pCur->nPrefix = pCur->nLine - i; |
| 9405 | 9434 | if( pCur->nPrefix>0 ){ |
| 9406 | 9435 | pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); |
| 9407 | 9436 | if( pCur->zPrefix==0 ) return SQLITE_NOMEM; |
| 9437 | + pCur->nPrefix = (int)strlen(pCur->zPrefix); |
| 9408 | 9438 | } |
| 9409 | 9439 | } |
| 9410 | 9440 | pCur->iRowid = 0; |
| 9411 | 9441 | pCur->ePhase = COMPLETION_FIRST_PHASE; |
| 9412 | 9442 | return completionNext(pVtabCursor); |
| | @@ -10316,13 +10346,18 @@ |
| 10316 | 10346 | "method," /* 6: Compression method (integer) */ |
| 10317 | 10347 | "z HIDDEN" /* 7: Name of zip file */ |
| 10318 | 10348 | ") WITHOUT ROWID;"; |
| 10319 | 10349 | |
| 10320 | 10350 | #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ |
| 10321 | | -#define ZIPFILE_BUFFER_SIZE (64*1024) |
| 10322 | 10351 | #define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */ |
| 10323 | 10352 | |
| 10353 | +/* |
| 10354 | +** The buffer should be large enough to contain 3 65536 byte strings - the |
| 10355 | +** filename, the extra field and the file comment. |
| 10356 | +*/ |
| 10357 | +#define ZIPFILE_BUFFER_SIZE (200*1024) |
| 10358 | + |
| 10324 | 10359 | |
| 10325 | 10360 | /* |
| 10326 | 10361 | ** Magic numbers used to read and write zip files. |
| 10327 | 10362 | ** |
| 10328 | 10363 | ** ZIPFILE_NEWENTRY_MADEBY: |
| | @@ -11000,10 +11035,19 @@ |
| 11000 | 11035 | || mUnixTime==zipfileMtime(pCds) |
| 11001 | 11036 | || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) |
| 11002 | 11037 | /* || (mUnixTime % 2) */ |
| 11003 | 11038 | ); |
| 11004 | 11039 | } |
| 11040 | + |
| 11041 | +/* |
| 11042 | +** Set (*pzErr) to point to a buffer from sqlite3_malloc() containing a |
| 11043 | +** generic corruption message and return SQLITE_CORRUPT; |
| 11044 | +*/ |
| 11045 | +static int zipfileCorrupt(char **pzErr){ |
| 11046 | + *pzErr = sqlite3_mprintf("zip archive is corrupt"); |
| 11047 | + return SQLITE_CORRUPT; |
| 11048 | +} |
| 11005 | 11049 | |
| 11006 | 11050 | /* |
| 11007 | 11051 | ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in |
| 11008 | 11052 | ** size) containing an entire zip archive image. Or, if aBlob is NULL, |
| 11009 | 11053 | ** then pFile is a file-handle open on a zip file. In either case, this |
| | @@ -11023,16 +11067,19 @@ |
| 11023 | 11067 | ZipfileEntry **ppEntry /* OUT: Pointer to new object */ |
| 11024 | 11068 | ){ |
| 11025 | 11069 | u8 *aRead; |
| 11026 | 11070 | char **pzErr = &pTab->base.zErrMsg; |
| 11027 | 11071 | int rc = SQLITE_OK; |
| 11028 | | - (void)nBlob; |
| 11029 | 11072 | |
| 11030 | 11073 | if( aBlob==0 ){ |
| 11031 | 11074 | aRead = pTab->aBuffer; |
| 11032 | 11075 | rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); |
| 11033 | 11076 | }else{ |
| 11077 | + if( (iOff+ZIPFILE_CDS_FIXED_SZ)>nBlob ){ |
| 11078 | + /* Not enough data for the CDS structure. Corruption. */ |
| 11079 | + return zipfileCorrupt(pzErr); |
| 11080 | + } |
| 11034 | 11081 | aRead = (u8*)&aBlob[iOff]; |
| 11035 | 11082 | } |
| 11036 | 11083 | |
| 11037 | 11084 | if( rc==SQLITE_OK ){ |
| 11038 | 11085 | sqlite3_int64 nAlloc; |
| | @@ -11059,10 +11106,13 @@ |
| 11059 | 11106 | rc = zipfileReadData( |
| 11060 | 11107 | pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr |
| 11061 | 11108 | ); |
| 11062 | 11109 | }else{ |
| 11063 | 11110 | aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; |
| 11111 | + if( (iOff + ZIPFILE_LFH_FIXED_SZ + nFile + nExtra)>nBlob ){ |
| 11112 | + rc = zipfileCorrupt(pzErr); |
| 11113 | + } |
| 11064 | 11114 | } |
| 11065 | 11115 | } |
| 11066 | 11116 | |
| 11067 | 11117 | if( rc==SQLITE_OK ){ |
| 11068 | 11118 | u32 *pt = &pNew->mUnixTime; |
| | @@ -11081,19 +11131,22 @@ |
| 11081 | 11131 | ZipfileLFH lfh; |
| 11082 | 11132 | if( pFile ){ |
| 11083 | 11133 | rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); |
| 11084 | 11134 | }else{ |
| 11085 | 11135 | aRead = (u8*)&aBlob[pNew->cds.iOffset]; |
| 11136 | + if( (pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ)>nBlob ){ |
| 11137 | + rc = zipfileCorrupt(pzErr); |
| 11138 | + } |
| 11086 | 11139 | } |
| 11087 | 11140 | |
| 11088 | 11141 | if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh); |
| 11089 | 11142 | if( rc==SQLITE_OK ){ |
| 11090 | 11143 | pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; |
| 11091 | 11144 | pNew->iDataOff += lfh.nFile + lfh.nExtra; |
| 11092 | 11145 | if( aBlob && pNew->cds.szCompressed ){ |
| 11093 | 11146 | if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){ |
| 11094 | | - rc = SQLITE_CORRUPT; |
| 11147 | + rc = zipfileCorrupt(pzErr); |
| 11095 | 11148 | }else{ |
| 11096 | 11149 | pNew->aData = &pNew->aExtra[nExtra]; |
| 11097 | 11150 | memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); |
| 11098 | 11151 | } |
| 11099 | 11152 | } |
| | @@ -12595,10 +12648,11 @@ |
| 12595 | 12648 | return rc; |
| 12596 | 12649 | } |
| 12597 | 12650 | |
| 12598 | 12651 | /************************* End ../ext/misc/sqlar.c ********************/ |
| 12599 | 12652 | #endif |
| 12653 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 12600 | 12654 | /************************* Begin ../ext/expert/sqlite3expert.h ******************/ |
| 12601 | 12655 | /* |
| 12602 | 12656 | ** 2017 April 07 |
| 12603 | 12657 | ** |
| 12604 | 12658 | ** The author disclaims copyright to this source code. In place of |
| | @@ -15003,10 +15057,11 @@ |
| 15003 | 15057 | } |
| 15004 | 15058 | |
| 15005 | 15059 | #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
| 15006 | 15060 | |
| 15007 | 15061 | /************************* End ../ext/expert/sqlite3expert.c ********************/ |
| 15062 | +#endif |
| 15008 | 15063 | /************************* Begin ../ext/intck/sqlite3intck.h ******************/ |
| 15009 | 15064 | /* |
| 15010 | 15065 | ** 2024-02-08 |
| 15011 | 15066 | ** |
| 15012 | 15067 | ** The author disclaims copyright to this source code. In place of |
| | @@ -21643,15 +21698,17 @@ |
| 21643 | 21698 | char **azFilter; /* Array of xFilter rejection GLOB patterns */ |
| 21644 | 21699 | sqlite3_session *p; /* The open session */ |
| 21645 | 21700 | }; |
| 21646 | 21701 | #endif |
| 21647 | 21702 | |
| 21703 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 21648 | 21704 | typedef struct ExpertInfo ExpertInfo; |
| 21649 | 21705 | struct ExpertInfo { |
| 21650 | 21706 | sqlite3expert *pExpert; |
| 21651 | 21707 | int bVerbose; |
| 21652 | 21708 | }; |
| 21709 | +#endif |
| 21653 | 21710 | |
| 21654 | 21711 | /* A single line in the EQP output */ |
| 21655 | 21712 | typedef struct EQPGraphRow EQPGraphRow; |
| 21656 | 21713 | struct EQPGraphRow { |
| 21657 | 21714 | int iEqpId; /* ID for this row */ |
| | @@ -21751,11 +21808,13 @@ |
| 21751 | 21808 | int *aiIndent; /* Array of indents used in MODE_Explain */ |
| 21752 | 21809 | int nIndent; /* Size of array aiIndent[] */ |
| 21753 | 21810 | int iIndent; /* Index of current op in aiIndent[] */ |
| 21754 | 21811 | char *zNonce; /* Nonce for temporary safe-mode escapes */ |
| 21755 | 21812 | EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ |
| 21813 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 21756 | 21814 | ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ |
| 21815 | +#endif |
| 21757 | 21816 | #ifdef SQLITE_SHELL_FIDDLE |
| 21758 | 21817 | struct { |
| 21759 | 21818 | const char * zInput; /* Input string from wasm/JS proxy */ |
| 21760 | 21819 | const char * zPos; /* Cursor pos into zInput */ |
| 21761 | 21820 | const char * zDefaultDbName; /* Default name for db file */ |
| | @@ -21779,13 +21838,12 @@ |
| 21779 | 21838 | */ |
| 21780 | 21839 | #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ |
| 21781 | 21840 | #define SHELL_OPEN_NORMAL 1 /* Normal database file */ |
| 21782 | 21841 | #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ |
| 21783 | 21842 | #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ |
| 21784 | | -#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ |
| 21785 | | -#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ |
| 21786 | | -#define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */ |
| 21843 | +#define SHELL_OPEN_DESERIALIZE 4 /* Open using sqlite3_deserialize() */ |
| 21844 | +#define SHELL_OPEN_HEXDB 5 /* Use "dbtotxt" output as data source */ |
| 21787 | 21845 | |
| 21788 | 21846 | /* Allowed values for ShellState.eTraceType |
| 21789 | 21847 | */ |
| 21790 | 21848 | #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ |
| 21791 | 21849 | #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ |
| | @@ -24688,11 +24746,11 @@ |
| 24688 | 24746 | } |
| 24689 | 24747 | } |
| 24690 | 24748 | } |
| 24691 | 24749 | } |
| 24692 | 24750 | |
| 24693 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 24751 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 24694 | 24752 | /* |
| 24695 | 24753 | ** This function is called to process SQL if the previous shell command |
| 24696 | 24754 | ** was ".expert". It passes the SQL in the second argument directly to |
| 24697 | 24755 | ** the sqlite3expert object. |
| 24698 | 24756 | ** |
| | @@ -24820,11 +24878,11 @@ |
| 24820 | 24878 | } |
| 24821 | 24879 | sqlite3_free(zErr); |
| 24822 | 24880 | |
| 24823 | 24881 | return rc; |
| 24824 | 24882 | } |
| 24825 | | -#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ |
| 24883 | +#endif /* !SQLITE_OMIT_VIRTUALTABLE && !SQLITE_OMIT_AUTHORIZATION */ |
| 24826 | 24884 | |
| 24827 | 24885 | /* |
| 24828 | 24886 | ** Execute a statement or set of statements. Print |
| 24829 | 24887 | ** any result rows/columns depending on the current mode |
| 24830 | 24888 | ** set via the supplied callback. |
| | @@ -24846,11 +24904,11 @@ |
| 24846 | 24904 | |
| 24847 | 24905 | if( pzErrMsg ){ |
| 24848 | 24906 | *pzErrMsg = NULL; |
| 24849 | 24907 | } |
| 24850 | 24908 | |
| 24851 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 24909 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 24852 | 24910 | if( pArg->expert.pExpert ){ |
| 24853 | 24911 | rc = expertHandleSQL(pArg, zSql, pzErrMsg); |
| 24854 | 24912 | return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); |
| 24855 | 24913 | } |
| 24856 | 24914 | #endif |
| | @@ -25008,11 +25066,11 @@ |
| 25008 | 25066 | static char **tableColumnList(ShellState *p, const char *zTab){ |
| 25009 | 25067 | char **azCol = 0; |
| 25010 | 25068 | sqlite3_stmt *pStmt; |
| 25011 | 25069 | char *zSql; |
| 25012 | 25070 | int nCol = 0; |
| 25013 | | - int nAlloc = 0; |
| 25071 | + i64 nAlloc = 0; |
| 25014 | 25072 | int nPK = 0; /* Number of PRIMARY KEY columns seen */ |
| 25015 | 25073 | int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ |
| 25016 | 25074 | int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); |
| 25017 | 25075 | int rc; |
| 25018 | 25076 | |
| | @@ -25022,11 +25080,11 @@ |
| 25022 | 25080 | sqlite3_free(zSql); |
| 25023 | 25081 | if( rc ) return 0; |
| 25024 | 25082 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 25025 | 25083 | if( nCol>=nAlloc-2 ){ |
| 25026 | 25084 | nAlloc = nAlloc*2 + nCol + 10; |
| 25027 | | - azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0])); |
| 25085 | + azCol = sqlite3_realloc64(azCol, nAlloc*sizeof(azCol[0])); |
| 25028 | 25086 | shell_check_oom(azCol); |
| 25029 | 25087 | } |
| 25030 | 25088 | azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); |
| 25031 | 25089 | shell_check_oom(azCol[nCol]); |
| 25032 | 25090 | if( sqlite3_column_int(pStmt, 5) ){ |
| | @@ -25352,11 +25410,13 @@ |
| 25352 | 25410 | " --bom Put a UTF8 byte-order mark on intermediate file", |
| 25353 | 25411 | #endif |
| 25354 | 25412 | #ifndef SQLITE_SHELL_FIDDLE |
| 25355 | 25413 | ".exit ?CODE? Exit this program with return-code CODE", |
| 25356 | 25414 | #endif |
| 25415 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 25357 | 25416 | ".expert EXPERIMENTAL. Suggest indexes for queries", |
| 25417 | +#endif |
| 25358 | 25418 | ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto", |
| 25359 | 25419 | ".filectrl CMD ... Run various sqlite3_file_control() operations", |
| 25360 | 25420 | " --schema SCHEMA Use SCHEMA instead of \"main\"", |
| 25361 | 25421 | " --help Show CMD details", |
| 25362 | 25422 | ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", |
| | @@ -25444,11 +25504,17 @@ |
| 25444 | 25504 | " Options:", |
| 25445 | 25505 | " --append Use appendvfs to append database to the end of FILE", |
| 25446 | 25506 | #endif |
| 25447 | 25507 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 25448 | 25508 | " --deserialize Load into memory using sqlite3_deserialize()", |
| 25509 | +#endif |
| 25510 | +/*" --exclusive Set the SQLITE_OPEN_EXCLUSIVE flag", UNDOCUMENTED */ |
| 25511 | +#ifndef SQLITE_OMIT_DESERIALIZE |
| 25449 | 25512 | " --hexdb Load the output of \"dbtotxt\" as an in-memory db", |
| 25513 | +#endif |
| 25514 | + " --ifexist Only open if FILE already exists", |
| 25515 | +#ifndef SQLITE_OMIT_DESERIALIZE |
| 25450 | 25516 | " --maxsize N Maximum size for --hexdb or --deserialized database", |
| 25451 | 25517 | #endif |
| 25452 | 25518 | " --new Initialize FILE to an empty database", |
| 25453 | 25519 | " --nofollow Do not follow symbolic links", |
| 25454 | 25520 | " --readonly Open FILE readonly", |
| | @@ -25865,11 +25931,11 @@ |
| 25865 | 25931 | if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ |
| 25866 | 25932 | sqlite3_fputs("invalid pagesize\n", stderr); |
| 25867 | 25933 | goto readHexDb_error; |
| 25868 | 25934 | } |
| 25869 | 25935 | sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */ |
| 25870 | | - a = sqlite3_malloc( sz ? sz : 1 ); |
| 25936 | + a = sqlite3_malloc64( sz ? sz : 1 ); |
| 25871 | 25937 | shell_check_oom(a); |
| 25872 | 25938 | memset(a, 0, sz); |
| 25873 | 25939 | for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ |
| 25874 | 25940 | int j = 0; /* Page number from "| page" line */ |
| 25875 | 25941 | int k = 0; /* Offset from "| page" line */ |
| | @@ -25989,14 +26055,17 @@ |
| 25989 | 26055 | }else{ |
| 25990 | 26056 | p->openMode = (u8)deduceDatabaseType(zDbFilename, |
| 25991 | 26057 | (openFlags & OPEN_DB_ZIPFILE)!=0); |
| 25992 | 26058 | } |
| 25993 | 26059 | } |
| 26060 | + if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){ |
| 26061 | + if( p->openFlags==0 ) p->openFlags = SQLITE_OPEN_CREATE; |
| 26062 | + p->openFlags |= SQLITE_OPEN_READWRITE; |
| 26063 | + } |
| 25994 | 26064 | switch( p->openMode ){ |
| 25995 | 26065 | case SHELL_OPEN_APPENDVFS: { |
| 25996 | | - sqlite3_open_v2(zDbFilename, &p->db, |
| 25997 | | - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs"); |
| 26066 | + sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, "apndvfs"); |
| 25998 | 26067 | break; |
| 25999 | 26068 | } |
| 26000 | 26069 | case SHELL_OPEN_HEXDB: |
| 26001 | 26070 | case SHELL_OPEN_DESERIALIZE: { |
| 26002 | 26071 | sqlite3_open(0, &p->db); |
| | @@ -26004,19 +26073,13 @@ |
| 26004 | 26073 | } |
| 26005 | 26074 | case SHELL_OPEN_ZIPFILE: { |
| 26006 | 26075 | sqlite3_open(":memory:", &p->db); |
| 26007 | 26076 | break; |
| 26008 | 26077 | } |
| 26009 | | - case SHELL_OPEN_READONLY: { |
| 26010 | | - sqlite3_open_v2(zDbFilename, &p->db, |
| 26011 | | - SQLITE_OPEN_READONLY|p->openFlags, 0); |
| 26012 | | - break; |
| 26013 | | - } |
| 26014 | 26078 | case SHELL_OPEN_UNSPEC: |
| 26015 | 26079 | case SHELL_OPEN_NORMAL: { |
| 26016 | | - sqlite3_open_v2(zDbFilename, &p->db, |
| 26017 | | - SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0); |
| 26080 | + sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, 0); |
| 26018 | 26081 | break; |
| 26019 | 26082 | } |
| 26020 | 26083 | } |
| 26021 | 26084 | if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
| 26022 | 26085 | sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n", |
| | @@ -26151,13 +26214,15 @@ |
| 26151 | 26214 | } |
| 26152 | 26215 | } |
| 26153 | 26216 | #endif |
| 26154 | 26217 | } |
| 26155 | 26218 | if( p->db!=0 ){ |
| 26219 | +#ifndef SQLITE_OMIT_AUTHORIZATION |
| 26156 | 26220 | if( p->bSafeModePersist ){ |
| 26157 | 26221 | sqlite3_set_authorizer(p->db, safeModeAuth, p); |
| 26158 | 26222 | } |
| 26223 | +#endif |
| 26159 | 26224 | sqlite3_db_config( |
| 26160 | 26225 | p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0 |
| 26161 | 26226 | ); |
| 26162 | 26227 | } |
| 26163 | 26228 | } |
| | @@ -26466,12 +26531,12 @@ |
| 26466 | 26531 | struct ImportCtx { |
| 26467 | 26532 | const char *zFile; /* Name of the input file */ |
| 26468 | 26533 | FILE *in; /* Read the CSV text from this input stream */ |
| 26469 | 26534 | int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */ |
| 26470 | 26535 | char *z; /* Accumulated text for a field */ |
| 26471 | | - int n; /* Number of bytes in z */ |
| 26472 | | - int nAlloc; /* Space allocated for z[] */ |
| 26536 | + i64 n; /* Number of bytes in z */ |
| 26537 | + i64 nAlloc; /* Space allocated for z[] */ |
| 26473 | 26538 | int nLine; /* Current line number */ |
| 26474 | 26539 | int nRow; /* Number of rows imported */ |
| 26475 | 26540 | int nErr; /* Number of errors encountered */ |
| 26476 | 26541 | int bNotFirst; /* True if one or more bytes already read */ |
| 26477 | 26542 | int cTerm; /* Character that terminated the most recent field */ |
| | @@ -27091,11 +27156,15 @@ |
| 27091 | 27156 | if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; |
| 27092 | 27157 | zTail = strrchr(zFilename, '/'); |
| 27093 | 27158 | #if defined(_WIN32) |
| 27094 | 27159 | if( zTail==0 ) zTail = strrchr(zFilename, '\\'); |
| 27095 | 27160 | #endif |
| 27096 | | - if( zTail && zTail[1]!=0 ) zTail++; |
| 27161 | + if( zTail==0 ){ |
| 27162 | + zTail = zFilename; |
| 27163 | + }else if( zTail[1]!=0 ){ |
| 27164 | + zTail++; |
| 27165 | + } |
| 27097 | 27166 | } |
| 27098 | 27167 | zName = strdup(zTail); |
| 27099 | 27168 | shell_check_oom(zName); |
| 27100 | 27169 | sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", |
| 27101 | 27170 | nPage*pgSz, pgSz, zName); |
| | @@ -28816,11 +28885,11 @@ |
| 28816 | 28885 | int nArg = 0; |
| 28817 | 28886 | int n, c; |
| 28818 | 28887 | int rc = 0; |
| 28819 | 28888 | char *azArg[52]; |
| 28820 | 28889 | |
| 28821 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 28890 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 28822 | 28891 | if( p->expert.pExpert ){ |
| 28823 | 28892 | expertFinish(p, 1, 0); |
| 28824 | 28893 | } |
| 28825 | 28894 | #endif |
| 28826 | 28895 | |
| | @@ -29117,11 +29186,11 @@ |
| 29117 | 29186 | }else{ |
| 29118 | 29187 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 29119 | 29188 | const char *zSchema = (const char *)sqlite3_column_text(pStmt,1); |
| 29120 | 29189 | const char *zFile = (const char*)sqlite3_column_text(pStmt,2); |
| 29121 | 29190 | if( zSchema==0 || zFile==0 ) continue; |
| 29122 | | - azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*)); |
| 29191 | + azName = sqlite3_realloc64(azName, (nName+1)*2*sizeof(char*)); |
| 29123 | 29192 | shell_check_oom(azName); |
| 29124 | 29193 | azName[nName*2] = strdup(zSchema); |
| 29125 | 29194 | azName[nName*2+1] = strdup(zFile); |
| 29126 | 29195 | nName++; |
| 29127 | 29196 | } |
| | @@ -29385,11 +29454,11 @@ |
| 29385 | 29454 | if( p->mode==MODE_Explain ) p->mode = p->normalMode; |
| 29386 | 29455 | p->autoExplain = 1; |
| 29387 | 29456 | } |
| 29388 | 29457 | }else |
| 29389 | 29458 | |
| 29390 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 29459 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 29391 | 29460 | if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ |
| 29392 | 29461 | if( p->bSafeMode ){ |
| 29393 | 29462 | sqlite3_fprintf(stderr, |
| 29394 | 29463 | "Cannot run experimental commands such as \"%s\" in safe mode\n", |
| 29395 | 29464 | azArg[0]); |
| | @@ -30385,10 +30454,11 @@ |
| 30385 | 30454 | const char *zFN = 0; /* Pointer to constant filename */ |
| 30386 | 30455 | char *zNewFilename = 0; /* Name of the database file to open */ |
| 30387 | 30456 | int iName = 1; /* Index in azArg[] of the filename */ |
| 30388 | 30457 | int newFlag = 0; /* True to delete file before opening */ |
| 30389 | 30458 | int openMode = SHELL_OPEN_UNSPEC; |
| 30459 | + int openFlags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; |
| 30390 | 30460 | |
| 30391 | 30461 | /* Check for command-line arguments */ |
| 30392 | 30462 | for(iName=1; iName<nArg; iName++){ |
| 30393 | 30463 | const char *z = azArg[iName]; |
| 30394 | 30464 | #ifndef SQLITE_SHELL_FIDDLE |
| | @@ -30399,13 +30469,18 @@ |
| 30399 | 30469 | openMode = SHELL_OPEN_ZIPFILE; |
| 30400 | 30470 | #endif |
| 30401 | 30471 | }else if( optionMatch(z, "append") ){ |
| 30402 | 30472 | openMode = SHELL_OPEN_APPENDVFS; |
| 30403 | 30473 | }else if( optionMatch(z, "readonly") ){ |
| 30404 | | - openMode = SHELL_OPEN_READONLY; |
| 30474 | + openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 30475 | + openFlags |= SQLITE_OPEN_READONLY; |
| 30476 | + }else if( optionMatch(z, "exclusive") ){ |
| 30477 | + openFlags |= SQLITE_OPEN_EXCLUSIVE; |
| 30478 | + }else if( optionMatch(z, "ifexists") ){ |
| 30479 | + openFlags &= ~(SQLITE_OPEN_CREATE); |
| 30405 | 30480 | }else if( optionMatch(z, "nofollow") ){ |
| 30406 | | - p->openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 30481 | + openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 30407 | 30482 | #ifndef SQLITE_OMIT_DESERIALIZE |
| 30408 | 30483 | }else if( optionMatch(z, "deserialize") ){ |
| 30409 | 30484 | openMode = SHELL_OPEN_DESERIALIZE; |
| 30410 | 30485 | }else if( optionMatch(z, "hexdb") ){ |
| 30411 | 30486 | openMode = SHELL_OPEN_HEXDB; |
| | @@ -30433,11 +30508,11 @@ |
| 30433 | 30508 | p->db = 0; |
| 30434 | 30509 | p->pAuxDb->zDbFilename = 0; |
| 30435 | 30510 | sqlite3_free(p->pAuxDb->zFreeOnClose); |
| 30436 | 30511 | p->pAuxDb->zFreeOnClose = 0; |
| 30437 | 30512 | p->openMode = openMode; |
| 30438 | | - p->openFlags = 0; |
| 30513 | + p->openFlags = openFlags; |
| 30439 | 30514 | p->szMax = 0; |
| 30440 | 30515 | |
| 30441 | 30516 | /* If a filename is specified, try to open it first */ |
| 30442 | 30517 | if( zFN || p->openMode==SHELL_OPEN_HEXDB ){ |
| 30443 | 30518 | if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN); |
| | @@ -31175,19 +31250,20 @@ |
| 31175 | 31250 | |
| 31176 | 31251 | /* .session filter GLOB .... |
| 31177 | 31252 | ** Set a list of GLOB patterns of table names to be excluded. |
| 31178 | 31253 | */ |
| 31179 | 31254 | if( cli_strcmp(azCmd[0], "filter")==0 ){ |
| 31180 | | - int ii, nByte; |
| 31255 | + int ii; |
| 31256 | + i64 nByte; |
| 31181 | 31257 | if( nCmd<2 ) goto session_syntax_error; |
| 31182 | 31258 | if( pAuxDb->nSession ){ |
| 31183 | 31259 | for(ii=0; ii<pSession->nFilter; ii++){ |
| 31184 | 31260 | sqlite3_free(pSession->azFilter[ii]); |
| 31185 | 31261 | } |
| 31186 | 31262 | sqlite3_free(pSession->azFilter); |
| 31187 | 31263 | nByte = sizeof(pSession->azFilter[0])*(nCmd-1); |
| 31188 | | - pSession->azFilter = sqlite3_malloc( nByte ); |
| 31264 | + pSession->azFilter = sqlite3_malloc64( nByte ); |
| 31189 | 31265 | shell_check_oom( pSession->azFilter ); |
| 31190 | 31266 | for(ii=1; ii<nCmd; ii++){ |
| 31191 | 31267 | char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); |
| 31192 | 31268 | shell_check_oom(x); |
| 31193 | 31269 | } |
| | @@ -33121,10 +33197,11 @@ |
| 33121 | 33197 | #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) |
| 33122 | 33198 | " -heap SIZE Size of heap for memsys3 or memsys5\n" |
| 33123 | 33199 | #endif |
| 33124 | 33200 | " -help show this message\n" |
| 33125 | 33201 | " -html set output mode to HTML\n" |
| 33202 | + " -ifexists only open if database already exists\n" |
| 33126 | 33203 | " -interactive force interactive I/O\n" |
| 33127 | 33204 | " -json set output mode to 'json'\n" |
| 33128 | 33205 | " -line set output mode to 'line'\n" |
| 33129 | 33206 | " -list set output mode to 'list'\n" |
| 33130 | 33207 | " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" |
| | @@ -33533,13 +33610,19 @@ |
| 33533 | 33610 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33534 | 33611 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33535 | 33612 | data.szMax = integerValue(argv[++i]); |
| 33536 | 33613 | #endif |
| 33537 | 33614 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33538 | | - data.openMode = SHELL_OPEN_READONLY; |
| 33615 | + data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 33616 | + data.openFlags |= SQLITE_OPEN_READONLY; |
| 33539 | 33617 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33540 | | - data.openFlags = SQLITE_OPEN_NOFOLLOW; |
| 33618 | + data.openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 33619 | + }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ |
| 33620 | + data.openFlags |= SQLITE_OPEN_EXCLUSIVE; |
| 33621 | + }else if( cli_strcmp(z,"-ifexists")==0 ){ |
| 33622 | + data.openFlags &= ~(SQLITE_OPEN_CREATE); |
| 33623 | + if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; |
| 33541 | 33624 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
| 33542 | 33625 | }else if( cli_strncmp(z, "-A",2)==0 ){ |
| 33543 | 33626 | /* All remaining command-line arguments are passed to the ".archive" |
| 33544 | 33627 | ** command, so ignore them */ |
| 33545 | 33628 | break; |
| | @@ -33689,13 +33772,19 @@ |
| 33689 | 33772 | data.openMode = SHELL_OPEN_DESERIALIZE; |
| 33690 | 33773 | }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ |
| 33691 | 33774 | data.szMax = integerValue(argv[++i]); |
| 33692 | 33775 | #endif |
| 33693 | 33776 | }else if( cli_strcmp(z,"-readonly")==0 ){ |
| 33694 | | - data.openMode = SHELL_OPEN_READONLY; |
| 33777 | + data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
| 33778 | + data.openFlags |= SQLITE_OPEN_READONLY; |
| 33695 | 33779 | }else if( cli_strcmp(z,"-nofollow")==0 ){ |
| 33696 | 33780 | data.openFlags |= SQLITE_OPEN_NOFOLLOW; |
| 33781 | + }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ |
| 33782 | + data.openFlags |= SQLITE_OPEN_EXCLUSIVE; |
| 33783 | + }else if( cli_strcmp(z,"-ifexists")==0 ){ |
| 33784 | + data.openFlags &= ~(SQLITE_OPEN_CREATE); |
| 33785 | + if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; |
| 33697 | 33786 | }else if( cli_strcmp(z,"-ascii")==0 ){ |
| 33698 | 33787 | data.mode = MODE_Ascii; |
| 33699 | 33788 | sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit); |
| 33700 | 33789 | sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record); |
| 33701 | 33790 | }else if( cli_strcmp(z,"-tabs")==0 ){ |
| | @@ -33912,11 +34001,11 @@ |
| 33912 | 34001 | } |
| 33913 | 34002 | } |
| 33914 | 34003 | #ifndef SQLITE_SHELL_FIDDLE |
| 33915 | 34004 | /* In WASM mode we have to leave the db state in place so that |
| 33916 | 34005 | ** client code can "push" SQL into it after this call returns. */ |
| 33917 | | -#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 34006 | +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) |
| 33918 | 34007 | if( data.expert.pExpert ){ |
| 33919 | 34008 | expertFinish(&data, 1, 0); |
| 33920 | 34009 | } |
| 33921 | 34010 | #endif |
| 33922 | 34011 | shell_main_exit: |
| 33923 | 34012 | |