SQLite Forum

Timeline
Login

20 forum posts by user Arfrever

2021-11-30
21:47 Reply: Proposed new date/time function to return a unix timestamp (artifact: 2de21bda3d user: Arfrever)

Modern time-related POSIX APIs [*] use struct timespec, which contains number of seconds and number of nanoseconds, so I recommend to use nanoseconds and not bother with milliseconds/microseconds.

[*] E.g. clock_getres(), clock_gettime(), clock_settime(), nanosleep(), clock_nanosleep(), thrd_sleep(), utimensat(), futimens()

21:08 Reply: Missing static keyword for some private functions (artifact: ecc98c1f4a user: Arfrever)

Another copy of SHA1Transform() function is also in tool/dbhash.c and it can be fixed too.

Full patch for convenience:

--- ext/expert/sqlite3expert.c
+++ ext/expert/sqlite3expert.c
@@ -1168,7 +1168,7 @@
 ** runs all the queries to see which indexes they prefer, and populates
 ** IdxStatement.zIdx and IdxStatement.zEQP with the results.
 */
-int idxFindIndexes(
+static int idxFindIndexes(
   sqlite3expert *p,
   char **pzErr                         /* OUT: Error message (sqlite3_malloc) */
 ){
--- ext/misc/sha1.c
+++ ext/misc/sha1.c
@@ -71,7 +71,7 @@
 /*
  * Hash a single 512-bit block. This is the core of the algorithm.
  */
-void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
+static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
   unsigned int qq[5]; /* a, b, c, d, e; */
   static int one = 1;
   unsigned int block[16];
--- ext/misc/zipfile.c
+++ ext/misc/zipfile.c
@@ -1938,7 +1938,7 @@
 **   SELECT zipfile(name,mode,mtime,data) ...
 **   SELECT zipfile(name,mode,mtime,data,method) ...
 */
-void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
+static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
   ZipfileCtx *p;                  /* Aggregate function context */
   ZipfileEntry e;                 /* New entry to add to zip archive */
 
@@ -2113,7 +2113,7 @@
 /*
 ** xFinalize() callback for zipfile aggregate function.
 */
-void zipfileFinal(sqlite3_context *pCtx){
+static void zipfileFinal(sqlite3_context *pCtx){
   ZipfileCtx *p;
   ZipfileEOCD eocd;
   sqlite3_int64 nZip;
--- ext/rbu/sqlite3rbu.c
+++ ext/rbu/sqlite3rbu.c
@@ -1563,7 +1563,7 @@
 ** the caller has to use an OFFSET clause to extract only the required 
 ** rows from the sourct table, just as it does for an RBU update operation.
 */
-char *rbuVacuumIndexStart(
+static char *rbuVacuumIndexStart(
   sqlite3rbu *p,                  /* RBU handle */
   RbuObjIter *pIter               /* RBU iterator object */
 ){
--- tool/dbhash.c
+++ tool/dbhash.c
@@ -100,7 +100,7 @@
 #define d qq[3]
 #define e qq[4]
 
-void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
+static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
   unsigned int qq[5]; /* a, b, c, d, e; */
   static int one = 1;
   unsigned int block[16];
20:58 Edit reply: Bugs in mechanism of loading of extensions (artifact: e163d20d27 user: Arfrever)

Potential patch for bug #2 (missing error message):

--- src/main.c
+++ src/main.c
@@ -61,40 +61,43 @@
 ** An array of pointers to extension initializer functions for
 ** built-in extensions.
 */
-static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
+static const struct {
+  const char *zExtName;
+  int (*pInit)(sqlite3*);
+} sqlite3BuiltinExtensions[] = {
 #ifdef SQLITE_ENABLE_FTS1
-  sqlite3Fts1Init,
+  { "fts1",                            sqlite3Fts1Init                       },
 #endif
 #ifdef SQLITE_ENABLE_FTS2
-  sqlite3Fts2Init,
+  { "fts2",                            sqlite3Fts2Init                       },
 #endif
 #ifdef SQLITE_ENABLE_FTS3
-  sqlite3Fts3Init,
+  { "fts3",                            sqlite3Fts3Init                       },
 #endif
 #ifdef SQLITE_ENABLE_FTS5
-  sqlite3Fts5Init,
+  { "fts5",                            sqlite3Fts5Init                       },
 #endif
 #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
-  sqlite3IcuInit,
+  { "icu",                             sqlite3IcuInit                        },
 #endif
 #ifdef SQLITE_ENABLE_RTREE
-  sqlite3RtreeInit,
+  { "rtree",                           sqlite3RtreeInit                      },
 #endif
 #ifdef SQLITE_ENABLE_DBPAGE_VTAB
-  sqlite3DbpageRegister,
+  { "dbpage",                          sqlite3DbpageRegister                 },
 #endif
 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
-  sqlite3DbstatRegister,
+  { "dbstat",                          sqlite3DbstatRegister                 },
 #endif
-  sqlite3TestExtInit,
+  { "testext",                         sqlite3TestExtInit                    },
 #ifdef SQLITE_ENABLE_JSON1
-  sqlite3Json1Init,
+  { "json1",                           sqlite3Json1Init                      },
 #endif
 #ifdef SQLITE_ENABLE_STMTVTAB
-  sqlite3StmtVtabInit,
+  { "stmt",                            sqlite3StmtVtabInit                   },
 #endif
 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
-  sqlite3VdbeBytecodeVtabInit,
+  { "vdbebytecode",                    sqlite3VdbeBytecodeVtabInit,          },
 #endif
 };
 
@@ -3410,8 +3413,16 @@
 
   /* Load compiled-in extensions */
   for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
-    rc = sqlite3BuiltinExtensions[i](db);
-    if( rc==SQLITE_OK_LOAD_PERMANENTLY ){
+    if( sqlite3BuiltinExtensions[i].zExtName && sqlite3BuiltinExtensions[i].pInit ){
+      rc = sqlite3BuiltinExtensions[i].pInit(db);
+      if( rc==SQLITE_OK_LOAD_PERMANENTLY ){
+        rc = SQLITE_OK;
+      }
+      if( rc!=SQLITE_OK ){
+        fprintf(stderr, "Error: initialization of built-in extension %s failed: %d\n",
+                sqlite3BuiltinExtensions[i].zExtName, rc);
+      }
+    }else{
       rc = SQLITE_OK;
     }
   }

I also tried sqlite3_log() and sqlite3ErrorWithMsg(), but neither of them results in showing any message in terminal, so above patch uses fprintf().

20:01 Reply: Bugs in mechanism of loading of extensions (artifact: e79dcaf9bc user: Arfrever)

Potential patch for bug #2 (missing error message):

--- src/main.c
+++ src/main.c
@@ -61,40 +61,43 @@
 ** An array of pointers to extension initializer functions for
 ** built-in extensions.
 */
-static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
+static const struct {
+  const char *zExtName;
+  int (*pInit)(sqlite3*);
+} sqlite3BuiltinExtensions[] = {
 #ifdef SQLITE_ENABLE_FTS1
-  sqlite3Fts1Init,
+  { "fts1",                            sqlite3Fts1Init                       },
 #endif
 #ifdef SQLITE_ENABLE_FTS2
-  sqlite3Fts2Init,
+  { "fts2",                            sqlite3Fts2Init                       },
 #endif
 #ifdef SQLITE_ENABLE_FTS3
-  sqlite3Fts3Init,
+  { "fts3",                            sqlite3Fts3Init                       },
 #endif
 #ifdef SQLITE_ENABLE_FTS5
-  sqlite3Fts5Init,
+  { "fts5",                            sqlite3Fts5Init                       },
 #endif
 #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
-  sqlite3IcuInit,
+  { "icu",                             sqlite3IcuInit                        },
 #endif
 #ifdef SQLITE_ENABLE_RTREE
-  sqlite3RtreeInit,
+  { "rtree",                           sqlite3RtreeInit                      },
 #endif
 #ifdef SQLITE_ENABLE_DBPAGE_VTAB
-  sqlite3DbpageRegister,
+  { "dbpage",                          sqlite3DbpageRegister                 },
 #endif
 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
-  sqlite3DbstatRegister,
+  { "dbstat",                          sqlite3DbstatRegister                 },
 #endif
-  sqlite3TestExtInit,
+  { "testext",                         sqlite3TestExtInit                    },
 #ifdef SQLITE_ENABLE_JSON1
-  sqlite3Json1Init,
+  { "json1",                           sqlite3Json1Init                      },
 #endif
 #ifdef SQLITE_ENABLE_STMTVTAB
-  sqlite3StmtVtabInit,
+  { "stmt",                            sqlite3StmtVtabInit                   },
 #endif
 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
-  sqlite3VdbeBytecodeVtabInit,
+  { "vdbebytecode",                    sqlite3VdbeBytecodeVtabInit,          },
 #endif
 };
 
@@ -3410,8 +3413,16 @@
 
   /* Load compiled-in extensions */
   for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
-    rc = sqlite3BuiltinExtensions[i](db);
-    if( rc==SQLITE_OK_LOAD_PERMANENTLY ){
+    if( sqlite3BuiltinExtensions[i].zExtName && sqlite3BuiltinExtensions[i].pInit ){
+      rc = sqlite3BuiltinExtensions[i].pInit(db);
+      if( rc==SQLITE_OK_LOAD_PERMANENTLY ){
+        rc = SQLITE_OK;
+      }
+      if( rc!=SQLITE_OK ){
+        fprintf(stderr, "Error: initialization of built-in extension %s failed: %d",
+                sqlite3BuiltinExtensions[i].zExtName, rc);
+      }
+    }else{
       rc = SQLITE_OK;
     }
   }

I also tried sqlite3_log() and sqlite3ErrorWithMsg(), but neither of them results in showing any message in terminal, so above patch uses fprintf().

16:45 Edit: Bugs in mechanism of loading of extensions (artifact: e9805ca7eb user: Arfrever)

SQLite contains at least 3 mechanisms of loading of extensions:

  • One of them is built-in extensions which are defined in array sqlite3BuiltinExtensions in src/main.c.

  • Another one is extensions registered by function sqlite3_auto_extension().

  • Extensions in separate .so files (not discussed here)

Loading of extensions defined in array sqlite3BuiltinExtensions and loading of automatic extensions (registered by function sqlite3_auto_extension()) is performed in function openDatabase() in src/main.c:

  /* Load compiled-in extensions */
  for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
    rc = sqlite3BuiltinExtensions[i](db);
  }

  /* Load automatic extensions - extensions that have been registered
  ** using the sqlite3_automatic_extension() API.
  */
  if( rc==SQLITE_OK ){
    sqlite3AutoLoadExtensions(db);
    rc = sqlite3_errcode(db);
    if( rc!=SQLITE_OK ){
      goto opendb_out;
    }
  }

Initialization functions of most of extensions distributed in SQLite return SQLITE_OK, but in case of 4 extensions, SQLITE_OK_LOAD_PERMANENTLY is returned:

ext/misc/appendvfs.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/appendvfs.c:  return rc;
--
ext/misc/cksumvfs.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/cksumvfs.c:  return rc;
--
ext/misc/memvfs.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/memvfs.c:  return rc;
--
ext/misc/vfsstat.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/vfsstat.c:  return rc;

SQLITE_OK_LOAD_PERMANENTLY is handled in src/loadext.c:

static int sqlite3LoadExtension(
  ...
  rc = xInit(db, &zErrmsg, &sqlite3Apis);
  if( rc ){
    if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK;
    if( pzErrMsg ){
      *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
    }
    sqlite3_free(zErrmsg);
    sqlite3OsDlClose(pVfs, handle);
    return SQLITE_ERROR;
  }

SQLITE_OK_LOAD_PERMANENTLY is also handled in src/test1.c:

static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
  ...
    if( aExtension[i].pInit ){
      rc = aExtension[i].pInit(db, &zErrMsg, 0);
    }else{
      rc = SQLITE_OK;
    }
    if( (rc!=SQLITE_OK && rc!=SQLITE_OK_LOAD_PERMANENTLY) || zErrMsg ){
      Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
                       (char*)0);
      sqlite3_free(zErrMsg);
      return TCL_ERROR;
    }

Bugs in mechanism of loading of extensions:

  1. Code for processing array sqlite3BuiltinExtensions in src/main.c does not handle SQLITE_OK_LOAD_PERMANENTLY, i.e. SQLITE_OK_LOAD_PERMANENTLY is treated as failure.

  2. If loading of any extension (by aforementioned code in src/main.c) fails for whatever reason, then no error message is printed. For usefulness, error message should contain human-readable name of extension, not something like "extension #11".

  3. If loading of any extension (by aforementioned code in src/main.c) fails for whatever reason, then loading of all subsequent extensions (including automatic extensions) is skipped. SQLite still continues running, just without some extensions. This is unlike e.g. unhandled ImportError in Python which terminates Python process, which strongly suggests that SQLite should try to load subsequent extensions.

  4. (Minor) Typo in this code: sqlite3_automatic_extension should be sqlite3_auto_extension.

Potential fix for bug #1:

--- src/main.c
+++ src/main.c
@@ -3411,6 +3411,9 @@
   /* Load compiled-in extensions */
   for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
     rc = sqlite3BuiltinExtensions[i](db);
+    if( rc==SQLITE_OK_LOAD_PERMANENTLY ){
+      rc = SQLITE_OK;
+    }
   }
 
   /* Load automatic extensions - extensions that have been registered
--- src/loadext.c
+++ src/loadext.c
@@ -859,10 +859,13 @@
     }
     sqlite3_mutex_leave(mutex);
     zErrmsg = 0;
-    if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){
-      sqlite3ErrorWithMsg(db, rc,
-            "automatic extension loading failed: %s", zErrmsg);
-      go = 0;
+    if( xInit ){
+      rc = xInit(db, &zErrmsg, pThunk);
+      if( rc!=SQLITE_OK && rc!=SQLITE_OK_LOAD_PERMANENTLY ){
+        sqlite3ErrorWithMsg(db, rc,
+              "automatic extension loading failed: %s", zErrmsg);
+        go = 0;
+      }
     }
     sqlite3_free(zErrmsg);
   }

Bug #2 can be partially solved by using array of structures similar to aExtension in src/test1.c.

16:04 Post: Missing static keyword for some private functions (artifact: 8e067ab2e0 user: Arfrever)

When reviewing symbols in library, I noticed some symbols which should have been private, but are not due to missing static keyword in source code:

  • idxFindIndexes in ext/expert/sqlite3expert.c
  • SHA1Transform in ext/misc/sha1.c
  • rbuVacuumIndexStart in ext/rbu/sqlite3rbu.c
  • zipfileFinal in ext/misc/zipfile.c
  • zipfileStep in ext/misc/zipfile.c
15:50 Post: Bugs in mechanism of loading of extensions (artifact: d4eb258eb3 user: Arfrever)

SQLite contains at least 3 mechanisms of loading of extensions:

  • One of them is built-in extensions which are defined in array sqlite3BuiltinExtensions in src/main.c.

  • Another one is extensions registered by function sqlite3_auto_extension().

Loading of extensions defined in array sqlite3BuiltinExtensions and loading of automatic extensions (registered by function sqlite3_auto_extension()) is performed in function openDatabase() in src/main.c:

  /* Load compiled-in extensions */
  for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
    rc = sqlite3BuiltinExtensions[i](db);
  }

  /* Load automatic extensions - extensions that have been registered
  ** using the sqlite3_automatic_extension() API.
  */
  if( rc==SQLITE_OK ){
    sqlite3AutoLoadExtensions(db);
    rc = sqlite3_errcode(db);
    if( rc!=SQLITE_OK ){
      goto opendb_out;
    }
  }

Initialization functions of most of extensions distributed in SQLite return SQLITE_OK, but in case of 4 extensions, SQLITE_OK_LOAD_PERMANENTLY is returned:

ext/misc/appendvfs.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/appendvfs.c:  return rc;
--
ext/misc/cksumvfs.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/cksumvfs.c:  return rc;
--
ext/misc/memvfs.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/memvfs.c:  return rc;
--
ext/misc/vfsstat.c:  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
ext/misc/vfsstat.c:  return rc;

SQLITE_OK_LOAD_PERMANENTLY is handled in src/loadext.c:

static int sqlite3LoadExtension(
  ...
  rc = xInit(db, &zErrmsg, &sqlite3Apis);
  if( rc ){
    if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK;
    if( pzErrMsg ){
      *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
    }
    sqlite3_free(zErrmsg);
    sqlite3OsDlClose(pVfs, handle);
    return SQLITE_ERROR;
  }

SQLITE_OK_LOAD_PERMANENTLY is also handled in src/test1.c:

static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
  ...
    if( aExtension[i].pInit ){
      rc = aExtension[i].pInit(db, &zErrMsg, 0);
    }else{
      rc = SQLITE_OK;
    }
    if( (rc!=SQLITE_OK && rc!=SQLITE_OK_LOAD_PERMANENTLY) || zErrMsg ){
      Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
                       (char*)0);
      sqlite3_free(zErrMsg);
      return TCL_ERROR;
    }

Bugs in mechanism of loading of extensions:

  1. Code for processing array sqlite3BuiltinExtensions in src/main.c does not handle SQLITE_OK_LOAD_PERMANENTLY, i.e. SQLITE_OK_LOAD_PERMANENTLY is treated as failure.

  2. If loading of any extension (by aforementioned code in src/main.c) fails for whatever reason, then no error message is printed. For usefulness, error message should contain human-readable name of extension, not something like "extension #11".

  3. If loading of any extension (by aforementioned code in src/main.c) fails for whatever reason, then loading of all subsequent extensions (including automatic extensions) is skipped.

  4. (Minor) Typo in this code: sqlite3_automatic_extension should be sqlite3_auto_extension.

Potential fix for bug #1:

--- src/main.c
+++ src/main.c
@@ -3411,6 +3411,9 @@
   /* Load compiled-in extensions */
   for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
     rc = sqlite3BuiltinExtensions[i](db);
+    if( rc==SQLITE_OK_LOAD_PERMANENTLY ){
+      rc = SQLITE_OK;
+    }
   }
 
   /* Load automatic extensions - extensions that have been registered
--- src/loadext.c
+++ src/loadext.c
@@ -859,10 +859,13 @@
     }
     sqlite3_mutex_leave(mutex);
     zErrmsg = 0;
-    if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){
-      sqlite3ErrorWithMsg(db, rc,
-            "automatic extension loading failed: %s", zErrmsg);
-      go = 0;
+    if( xInit ){
+      rc = xInit(db, &zErrmsg, pThunk);
+      if( rc!=SQLITE_OK && rc!=SQLITE_OK_LOAD_PERMANENTLY ){
+        sqlite3ErrorWithMsg(db, rc,
+              "automatic extension loading failed: %s", zErrmsg);
+        go = 0;
+      }
     }
     sqlite3_free(zErrmsg);
   }

Bug #2 can be partially solved by using array of structures similar to aExtension in src/test1.c.

2020-11-13
17:48 Reply: Test ext/session/sessionrebase.test:2.1.1 fails on HPPA architecture (artifact: 9208a0d14b user: Arfrever)

Reporter of problem confirmed that this patch works.

2020-10-24
21:55 Reply: Test ext/session/sessionrebase.test:2.1.1 fails on HPPA architecture (artifact: 74891c6208 user: Arfrever)

Yes.

From https://bugs.gentoo.org/658912#c8:

./testfixture ./ext/session/sessionrebase.test
sessionrebase-1.0... Ok
sessionrebase-1.1.1... Ok
sessionrebase-1.1.2... Ok
sessionrebase-1.2.1... Ok
sessionrebase-1.2.2... Ok
sessionrebase-1.3.1... Ok
sessionrebase-1.3.2... Ok
sessionrebase-2.1.0... Ok
./testfixture: wrong # args: should be "R rebase CHANGESET"
    while executing
"R delete"
    (procedure "do_rebase_test" line 55)
    invoked from within
"do_rebase_test 2.1.1 {
  UPDATE t1 SET b = 'two.1' WHERE a=2
} {
  UPDATE t1 SET b = 'two.2' WHERE a=2;
} {
  OMIT
} { SELECT * FROM t1 } {1 one 2 two..."
    (file "./ext/session/sessionrebase.test" line 238)
    invoked from within
"source $argv0"
    invoked from within
"if {[llength $argv]>=1} {
set argv0 [lindex $argv 0]
set argv [lrange $argv 1 end]
source $argv0
} else {
set line {}
while {![eof stdin]} {
if {$line..."

Valgrind does not support HPPA: https://www.valgrind.org/info/platforms.html

2020-10-22
17:15 Reply: Test ext/session/sessionrebase.test:2.1.1 fails on HPPA architecture (artifact: 2ba36d0903 user: Arfrever)

Another HPPA user confirmed problem with Tcl 8.6.9.

17:13 Reply: Test ext/session/sessionrebase.test:2.1.1 fails on HPPA architecture (artifact: aeeb2f409f user: Arfrever)

Reporter of problem said that he currently has Tcl 8.6.8 installed.

2020-10-21
18:58 Post: Test ext/session/sessionrebase.test:2.1.1 fails on HPPA architecture (artifact: 51d5cfe04e user: Arfrever)

Test ext/session/sessionrebase.test:2.1.1 fails on HPPA architecture. This problem was not reported on any other architecture.

Original bug report: https://bugs.gentoo.org/658912

I do not have many ideas, but one thing which is different on HPPA than almost all other architectures is that stack grows up, instead of down.

Output of test suite:

...
./testfixture: wrong # args: should be "R rebase CHANGESET"
    while executing
"R delete"
    (procedure "do_rebase_test" line 55)
    invoked from within
"do_rebase_test 2.1.1 {
  UPDATE t1 SET b = 'two.1' WHERE a=2
} {
  UPDATE t1 SET b = 'two.2' WHERE a=2;
} {
  OMIT
} { SELECT * FROM t1 } {1 one 2 two..."
    (file "/var/tmp/portage/dev-db/sqlite-3.33.0/work/sqlite-src-3330000-.hppa/test/../ext/session/sessionrebase.test" line 238)
    invoked from within
"source /var/tmp/portage/dev-db/sqlite-3.33.0/work/sqlite-src-3330000-.hppa/test/../ext/session/sessionrebase.test"
    invoked from within
"interp eval tinterp $script"
    (procedure "slave_test_script" line 30)
    invoked from within
"slave_test_script [list source $zFile] "
    invoked from within
"time { slave_test_script [list source $zFile] }"
    (procedure "slave_test_file" line 23)
    invoked from within
"slave_test_file $file"
    (procedure "run_tests" line 19)
    invoked from within
"run_tests veryquick -presql {} -files {shared3.test writecrash.test vacuum5.test func4.test tkt3731.test /var/tmp/portage/dev-db/sqlite-3.33.0/work/sq..."
    ("uplevel" body line 1)
    invoked from within
"uplevel run_tests $name $::testspec($name)"
    (procedure "run_test_suite" line 5)
    invoked from within
"run_test_suite veryquick"
    (file "/var/tmp/portage/dev-db/sqlite-3.33.0/work/sqlite-src-3330000-.hppa/test/veryquick.test" line 16)
    invoked from within
"source $argv0"
    invoked from within
"if {[llength $argv]>=1} {
set argv0 [lindex $argv 0]
set argv [lrange $argv 1 end]
source $argv0
} else {
set line {}
while {![eof stdin]} {
if {$line..."
2020-07-26
23:14 Reply: sessionfuzz fails on some architectures (ARM, PPC, SPARC) (artifact: ce3800fdf1 user: Arfrever)

Rolf Eike Beer confirmed that new fixes work on SPARC.

Sam James confirmed that new fixes work on ARM/PPC.

2020-07-22
20:11 Edit: sessionfuzz fails on some architectures (ARM, PPC, SPARC) (artifact: d44eb2fc44 user: Arfrever)

Some users have reported that sessionfuzz fails on some architectures (ARM, PPC, SPARC).

I do not know if underlying cause of problem is the same on all of these architectures.

I do not have access to that hardware. sessionfuzz succeeds for me on x86_32 and x86_64.

https://bugs.gentoo.org/685874

https://bugs.gentoo.org/733092

SQLite configuration:

export CPPFLAGS="-DSQLITE_ENABLE_API_ARMOR -DSQLITE_ENABLE_BYTECODE_VTAB -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_DESERIALIZE -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_HIDDEN_COLUMNS -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_NORMALIZE -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_RBU -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY -DSQLITE_ENABLE_STMT_SCANSTATUS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_SOUNDEX -DSQLITE_USE_URI -DSQLITE_SECURE_DELETE"
./configure --enable-load-extension --enable-threadsafe --enable-fts5 --enable-session --disable-debug --disable-editline --enable-readline --with-readline-inc=-I/usr/include/readline --disable-static --enable-tcl

GDB output on PPC:

Reading symbols from ./sessionfuzz...
(gdb) r
Starting program: /var/tmp/portage/dev-db/sqlite-3.32.3/work/sqlite-src-3320300-.ppc/sessionfuzz run test/sessionfuzz-data1.db
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
sessionfuzz-data1.db: sessionfuzz: ./sqlite3.c:57398: pager_open_journal: Assertion `rc!=SQLITE_OK || isOpen(pPager->jfd)' failed.

Program received signal SIGABRT, Aborted.
0xf7e0d1d0 in raise () from /lib/libc.so.6
(gdb) bt
#0  0xf7e0d1d0 in raise () from /lib/libc.so.6
#1  0xf7df2e2c in abort () from /lib/libc.so.6
#2  0xf7e03b2c in ?? () from /lib/libc.so.6
#3  0xf7e03bb0 in __assert_fail () from /lib/libc.so.6
#4  0x004c85d0 in pager_open_journal (pPager=0x6448e0) at ./sqlite3.c:57398
#5  pager_write (pPg=0x66d6a0) at ./sqlite3.c:57596
#6  0x004cfaf4 in insertCell (pPage=0x66d6c8, i=0, pCell=0x643bb4 "\002\002\r", sz=4, pTemp=0x0, iChild=0, pRC=0xffffda40) at ./sqlite3.c:71088
#7  0x004d9bb4 in sqlite3BtreeInsert (pCur=0x64d398, pX=0xffffdb70, flags=<optimized out>, seekResult=<optimized out>) at ./sqlite3.c:73173
#8  0x0051d110 in sqlite3VdbeExec (p=<optimized out>) at ./sqlite3.c:90754
#9  0x0052b354 in sqlite3Step (p=0x64dc90) at ./sqlite3.c:83488
#10 sqlite3_step (pStmt=0x64dc90) at ./sqlite3.c:18017
#11 0x00565aa0 in sessionApplyOneOp (pIter=0x656f10, p=0xffffdee8, xConflict=0x447ca4 <conflictCall>, pCtx=0x0, pbReplace=0xffffde74, pbRetry=0xffffde78) at ./sqlite3.c:205933
#12 0x00565ee8 in sessionApplyOneWithRetry (db=0x6431c0, pIter=0x656f10, pApply=0xffffdee8, xConflict=0x447ca4 <conflictCall>, pCtx=0x0) at ./sqlite3.c:205968
#13 0x00591948 in sessionChangesetApply (db=0x6431c0, pIter=0x656f10, xFilter=0x0, xConflict=0x447ca4 <conflictCall>, pCtx=0x0, ppRebase=0x0, pnRebase=0x0, flags=<optimized out>)
    at ./sqlite3.c:206207
#14 0x005928f4 in sqlite3changeset_apply_v2 (db=0x6431c0, nChangeset=<optimized out>, pChangeset=<optimized out>, xFilter=0x0, xConflict=0x447ca4 <conflictCall>, pCtx=0x0,
    ppRebase=0x0, pnRebase=0x0, flags=0) at ./sqlite3.c:206288
#15 0x00417bb0 in sqlite3changeset_apply (pCtx=0x0, xConflict=0x447ca4 <conflictCall>, xFilter=0x0, pChangeset=0x6664d0, nChangeset=<optimized out>, db=<optimized out>)
    at ./sqlite3.c:206315
#16 main (argc=3, argv=<optimized out>) at /var/tmp/portage/dev-db/sqlite-3.32.3/work/sqlite-src-3320300-.ppc/test/sessionfuzz.c:930
(gdb) 
19:14 Post: sessionfuzz fails on some architectures (ARM, PPC, SPARC) (artifact: 6c501b1e70 user: Arfrever)

Some users have reported that sessionfuzz fails on some architectures (ARM, PPC, SPARC).

I do not know if underlying cause of problem is the same on all of these architectures.

I do not have access to that hardware. sessionfuzz suceeds for me on x86_32 and x86_64.

https://bugs.gentoo.org/685874

https://bugs.gentoo.org/733092

SQLite configuration:

export CPPFLAGS="-DSQLITE_ENABLE_API_ARMOR -DSQLITE_ENABLE_BYTECODE_VTAB -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_DESERIALIZE -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_HIDDEN_COLUMNS -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_ENABLE_NORMALIZE -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_RBU -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY -DSQLITE_ENABLE_STMT_SCANSTATUS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -DSQLITE_SOUNDEX -DSQLITE_USE_URI -DSQLITE_SECURE_DELETE"
./configure --enable-load-extension --enable-threadsafe --enable-fts5 --enable-session --disable-debug --disable-editline --enable-readline --with-readline-inc=-I/usr/include/readline --disable-static --enable-tcl

GDB output on PPC:

Reading symbols from ./sessionfuzz...
(gdb) r
Starting program: /var/tmp/portage/dev-db/sqlite-3.32.3/work/sqlite-src-3320300-.ppc/sessionfuzz run test/sessionfuzz-data1.db
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
sessionfuzz-data1.db: sessionfuzz: ./sqlite3.c:57398: pager_open_journal: Assertion `rc!=SQLITE_OK || isOpen(pPager->jfd)' failed.

Program received signal SIGABRT, Aborted.
0xf7e0d1d0 in raise () from /lib/libc.so.6
(gdb) bt
#0  0xf7e0d1d0 in raise () from /lib/libc.so.6
#1  0xf7df2e2c in abort () from /lib/libc.so.6
#2  0xf7e03b2c in ?? () from /lib/libc.so.6
#3  0xf7e03bb0 in __assert_fail () from /lib/libc.so.6
#4  0x004c85d0 in pager_open_journal (pPager=0x6448e0) at ./sqlite3.c:57398
#5  pager_write (pPg=0x66d6a0) at ./sqlite3.c:57596
#6  0x004cfaf4 in insertCell (pPage=0x66d6c8, i=0, pCell=0x643bb4 "\002\002\r", sz=4, pTemp=0x0, iChild=0, pRC=0xffffda40) at ./sqlite3.c:71088
#7  0x004d9bb4 in sqlite3BtreeInsert (pCur=0x64d398, pX=0xffffdb70, flags=<optimized out>, seekResult=<optimized out>) at ./sqlite3.c:73173
#8  0x0051d110 in sqlite3VdbeExec (p=<optimized out>) at ./sqlite3.c:90754
#9  0x0052b354 in sqlite3Step (p=0x64dc90) at ./sqlite3.c:83488
#10 sqlite3_step (pStmt=0x64dc90) at ./sqlite3.c:18017
#11 0x00565aa0 in sessionApplyOneOp (pIter=0x656f10, p=0xffffdee8, xConflict=0x447ca4 <conflictCall>, pCtx=0x0, pbReplace=0xffffde74, pbRetry=0xffffde78) at ./sqlite3.c:205933
#12 0x00565ee8 in sessionApplyOneWithRetry (db=0x6431c0, pIter=0x656f10, pApply=0xffffdee8, xConflict=0x447ca4 <conflictCall>, pCtx=0x0) at ./sqlite3.c:205968
#13 0x00591948 in sessionChangesetApply (db=0x6431c0, pIter=0x656f10, xFilter=0x0, xConflict=0x447ca4 <conflictCall>, pCtx=0x0, ppRebase=0x0, pnRebase=0x0, flags=<optimized out>)
    at ./sqlite3.c:206207
#14 0x005928f4 in sqlite3changeset_apply_v2 (db=0x6431c0, nChangeset=<optimized out>, pChangeset=<optimized out>, xFilter=0x0, xConflict=0x447ca4 <conflictCall>, pCtx=0x0,
    ppRebase=0x0, pnRebase=0x0, flags=0) at ./sqlite3.c:206288
#15 0x00417bb0 in sqlite3changeset_apply (pCtx=0x0, xConflict=0x447ca4 <conflictCall>, xFilter=0x0, pChangeset=0x6664d0, nChangeset=<optimized out>, db=<optimized out>)
    at ./sqlite3.c:206315
#16 main (argc=3, argv=<optimized out>) at /var/tmp/portage/dev-db/sqlite-3.32.3/work/sqlite-src-3320300-.ppc/test/sessionfuzz.c:930
(gdb) 
2020-06-30
00:17 Edit: PATCH Add SQLITE_ENABLE_CARRAY (artifact: b5ed570e4c user: Arfrever)
I maintain SQLite package in Gentoo and I would like to reduce amount of necessary patching.
I would like to enable some extensions in libsqlite3.so library (some of those which only add additional features (usually functions) and have no incompatible effect on behavior) (e.g. carray, csv, dbdata, eval, fileio, ieee754, regexp, sha1, shathree, totype, uint, uuid).

This can be done by supporting new SQLITE_ENABLE_* macros, which would be disabled by default.

Is there chance that any new proposed macros will be accepted?
(I can provide similar patches adding other macros.)

The following patch adds SQLITE_ENABLE_CARRAY macro, which enables carray extension with carray function.
(Patch written exclusively by me and provided in public domain.)


Index: Makefile.in
==================================================================
--- Makefile.in
+++ Makefile.in
@@ -363,10 +363,11 @@
   $(TOP)/ext/userauth/sqlite3userauth.h
 SRC += \
   $(TOP)/ext/rbu/sqlite3rbu.h \
   $(TOP)/ext/rbu/sqlite3rbu.c
 SRC += \
+  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/json1.c \
   $(TOP)/ext/misc/stmt.c
 
 # Generated source code files
 #
@@ -438,11 +439,10 @@
 #
 TESTSRC += \
   $(TOP)/ext/expert/sqlite3expert.c \
   $(TOP)/ext/expert/test_expert.c \
   $(TOP)/ext/misc/amatch.c \
-  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/closure.c \
   $(TOP)/ext/misc/csv.c \
   $(TOP)/ext/misc/decimal.c \
   $(TOP)/ext/misc/eval.c \
   $(TOP)/ext/misc/explain.c \

Index: Makefile.msc
==================================================================
--- Makefile.msc
+++ Makefile.msc
@@ -1440,10 +1440,11 @@
   $(TOP)\ext\fts3\fts3_write.c \
   $(TOP)\ext\icu\icu.c \
   $(TOP)\ext\rtree\rtree.c \
   $(TOP)\ext\session\sqlite3session.c \
   $(TOP)\ext\rbu\sqlite3rbu.c \
+  $(TOP)\ext\misc\carray.c \
   $(TOP)\ext\misc\json1.c \
   $(TOP)\ext\misc\stmt.c
 
 # Extension header files, part 1.
 #
@@ -1555,11 +1556,10 @@
 #
 TESTEXT = \
   $(TOP)\ext\expert\sqlite3expert.c \
   $(TOP)\ext\expert\test_expert.c \
   $(TOP)\ext\misc\amatch.c \
-  $(TOP)\ext\misc\carray.c \
   $(TOP)\ext\misc\closure.c \
   $(TOP)\ext\misc\csv.c \
   $(TOP)\ext\misc\decimal.c \
   $(TOP)\ext\misc\eval.c \
   $(TOP)\ext\misc\explain.c \

Index: ext/misc/carray.c
==================================================================
--- ext/misc/carray.c
+++ ext/misc/carray.c
@@ -50,10 +50,11 @@
 ** the virtual table has no rows.  Otherwise, the virtual table interprets
 ** the integer value of "pointer" as a pointer to the array and "count"
 ** as the number of elements in the array.  The virtual table steps through
 ** the array, element by element.
 */
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_CARRAY)
 #include "sqlite3ext.h"
 SQLITE_EXTENSION_INIT1
 #include <assert.h>
 #include <string.h>
 
@@ -381,20 +382,12 @@
 }
 #endif /* SQLITE_TEST */
 
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_carray_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
+int sqlite3CarrayInit(sqlite3 *db){
   int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
 #ifdef SQLITE_TEST
   if( rc==SQLITE_OK ){
     rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0,
@@ -402,5 +395,21 @@
   }
 #endif /* SQLITE_TEST */
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
   return rc;
 }
