Skip to content

Commit bde2fd8

Browse files
committed
Prepare release of version 1.8.5
- Based on SQLite version 3.46.0
1 parent 80722b0 commit bde2fd8

File tree

12 files changed

+12424
-7124
lines changed

12 files changed

+12424
-7124
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.8.5] - 2024-05-24
11+
12+
### Changed
13+
14+
- Based on SQLite version 3.46.0
15+
1016
## [1.8.4] - 2024-03-14
1117

1218
### Changed
@@ -488,7 +494,8 @@ The following ciphers are supported:
488494
- AES 256 Bit CBC - SHA1/SHA256/SHA512 HMAC ([SQLCipher](https://www.zetetic.net/sqlcipher/), database versions 1, 2, 3, and 4)
489495
- RC4 - No HMAC ([System.Data.SQLite](http://system.data.sqlite.org))
490496

491-
[Unreleased]: ../../compare/v1.8.4...HEAD
497+
[Unreleased]: ../../compare/v1.8.5...HEAD
498+
[1.8.5]: ../../compare/v1.8.4...v1.8.5
492499
[1.8.4]: ../../compare/v1.8.3...v1.8.4
493500
[1.8.3]: ../../compare/v1.8.2...v1.8.3
494501
[1.8.2]: ../../compare/v1.8.1...v1.8.2

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ dnl Copyright (C) 2019-2024 Ulrich Telle <[email protected]>
44
dnl
55
dnl This file is covered by the same licence as the entire SQLite3 Multiple Ciphers package.
66

7-
AC_INIT([sqlite3mc], [1.8.4], [[email protected]])
7+
AC_INIT([sqlite3mc], [1.8.5], [[email protected]])
88

99
dnl This is the version tested with, might work with earlier ones.
1010
AC_PREREQ([2.69])

readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ The code was mainly developed under Windows, but was tested under Linux as well.
1010

1111
## Version information
1212

13-
* 1.8.4 - *March 2024*
14-
- Based on SQLite version 3.45.5
13+
* 1.8.5 - *May 2024*
14+
- Based on SQLite version 3.46.0
1515
- Disable user authentication extension by default
1616

1717
For further version information please consult the [CHANGELOG](CHANGELOG.md).

src/fileio.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,9 @@ static int writeFile(
372372
#if !defined(_WIN32) && !defined(WIN32)
373373
if( S_ISLNK(mode) ){
374374
const char *zTo = (const char*)sqlite3_value_text(pData);
375-
if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
375+
if( zTo==0 ) return 1;
376+
unlink(zFile);
377+
if( symlink(zTo, zFile)<0 ) return 1;
376378
}else
377379
#endif
378380
{
@@ -458,13 +460,19 @@ static int writeFile(
458460
return 1;
459461
}
460462
#else
461-
/* Legacy unix */
462-
struct timeval times[2];
463-
times[0].tv_usec = times[1].tv_usec = 0;
464-
times[0].tv_sec = time(0);
465-
times[1].tv_sec = mtime;
466-
if( utimes(zFile, times) ){
467-
return 1;
463+
/* Legacy unix.
464+
**
465+
** Do not use utimes() on a symbolic link - it sees through the link and
466+
** modifies the timestamps on the target. Or fails if the target does
467+
** not exist. */
468+
if( 0==S_ISLNK(mode) ){
469+
struct timeval times[2];
470+
times[0].tv_usec = times[1].tv_usec = 0;
471+
times[0].tv_sec = time(0);
472+
times[1].tv_sec = mtime;
473+
if( utimes(zFile, times) ){
474+
return 1;
475+
}
468476
}
469477
#endif
470478
}

src/rekeyvacuum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
** Change 4: Call sqlite3mcBtreeSetPageSize instead of sqlite3BtreeSetPageSize for main database
2828
** (sqlite3mcBtreeSetPageSize allows to reduce the number of reserved bytes)
2929
**
30-
** This code is generated by the script rekeyvacuum.sh from SQLite version 3.45.2 amalgamation.
30+
** This code is generated by the script rekeyvacuum.sh from SQLite version 3.46.0 amalgamation.
3131
*/
3232
SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey(
3333
char **pzErrMsg, /* Write error message here */

src/series.c

Lines changed: 88 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,20 @@ SQLITE_EXTENSION_INIT1
103103
** index is ix. The 0th member is given by smBase. The sequence members
104104
** progress per ix increment by smStep.
105105
*/
106-
static sqlite3_int64 genSeqMember(sqlite3_int64 smBase,
107-
sqlite3_int64 smStep,
108-
sqlite3_uint64 ix){
109-
if( ix>=(sqlite3_uint64)LLONG_MAX ){
106+
static sqlite3_int64 genSeqMember(
107+
sqlite3_int64 smBase,
108+
sqlite3_int64 smStep,
109+
sqlite3_uint64 ix
110+
){
111+
static const sqlite3_uint64 mxI64 =
112+
((sqlite3_uint64)0x7fffffff)<<32 | 0xffffffff;
113+
if( ix>=mxI64 ){
110114
/* Get ix into signed i64 range. */
111-
ix -= (sqlite3_uint64)LLONG_MAX;
115+
ix -= mxI64;
112116
/* With 2's complement ALU, this next can be 1 step, but is split into
113117
* 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */
114-
smBase += (LLONG_MAX/2) * smStep;
115-
smBase += (LLONG_MAX - LLONG_MAX/2) * smStep;
118+
smBase += (mxI64/2) * smStep;
119+
smBase += (mxI64 - mxI64/2) * smStep;
116120
}
117121
/* Under UBSAN (or on 1's complement machines), must do this last term
118122
* in steps to avoid the dreaded (and harmless) signed multiply overlow. */
@@ -372,13 +376,13 @@ static int seriesEof(sqlite3_vtab_cursor *cur){
372376
** parameter. (idxStr is not used in this implementation.) idxNum
373377
** is a bitmask showing which constraints are available:
374378
**
375-
** 1: start=VALUE
376-
** 2: stop=VALUE
377-
** 4: step=VALUE
378-
**
379-
** Also, if bit 8 is set, that means that the series should be output
380-
** in descending order rather than in ascending order. If bit 16 is
381-
** set, then output must appear in ascending order.
379+
** 0x01: start=VALUE
380+
** 0x02: stop=VALUE
381+
** 0x04: step=VALUE
382+
** 0x08: descending order
383+
** 0x10: ascending order
384+
** 0x20: LIMIT VALUE
385+
** 0x40: OFFSET VALUE
382386
**
383387
** This routine should initialize the cursor and position it so that it
384388
** is pointing at the first row, or pointing off the end of the table
@@ -392,26 +396,44 @@ static int seriesFilter(
392396
series_cursor *pCur = (series_cursor *)pVtabCursor;
393397
int i = 0;
394398
(void)idxStrUnused;
395-
if( idxNum & 1 ){
399+
if( idxNum & 0x01 ){
396400
pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
397401
}else{
398402
pCur->ss.iBase = 0;
399403
}
400-
if( idxNum & 2 ){
404+
if( idxNum & 0x02 ){
401405
pCur->ss.iTerm = sqlite3_value_int64(argv[i++]);
402406
}else{
403407
pCur->ss.iTerm = 0xffffffff;
404408
}
405-
if( idxNum & 4 ){
409+
if( idxNum & 0x04 ){
406410
pCur->ss.iStep = sqlite3_value_int64(argv[i++]);
407411
if( pCur->ss.iStep==0 ){
408412
pCur->ss.iStep = 1;
409413
}else if( pCur->ss.iStep<0 ){
410-
if( (idxNum & 16)==0 ) idxNum |= 8;
414+
if( (idxNum & 0x10)==0 ) idxNum |= 0x08;
411415
}
412416
}else{
413417
pCur->ss.iStep = 1;
414418
}
419+
if( idxNum & 0x20 ){
420+
sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]);
421+
sqlite3_int64 iTerm;
422+
if( idxNum & 0x40 ){
423+
sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]);
424+
if( iOffset>0 ){
425+
pCur->ss.iBase += pCur->ss.iStep*iOffset;
426+
}
427+
}
428+
if( iLimit>=0 ){
429+
iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
430+
if( pCur->ss.iStep<0 ){
431+
if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
432+
}else{
433+
if( iTerm<pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
434+
}
435+
}
436+
}
415437
for(i=0; i<argc; i++){
416438
if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
417439
/* If any of the constraints have a NULL value, then return no rows.
@@ -422,7 +444,7 @@ static int seriesFilter(
422444
break;
423445
}
424446
}
425-
if( idxNum & 8 ){
447+
if( idxNum & 0x08 ){
426448
pCur->ss.isReversing = pCur->ss.iStep > 0;
427449
}else{
428450
pCur->ss.isReversing = pCur->ss.iStep < 0;
@@ -442,50 +464,81 @@ static int seriesFilter(
442464
**
443465
** The query plan is represented by bits in idxNum:
444466
**
445-
** (1) start = $value -- constraint exists
446-
** (2) stop = $value -- constraint exists
447-
** (4) step = $value -- constraint exists
448-
** (8) output in descending order
467+
** 0x01 start = $value -- constraint exists
468+
** 0x02 stop = $value -- constraint exists
469+
** 0x04 step = $value -- constraint exists
470+
** 0x08 output is in descending order
471+
** 0x10 output is in ascending order
472+
** 0x20 LIMIT $value -- constraint exists
473+
** 0x40 OFFSET $value -- constraint exists
449474
*/
450475
static int seriesBestIndex(
451476
sqlite3_vtab *pVTab,
452477
sqlite3_index_info *pIdxInfo
453478
){
454479
int i, j; /* Loop over constraints */
455480
int idxNum = 0; /* The query plan bitmask */
481+
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
456482
int bStartSeen = 0; /* EQ constraint seen on the START column */
483+
#endif
457484
int unusableMask = 0; /* Mask of unusable constraints */
458485
int nArg = 0; /* Number of arguments that seriesFilter() expects */
459-
int aIdx[3]; /* Constraints on start, stop, and step */
486+
int aIdx[5]; /* Constraints on start, stop, step, LIMIT, OFFSET */
460487
const struct sqlite3_index_constraint *pConstraint;
461488

462489
/* This implementation assumes that the start, stop, and step columns
463490
** are the last three columns in the virtual table. */
464491
assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
465492
assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
466493

467-
aIdx[0] = aIdx[1] = aIdx[2] = -1;
494+
aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1;
468495
pConstraint = pIdxInfo->aConstraint;
469496
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
470497
int iCol; /* 0 for start, 1 for stop, 2 for step */
471498
int iMask; /* bitmask for those column */
499+
int op = pConstraint->op;
500+
if( op>=SQLITE_INDEX_CONSTRAINT_LIMIT
501+
&& op<=SQLITE_INDEX_CONSTRAINT_OFFSET
502+
){
503+
if( pConstraint->usable==0 ){
504+
/* do nothing */
505+
}else if( op==SQLITE_INDEX_CONSTRAINT_LIMIT ){
506+
aIdx[3] = i;
507+
idxNum |= 0x20;
508+
}else{
509+
assert( op==SQLITE_INDEX_CONSTRAINT_OFFSET );
510+
aIdx[4] = i;
511+
idxNum |= 0x40;
512+
}
513+
continue;
514+
}
472515
if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
473516
iCol = pConstraint->iColumn - SERIES_COLUMN_START;
474517
assert( iCol>=0 && iCol<=2 );
475518
iMask = 1 << iCol;
476-
if( iCol==0 ) bStartSeen = 1;
519+
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
520+
if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){
521+
bStartSeen = 1;
522+
}
523+
#endif
477524
if( pConstraint->usable==0 ){
478525
unusableMask |= iMask;
479526
continue;
480-
}else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
527+
}else if( op==SQLITE_INDEX_CONSTRAINT_EQ ){
481528
idxNum |= iMask;
482529
aIdx[iCol] = i;
483530
}
484531
}
485-
for(i=0; i<3; i++){
532+
if( aIdx[3]==0 ){
533+
/* Ignore OFFSET if LIMIT is omitted */
534+
idxNum &= ~0x60;
535+
aIdx[4] = 0;
536+
}
537+
for(i=0; i<5; i++){
486538
if( (j = aIdx[i])>=0 ){
487539
pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
488-
pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
540+
pIdxInfo->aConstraintUsage[j].omit =
541+
!SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3;
489542
}
490543
}
491544
/* The current generate_column() implementation requires at least one
@@ -506,19 +559,22 @@ static int seriesBestIndex(
506559
** this plan is unusable */
507560
return SQLITE_CONSTRAINT;
508561
}
509-
if( (idxNum & 3)==3 ){
562+
if( (idxNum & 0x03)==0x03 ){
510563
/* Both start= and stop= boundaries are available. This is the
511564
** the preferred case */
512565
pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
513566
pIdxInfo->estimatedRows = 1000;
514567
if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){
515568
if( pIdxInfo->aOrderBy[0].desc ){
516-
idxNum |= 8;
569+
idxNum |= 0x08;
517570
}else{
518-
idxNum |= 16;
571+
idxNum |= 0x10;
519572
}
520573
pIdxInfo->orderByConsumed = 1;
521574
}
575+
}else if( (idxNum & 0x21)==0x21 ){
576+
/* We have start= and LIMIT */
577+
pIdxInfo->estimatedRows = 2500;
522578
}else{
523579
/* If either boundary is missing, we have to generate a huge span
524580
** of numbers. Make this case very expensive so that the query

0 commit comments

Comments
 (0)