Skip to content

Commit ecbf9b2

Browse files
committed
Merge "SQLite master branch - Dec 15th 2022" from Piotr Sarna
2 parents a5a0371 + 69010a5 commit ecbf9b2

77 files changed

Lines changed: 5940 additions & 2181 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ext/misc/base64.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ static const ubyte b64DigitValues[128] = {
9191
static const char b64Numerals[64+1]
9292
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
9393

94-
#define BX_DV_PROTO(c) ((((ubyte)(c))<0x80)? b64DigitValues[c] : 0x80)
94+
#define BX_DV_PROTO(c) \
95+
((((ubyte)(c))<0x80)? (ubyte)(b64DigitValues[(ubyte)(c)]) : 0x80)
9596
#define IS_BX_DIGIT(bdp) (((ubyte)(bdp))<0x80)
9697
#define IS_BX_WS(bdp) ((bdp)==WS)
9798
#define IS_BX_PAD(bdp) ((bdp)==PC)

ext/misc/basexx.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ int sqlite3_basexx_init(sqlite3 *db, char **pzErr,
6969
init_api_ptr(pApi);
7070
int rc1 = BASE64_INIT(db);
7171
int rc2 = BASE85_INIT(db);
72-
int rc = SQLITE_OK;
7372

7473
if( rc1==SQLITE_OK && rc2==SQLITE_OK ){
7574
BASE64_EXPOSE(db, pzErr);

ext/rbu/rbuB.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ do_test 1.2 {
4848

4949
do_test 1.3 {
5050
set ::errlog
51-
} {SQLITE_NOTICE_RECOVER_WAL SQLITE_INTERNAL}
51+
} {SQLITE_NOTICE_RECOVER_WAL SQLITE_NOTICE_RBU}
5252

5353
do_execsql_test 1.4 {
5454
SELECT * FROM t1

ext/rbu/sqlite3rbu.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3031,11 +3031,11 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
30313031
** no-ops. These locks will not be released until the connection
30323032
** is closed.
30333033
**
3034-
** * Attempting to xSync() the database file causes an SQLITE_INTERNAL
3034+
** * Attempting to xSync() the database file causes an SQLITE_NOTICE
30353035
** error.
30363036
**
30373037
** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the
3038-
** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[]
3038+
** checkpoint below fails with SQLITE_NOTICE, and leaves the aFrame[]
30393039
** array populated with a set of (frame -> page) mappings. Because the
30403040
** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy
30413041
** data from the wal file into the database file according to the
@@ -3045,7 +3045,7 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
30453045
int rc2;
30463046
p->eStage = RBU_STAGE_CAPTURE;
30473047
rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
3048-
if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
3048+
if( rc2!=SQLITE_NOTICE ) p->rc = rc2;
30493049
}
30503050

30513051
if( p->rc==SQLITE_OK && p->nFrame>0 ){
@@ -3091,7 +3091,7 @@ static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){
30913091

30923092
if( pRbu->mLock!=mReq ){
30933093
pRbu->rc = SQLITE_BUSY;
3094-
return SQLITE_INTERNAL;
3094+
return SQLITE_NOTICE_RBU;
30953095
}
30963096

30973097
pRbu->pgsz = iAmt;
@@ -4478,7 +4478,7 @@ void sqlite3rbu_rename_handler(
44784478
** database file are recorded. xShmLock() calls to unlock the same
44794479
** locks are no-ops (so that once obtained, these locks are never
44804480
** relinquished). Finally, calls to xSync() on the target database
4481-
** file fail with SQLITE_INTERNAL errors.
4481+
** file fail with SQLITE_NOTICE errors.
44824482
*/
44834483

44844484
static void rbuUnlockShm(rbu_file *p){
@@ -4757,7 +4757,7 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){
47574757
rbu_file *p = (rbu_file *)pFile;
47584758
if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){
47594759
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
4760-
return SQLITE_INTERNAL;
4760+
return SQLITE_NOTICE_RBU;
47614761
}
47624762
return SQLITE_OK;
47634763
}

ext/session/sessionat.test

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,60 @@ eval [string map [list %WR% $trailing] {
243243
sqlite3changeset_apply db $cinv xConflict
244244
execsql { SELECT * FROM t7 }
245245
} {1 1 ccc 2 2 ccc 3 3 ccc}
246+
247+
#-----------------------------------------------------------------------
248+
reset_test
249+
do_execsql_test $tn.7.0 {
250+
CREATE TABLE t8(a PRIMARY KEY, b, c);
251+
}
252+
do_execsql_test -db db2 $tn.7.1 {
253+
CREATE TABLE t8(a PRIMARY KEY, b, c, d DEFAULT 'D', e DEFAULT 'E');
254+
}
255+
256+
do_then_apply_sql {
257+
INSERT INTO t8 VALUES(1, 2, 3);
258+
INSERT INTO t8 VALUES(4, 5, 6);
259+
}
260+
do_execsql_test $tn.7.2.1 {
261+
SELECT * FROM t8
262+
} {1 2 3 4 5 6}
263+
do_execsql_test -db db2 $tn.7.2.2 {
264+
SELECT * FROM t8
265+
} {1 2 3 D E 4 5 6 D E}
266+
267+
do_then_apply_sql {
268+
UPDATE t8 SET c=45 WHERE a=4;
269+
}
270+
do_execsql_test $tn.7.3.1 {
271+
SELECT * FROM t8
272+
} {1 2 3 4 5 45}
273+
do_execsql_test -db db2 $tn.7.3.2 {
274+
SELECT * FROM t8
275+
} {1 2 3 D E 4 5 45 D E}
276+
277+
#-----------------------------------------------------------------------
278+
reset_test
279+
do_execsql_test $tn.8.0 {
280+
CREATE TABLE t9(a PRIMARY KEY, b, c, d, e, f, g, h);
281+
}
282+
do_execsql_test -db db2 $tn.8.1 {
283+
CREATE TABLE t9(a PRIMARY KEY, b, c, d, e, f, g, h, i, j, k, l);
284+
}
285+
do_then_apply_sql {
286+
INSERT INTO t9 VALUES(1, 2, 3, 4, 5, 6, 7, 8);
287+
}
288+
do_then_apply_sql {
289+
UPDATE t9 SET h=450 WHERE a=1
290+
}
291+
do_execsql_test -db db2 $tn.8.2 {
292+
SELECT * FROM t9
293+
} {1 2 3 4 5 6 7 450 {} {} {} {}}
294+
do_then_apply_sql {
295+
UPDATE t9 SET h=NULL
296+
}
297+
do_execsql_test -db db2 $tn.8.2 {
298+
SELECT * FROM t9
299+
} {1 2 3 4 5 6 7 {} {} {} {} {}}
246300
}]
247301
}
248302

ext/session/sqlite3session.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3327,6 +3327,22 @@ static int sessionChangesetNextOne(
33273327
if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
33283328
else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
33293329
}
3330+
3331+
/* If this is an UPDATE that is part of a changeset, then check that
3332+
** there are no fields in the old.* record that are not (a) PK fields,
3333+
** or (b) also present in the new.* record.
3334+
**
3335+
** Such records are technically corrupt, but the rebaser was at one
3336+
** point generating them. Under most circumstances this is benign, but
3337+
** can cause spurious SQLITE_RANGE errors when applying the changeset. */
3338+
if( p->bPatchset==0 && p->op==SQLITE_UPDATE){
3339+
for(i=0; i<p->nCol; i++){
3340+
if( p->abPK[i]==0 && p->apValue[i+p->nCol]==0 ){
3341+
sqlite3ValueFree(p->apValue[i]);
3342+
p->apValue[i] = 0;
3343+
}
3344+
}
3345+
}
33303346
}
33313347

33323348
return SQLITE_ROW;
@@ -5523,7 +5539,7 @@ static void sessionAppendPartialUpdate(
55235539
if( !pIter->abPK[i] && a1[0] ) bData = 1;
55245540
memcpy(pOut, a1, n1);
55255541
pOut += n1;
5526-
}else if( a2[0]!=0xFF ){
5542+
}else if( a2[0]!=0xFF && a1[0] ){
55275543
bData = 1;
55285544
memcpy(pOut, a2, n2);
55295545
pOut += n2;

ext/session/test_session.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,19 @@ int sql_exec_changeset(
9898
}
9999
/************************************************************************/
100100

101+
102+
#ifdef SQLITE_DEBUG
103+
static int sqlite3_test_changeset(int, void *, char **);
104+
static void assert_changeset_is_ok(int n, void *p){
105+
int rc = 0;
106+
char *z = 0;
107+
rc = sqlite3_test_changeset(n, p, &z);
108+
assert( z==0 );
109+
}
110+
#else
111+
# define assert_changeset_is_ok(n,p)
112+
#endif
113+
101114
/*
102115
** Tclcmd: sql_exec_changeset DB SQL
103116
*/
@@ -127,6 +140,7 @@ static int SQLITE_TCLAPI test_sql_exec_changeset(
127140
return TCL_ERROR;
128141
}
129142

143+
assert_changeset_is_ok(nChangeset, pChangeset);
130144
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pChangeset, nChangeset));
131145
sqlite3_free(pChangeset);
132146
return TCL_OK;
@@ -295,6 +309,7 @@ static int SQLITE_TCLAPI test_session_cmd(
295309
}
296310
}
297311
if( rc==SQLITE_OK ){
312+
assert_changeset_is_ok(o.n, o.p);
298313
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(o.p, o.n));
299314
}
300315
sqlite3_free(o.p);
@@ -953,6 +968,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_invert(
953968
if( rc!=SQLITE_OK ){
954969
rc = test_session_error(interp, rc, 0);
955970
}else{
971+
assert_changeset_is_ok(sOut.n, sOut.p);
956972
Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n));
957973
}
958974
sqlite3_free(sOut.p);
@@ -1001,6 +1017,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_concat(
10011017
if( rc!=SQLITE_OK ){
10021018
rc = test_session_error(interp, rc, 0);
10031019
}else{
1020+
assert_changeset_is_ok(sOut.n, sOut.p);
10041021
Tcl_SetObjResult(interp,Tcl_NewByteArrayObj((unsigned char*)sOut.p,sOut.n));
10051022
}
10061023
sqlite3_free(sOut.p);
@@ -1236,6 +1253,7 @@ static int SQLITE_TCLAPI test_rebaser_cmd(
12361253
}
12371254

12381255
if( rc==SQLITE_OK ){
1256+
assert_changeset_is_ok(sOut.n, sOut.p);
12391257
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(sOut.p, sOut.n));
12401258
}
12411259
sqlite3_free(sOut.p);
@@ -1282,6 +1300,107 @@ static int SQLITE_TCLAPI test_sqlite3rebaser_create(
12821300
return TCL_OK;
12831301
}
12841302