+
+#ifndef SQLITE_CORE
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int sqlite3_carray_init(
+  sqlite3 *db, 
+  char **pzErrMsg, 
+  const sqlite3_api_routines *pApi
+){
+  SQLITE_EXTENSION_INIT2(pApi);
+  (void)pzErrMsg;  /* Unused parameter */
+  return sqlite3CarrayInit(db);
+}
+#endif
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_CARRAY) */

Index: main.mk
==================================================================
--- main.mk
+++ main.mk
@@ -241,10 +241,11 @@
   $(TOP)/ext/userauth/sqlite3userauth.h
 SRC += \
   $(TOP)/ext/rbu/sqlite3rbu.c \
   $(TOP)/ext/rbu/sqlite3rbu.h
 SRC += \
+  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/json1.c \
   $(TOP)/ext/misc/stmt.c
 
 
 # FTS5 things
@@ -358,11 +359,10 @@
 
 # Extensions to be statically loaded.
 #
 TESTSRC += \
   $(TOP)/ext/misc/amatch.c \
-  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/closure.c \
   $(TOP)/ext/misc/csv.c \
   $(TOP)/ext/misc/decimal.c \
   $(TOP)/ext/misc/eval.c \
   $(TOP)/ext/misc/explain.c \

Index: src/ctime.c
==================================================================
--- src/ctime.c
+++ src/ctime.c
@@ -193,10 +193,13 @@
 #if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
   "ENABLE_BATCH_ATOMIC_WRITE",
 #endif
 #if SQLITE_ENABLE_BYTECODE_VTAB
   "ENABLE_BYTECODE_VTAB",
+#endif
+#if SQLITE_ENABLE_CARRAY
+  "ENABLE_CARRAY",
 #endif
 #if SQLITE_ENABLE_CEROD
   "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
 #endif
 #if SQLITE_ENABLE_COLUMN_METADATA

Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -39,10 +39,13 @@
 
 /*
 ** Forward declarations of external module initializer functions
 ** for modules that need them.
 */
+#ifdef SQLITE_ENABLE_CARRAY
+int sqlite3CarrayInit(sqlite3*);
+#endif
 #ifdef SQLITE_ENABLE_FTS1
 int sqlite3Fts1Init(sqlite3*);
 #endif
 #ifdef SQLITE_ENABLE_FTS2
 int sqlite3Fts2Init(sqlite3*);
@@ -60,10 +63,13 @@
 /*
 ** An array of pointers to extension initializer functions for
 ** built-in extensions.
 */
 static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
+#ifdef SQLITE_ENABLE_CARRAY
+  sqlite3CarrayInit,
+#endif
 #ifdef SQLITE_ENABLE_FTS1
   sqlite3Fts1Init,
 #endif
 #ifdef SQLITE_ENABLE_FTS2
   sqlite3Fts2Init,

Index: tool/mksqlite3c.tcl
==================================================================
--- tool/mksqlite3c.tcl
+++ tool/mksqlite3c.tcl
@@ -392,10 +392,11 @@
    fts3_write.c
    fts3_snippet.c
    fts3_unicode.c
    fts3_unicode2.c
 