1303+
/*
1304+
** Run some sanity checks on the changeset in nChangeset byte buffer
1305+
** pChangeset. If any fail, return a non-zero value and, optionally,
1306+
** set output variable (*pzErr) to point to a buffer containing an
1307+
** English language error message describing the problem. In this
1308+
** case it is the responsibility of the caller to free the buffer
1309+
** using sqlite3_free().
1310+
**
1311+
** Or, if the changeset appears to be well-formed, this function
1312+
** returns SQLITE_OK and sets (*pzErr) to NULL.
1313+
*/
1314+
static int sqlite3_test_changeset(
1315+
int nChangeset,
1316+
void *pChangeset,
1317+
char **pzErr
1318+
){
1319+
sqlite3_changeset_iter *pIter = 0;
1320+
char *zErr = 0;
1321+
int rc = SQLITE_OK;
1322+
int bPatch = (nChangeset>0 && ((char*)pChangeset)[0]=='P');
1323+
1324+
rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
1325+
if( rc==SQLITE_OK ){
1326+
int rc2;
1327+
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){
1328+
unsigned char *aPk = 0;
1329+
int nCol = 0;
1330+
int op = 0;
1331+
const char *zTab = 0;
1332+
1333+
sqlite3changeset_pk(pIter, &aPk, &nCol);
1334+
sqlite3changeset_op(pIter, &zTab, &nCol, &op, 0);
1335+
1336+
if( op==SQLITE_UPDATE ){
1337+
int iCol;
1338+
for(iCol=0; iCol<nCol; iCol++){
1339+
sqlite3_value *pNew = 0;
1340+
sqlite3_value *pOld = 0;
1341+
sqlite3changeset_new(pIter, iCol, &pNew);
1342+
sqlite3changeset_old(pIter, iCol, &pOld);
1343+
1344+
if( aPk[iCol] ){
1345+
if( pOld==0 ) rc = SQLITE_ERROR;
1346+
}else if( bPatch ){
1347+
if( pOld ) rc = SQLITE_ERROR;
1348+
}else{
1349+
if( (pOld==0)!=(pNew==0) ) rc = SQLITE_ERROR;
1350+
}
1351+
1352+
if( rc!=SQLITE_OK ){
1353+
zErr = sqlite3_mprintf(
1354+
"unexpected SQLITE_UPDATE (bPatch=%d pk=%d pOld=%d pNew=%d)",
1355+
bPatch, (int)aPk[iCol], pOld!=0, pNew!=0
1356+
);
1357+
break;
1358+
}
1359+
}
1360+
}
1361+
}
1362+
rc2 = sqlite3changeset_finalize(pIter);
1363+
if( rc==SQLITE_OK ){
1364+
rc = rc2;
1365+
}
1366+
}
1367+
1368+
*pzErr = zErr;
1369+
return rc;
1370+
}
1371+
1372+
/*
1373+
** test_changeset CHANGESET
1374+
*/
1375+
static int SQLITE_TCLAPI test_changeset(
1376+
void * clientData,
1377+
Tcl_Interp *interp,
1378+
int objc,
1379+
Tcl_Obj *CONST objv[]
1380+
){
1381+
void *pChangeset = 0; /* Buffer containing changeset */
1382+
int nChangeset = 0; /* Size of buffer aChangeset in bytes */
1383+
int rc = SQLITE_OK;
1384+
char *z = 0;
1385+
1386+
if( objc!=2 ){
1387+
Tcl_WrongNumArgs(interp, 1, objv, "CHANGESET");
1388+
return TCL_ERROR;
1389+
}
1390+
pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[1], &nChangeset);
1391+
1392+
Tcl_ResetResult(interp);
1393+
rc = sqlite3_test_changeset(nChangeset, pChangeset, &z);
1394+
if( rc!=SQLITE_OK ){
1395+
char *zErr = sqlite3_mprintf("(%d) - \"%s\"", rc, z);
1396+
Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
1397+
sqlite3_free(zErr);
1398+
}
1399+
sqlite3_free(z);
1400+
1401+
return rc ? TCL_ERROR : TCL_OK;
1402+
}
1403+
12851404
/*
12861405
** tclcmd: sqlite3rebaser_configure OP VALUE
12871406
*/
@@ -1337,6 +1456,7 @@ int TestSession_Init(Tcl_Interp *interp){
13371456
{ "sql_exec_changeset", test_sql_exec_changeset },
13381457
{ "sqlite3rebaser_create", test_sqlite3rebaser_create },
13391458
{ "sqlite3session_config", test_sqlite3session_config },
1459+
{ "test_changeset", test_changeset },
13401460
};
13411461
int i;
13421462

0 commit comments

Comments
 (0)