+   carray.c
    json1.c
    rtree.c
    icu.c
    fts3_icu.c
    sqlite3rbu.c
2020-06-29
22:21 Reply: Place for patches (artifact: e5cc6adca7 user: Arfrever)
OK. I have sent it (using e-mail)...

If sending such copyright release declaration is useful for contributors, then website should somewhere inform about this possibility.
22:08 Post: PATCH Add SQLITE_ENABLE_CARRAY (artifact: c0dcf6c561 user: Arfrever)
I maintain SQLite package in Gentoo and I would like to reduce amount of necessary patching.
I would like to enable some extensions in libsqlite3.so library (some of those which only add additional features (usually functions) and have no incompatible effect on behavior) (e.g. carray, csv, dbdata, eval, fileio, ieee754, regexp, sha1, shathree, totype, uint, uuid).

This can be done by supporting new SQLITE_ENABLE_* macros, which would be disabled by default.

Is there chance that any new proposed macros will be accepted?
(I can provide similar patches adding other macros.)

The following patch adds SQLITE_ENABLE_CARRAY macro, which enables carray extension with carray function.
(Patch written exclusively by me and provided in public domain.)


Index: Makefile.in
==================================================================
--- Makefile.in
+++ Makefile.in
@@ -363,10 +363,11 @@
   $(TOP)/ext/userauth/sqlite3userauth.h
 SRC += \
   $(TOP)/ext/rbu/sqlite3rbu.h \
   $(TOP)/ext/rbu/sqlite3rbu.c
 SRC += \
+  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/json1.c \
   $(TOP)/ext/misc/stmt.c
 
 # Generated source code files
 #
@@ -438,11 +439,10 @@
 #
 TESTSRC += \
   $(TOP)/ext/expert/sqlite3expert.c \
   $(TOP)/ext/expert/test_expert.c \
   $(TOP)/ext/misc/amatch.c \
-  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/closure.c \
   $(TOP)/ext/misc/csv.c \
   $(TOP)/ext/misc/decimal.c \
   $(TOP)/ext/misc/eval.c \
   $(TOP)/ext/misc/explain.c \

Index: Makefile.msc
==================================================================
--- Makefile.msc
+++ Makefile.msc
@@ -1440,10 +1440,11 @@
   $(TOP)\ext\fts3\fts3_write.c \
   $(TOP)\ext\icu\icu.c \
   $(TOP)\ext\rtree\rtree.c \
   $(TOP)\ext\session\sqlite3session.c \
   $(TOP)\ext\rbu\sqlite3rbu.c \
+  $(TOP)\ext\misc\carray.c \
   $(TOP)\ext\misc\json1.c \
   $(TOP)\ext\misc\stmt.c
 
 # Extension header files, part 1.
 #
@@ -1555,11 +1556,10 @@
 #
 TESTEXT = \
   $(TOP)\ext\expert\sqlite3expert.c \
   $(TOP)\ext\expert\test_expert.c \
   $(TOP)\ext\misc\amatch.c \
-  $(TOP)\ext\misc\carray.c \
   $(TOP)\ext\misc\closure.c \
   $(TOP)\ext\misc\csv.c \
   $(TOP)\ext\misc\decimal.c \
   $(TOP)\ext\misc\eval.c \
   $(TOP)\ext\misc\explain.c \

Index: ext/misc/carray.c
==================================================================
--- ext/misc/carray.c
+++ ext/misc/carray.c
@@ -50,10 +50,11 @@
 ** the virtual table has no rows.  Otherwise, the virtual table interprets
 ** the integer value of "pointer" as a pointer to the array and "count"
 ** as the number of elements in the array.  The virtual table steps through
 ** the array, element by element.
 */
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_CARRAY)
 #include "sqlite3ext.h"
 SQLITE_EXTENSION_INIT1
 #include <assert.h>
 #include <string.h>
 
@@ -381,20 +382,12 @@
 }
 #endif /* SQLITE_TEST */
 
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
-#ifdef _WIN32
-__declspec(dllexport)
-#endif
-int sqlite3_carray_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
+int sqlite3CarrayInit(sqlite3 *db){
   int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   rc = sqlite3_create_module(db, "carray", &carrayModule, 0);
 #ifdef SQLITE_TEST
   if( rc==SQLITE_OK ){
     rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0,
@@ -402,5 +395,21 @@
   }
 #endif /* SQLITE_TEST */
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
   return rc;
 }
+
+#ifndef SQLITE_CORE
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int sqlite3_carray_init(
+  sqlite3 *db, 
+  char **pzErrMsg, 
+  const sqlite3_api_routines *pApi
+){
+  SQLITE_EXTENSION_INIT2(pApi);
+  (void)pzErrMsg;  /* Unused parameter */
+  return sqlite3CarrayInit(db);
+}
+#endif
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_CARRAY) */

Index: main.mk
==================================================================
--- main.mk
+++ main.mk
@@ -241,10 +241,11 @@
   $(TOP)/ext/userauth/sqlite3userauth.h
 SRC += \
   $(TOP)/ext/rbu/sqlite3rbu.c \
   $(TOP)/ext/rbu/sqlite3rbu.h
 SRC += \
+  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/json1.c \
   $(TOP)/ext/misc/stmt.c
 
 
 # FTS5 things
@@ -358,11 +359,10 @@
 
 # Extensions to be statically loaded.
 #
 TESTSRC += \
   $(TOP)/ext/misc/amatch.c \
-  $(TOP)/ext/misc/carray.c \
   $(TOP)/ext/misc/closure.c \
   $(TOP)/ext/misc/csv.c \
   $(TOP)/ext/misc/decimal.c \
   $(TOP)/ext/misc/eval.c \
   $(TOP)/ext/misc/explain.c \

Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -39,10 +39,13 @@
 
 /*
 ** Forward declarations of external module initializer functions
 ** for modules that need them.
 */
+#ifdef SQLITE_ENABLE_CARRAY
+int sqlite3CarrayInit(sqlite3*);
+#endif
 #ifdef SQLITE_ENABLE_FTS1
 int sqlite3Fts1Init(sqlite3*);
 #endif
 #ifdef SQLITE_ENABLE_FTS2
 int sqlite3Fts2Init(sqlite3*);
@@ -60,10 +63,13 @@
 /*
 ** An array of pointers to extension initializer functions for
 ** built-in extensions.
 */
 static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
+#ifdef SQLITE_ENABLE_CARRAY
+  sqlite3CarrayInit,
+#endif
 #ifdef SQLITE_ENABLE_FTS1
   sqlite3Fts1Init,
 #endif
 #ifdef SQLITE_ENABLE_FTS2
   sqlite3Fts2Init,

Index: tool/mksqlite3c.tcl
==================================================================
--- tool/mksqlite3c.tcl
+++ tool/mksqlite3c.tcl
@@ -392,10 +392,11 @@
    fts3_write.c
    fts3_snippet.c
    fts3_unicode.c
    fts3_unicode2.c
 
+   carray.c
    json1.c
    rtree.c
    icu.c
    fts3_icu.c
    sqlite3rbu.c
21:05 Reply: Place for patches (artifact: bfdacde96e user: Arfrever)
Why not requiring something like Contributor License Agreement instead (which would specify that the contributed code remains in public domain)?
20:58 Post: PATCH Drop SQLITE_ENABLE_ICU_COLLATIONS (artifact: 19f289620f user: Arfrever)
I noticed that number of tests run by whole test suite is
smaller when SQLite is compiled with merely -DSQLITE_ENABLE_ICU than
with -DSQLITE_ENABLE_ICU -DSQLITE_ENABLE_ICU_COLLATIONS.

src/test_config.c sets icu_collations setting based on
SQLITE_ENABLE_ICU_COLLATIONS macro.
ext/rbu/rbucollate.test has "ifcapable !icu_collations", while other tests usually check icu, not icu_collations.

SQLITE_ENABLE_ICU_COLLATIONS macro is undocumented and has no other effect.
All other places, which check SQLITE_ENABLE_ICU_COLLATIONS macro, also
check SQLITE_ENABLE_ICU macro.
I suggest to drop SQLITE_ENABLE_ICU_COLLATIONS macro and
icu_collations setting in test suite.

There is also unrelated typo "idu-6.0" in test/icu.test.

Patch:

Index: ext/icu/icu.c
==================================================================
--- ext/icu/icu.c
+++ ext/icu/icu.c
@@ -26,13 +26,11 @@
 **
 **   * An implementation of the LIKE operator that uses ICU to 
 **     provide case-independent matching.
 */
 
-#if !defined(SQLITE_CORE)                  \
- || defined(SQLITE_ENABLE_ICU)             \
- || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
 
 /* Include ICU headers */
 #include <unicode/utypes.h>
 #include <unicode/uregex.h>
 #include <unicode/ustring.h>

Index: ext/rbu/rbucollate.test
==================================================================
--- ext/rbu/rbucollate.test
+++ ext/rbu/rbucollate.test
@@ -11,11 +11,11 @@
 #
 
 source [file join [file dirname [info script]] rbu_common.tcl]
 set ::testprefix rbucollate
 
-ifcapable !icu_collations {
+ifcapable !icu {
   finish_test
   return
 }
 
 db close

Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -20,11 +20,11 @@
 # include "fts3.h"
 #endif
 #ifdef SQLITE_ENABLE_RTREE
 # include "rtree.h"
 #endif
-#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+#ifdef SQLITE_ENABLE_ICU
 # include "sqliteicu.h"
 #endif
 
 /*
 ** This is an extension initializer that is a no-op and always
@@ -72,11 +72,11 @@
   sqlite3Fts3Init,
 #endif
 #ifdef SQLITE_ENABLE_FTS5
   sqlite3Fts5Init,
 #endif
-#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+#ifdef SQLITE_ENABLE_ICU
   sqlite3IcuInit,
 #endif
 #ifdef SQLITE_ENABLE_RTREE
   sqlite3RtreeInit,
 #endif

Index: src/test_config.c
==================================================================
--- src/test_config.c
+++ src/test_config.c
@@ -435,16 +435,10 @@
   Tcl_SetVar2(interp, "sqlite_options", "icu", "1", TCL_GLOBAL_ONLY);
 #else
   Tcl_SetVar2(interp, "sqlite_options", "icu", "0", TCL_GLOBAL_ONLY);
 #endif
 
-#ifdef SQLITE_ENABLE_ICU_COLLATIONS
-  Tcl_SetVar2(interp, "sqlite_options", "icu_collations", "1", TCL_GLOBAL_ONLY);
-#else
-  Tcl_SetVar2(interp, "sqlite_options", "icu_collations", "0", TCL_GLOBAL_ONLY);
-#endif
-
 #ifdef SQLITE_OMIT_INCRBLOB
   Tcl_SetVar2(interp, "sqlite_options", "incrblob", "0", TCL_GLOBAL_ONLY);
 #else
   Tcl_SetVar2(interp, "sqlite_options", "incrblob", "1", TCL_GLOBAL_ONLY);
 #endif /* SQLITE_OMIT_AUTOVACUUM */

Index: test/icu.test
==================================================================
--- test/icu.test
+++ test/icu.test
@@ -13,11 +13,11 @@
 #
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
-ifcapable !icu&&!icu_collations {
+ifcapable !icu {
   finish_test
   return
 }
 
 # Create a table to work with.
@@ -147,11 +147,11 @@
 }
 
 # 2020-03-19
 # The ESCAPE clause on LIKE takes precedence over wildcards
 #
-do_execsql_test idu-6.0 {
+do_execsql_test icu-6.0 {
   DROP TABLE IF EXISTS t1;
   CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT);
   INSERT INTO t1 VALUES
     (1,'abcde'),
     (2,'abc_'),