]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Sync w/trunk, fix zAutoColumns placement blunder, all to pass all TCL tests
authorlarrybr <larrybr@noemail.net>
Sun, 13 Feb 2022 22:18:22 +0000 (22:18 +0000)
committerlarrybr <larrybr@noemail.net>
Sun, 13 Feb 2022 22:18:22 +0000 (22:18 +0000)
FossilOrigin-Name: 67dc59f46d742ad69742fb34540a3074af163a3f1a0f9093f83db2276bf944ca

1  2 
manifest
manifest.uuid
src/shell.c.in

diff --cc manifest
index d5fca950d3604bf9ea5b4d6a767f9672dad27346,99c429946293e387a20e40e9f519699e9e095bf7..c8b221ba39da0403b70798980d638cad0011bf25
+++ b/manifest
@@@ -1,5 -1,5 +1,5 @@@
- C For\s.import\sauto-column,\said\sbuild-time\soverride\sof\srename\sdecoration.
- D 2022-02-12T13:12:03.134
 -C Do\snot\srun\smerge1.test\swith\sSQLITE_OMIT_VIRTUALTABLE\sbuilds.
 -D 2022-02-12T18:56:24.181
++C Sync\sw/trunk,\sfix\szAutoColumns\splacement\sblunder,\sall\sto\spass\sall\sTCL\stests
++D 2022-02-13T22:18:22.163
  F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
  F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
  F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@@ -553,7 -553,7 +553,7 @@@ F src/random.c 097dc8b31b8fba5a9aca1697
  F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e
  F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
  F src/select.c 3baa9dd8cf240654773c7974e2bcce398ac9dd24419c36684156963defe43b35
- F src/shell.c.in c2a03469e2f6f694878bdbee0e99f428c7bd2db104d54bd818f8834419ed666a x
 -F src/shell.c.in b800bf8e02d9b4fd97078b68ca4371048f7196fc63accaa99c3c5943f72c80a0
++F src/shell.c.in 233a5c7f0ee9a9d1b88f1caed538d813390bb474082d9d74504d846ccb49f31e x
  F src/sqlite.h.in 7047c4b60fa550264d6363bb1d983540e7828fb19d2d1e5aa43b52ca13144807
  F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
  F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6
@@@ -1944,8 -1944,8 +1944,8 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9
  F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
  F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
  F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
- P 689137e1b5bc78b0f16e5db86d16415b9fa77d22ded59e93d75e7033b465e673
- R c9aa492d97b18dedc9e846ae1794f2b1
 -P 9252619d410293ddefd108f5cf81b6fb4932bd3f2ceaaa92abb7542e34f66111
 -R 80e8eecaf7636ea102822137f451668f
 -U dan
 -Z 534ed5fc79f3b9c855702c93bc92827c
++P 433e5ead2b711d1e3b0b62cf8cb5a8a65e2474c68ef2173317ed4323fc8bdc58 bf8dbfd499e732f14c7a8efee527e8ce155937dbb2a3e85213f8aa64ac497189
++R d0a4f648a76dcc064c4b8040fefbc80a
 +U larrybr
- Z f9350e44002aa6905f87e93f2aa43b9c
++Z 9500253e6d614600afa73cc694266a23
  # Remove this line to create a well-formed Fossil manifest.
diff --cc manifest.uuid
index f0f8d99eda3a11cc01e35afa2d3526351b47e449,17e7501d4c772b8d311232e118f8c5e3166a9ce2..505f134e8fb3f87439328e777be4a0d65614f910
@@@ -1,1 -1,1 +1,1 @@@
- 433e5ead2b711d1e3b0b62cf8cb5a8a65e2474c68ef2173317ed4323fc8bdc58
 -bf8dbfd499e732f14c7a8efee527e8ce155937dbb2a3e85213f8aa64ac497189
++67dc59f46d742ad69742fb34540a3074af163a3f1a0f9093f83db2276bf944ca
diff --cc src/shell.c.in
index fba748bc961fd3119b2c19759433872e86002fe3,35e99989f59896b099bf29f192b69f92b5770373..66428b72b611b035990f322a6c41474f54c5ea6a
mode 100755,100644..100755
@@@ -7223,187 -7223,6 +7223,7 @@@ static char *shellMPrintf(int *pRc, con
    return z;
  }
  
- /* 
-  * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
-  * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
-  *   close db and set it to 0, and return the columns spec, to later
-  *   be sqlite3_free()'ed by the caller.
-  * The return is 0 when either:
-  *   (a) The db was not initialized and zCol==0 (There are no columns.)
-  *   (b) zCol!=0  (Column was added, db initialized as needed.)
-  * The 3rd argument, pRenamed, references an out parameter. If the
-  * pointer is non-zero, its referent will be set to 1 if renaming was
-  * necessary, or set to 0 if none was done.
-  */
- #ifdef SHELL_DEBUG
- #define rc_err_oom_die(rc) \
-   if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
-   else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
-     fprintf(stderr,"E:%d\n",rc), assert(0)
- #else
- static void rc_err_oom_die(int rc){
-   if( rc==SQLITE_NOMEM ) shell_check_oom(0);
-   assert(rc==SQLITE_OK||rc==SQLITE_DONE);
- }
- #endif
- #ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */
- static char zCOL_DB[] = SHELL_COLFIX_DB;
- #else  /* Otherwise, memory is faster/better for the transient DB. */
- static const char *zCOL_DB = ":memory:";
- #endif
- /* Define character (as C string) to separate generated column ordinal
-  * from protected part of incoming column names. This defaults to "_"
-  * so that incoming column identifiers that did not need not be quoted
-  * remain usable without being quoted. It must be one character.
-  */
- #ifndef SHELL_AUTOCOLUMN_SEP
- # define AUTOCOLUMN_SEP "_"
- #else
- # define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP)
- #endif
- static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, int *pRenamed){
-   /* Queries and D{D,M}L used here */
-   static const char const *zTabMake = "\
- CREATE TABLE ColNames(\
-  cpos INTEGER PRIMARY KEY,\
-  name TEXT, nlen INT, chop INT, reps INT, suff TEXT)\
- ";
-   static const char const *zTabFill = "\
- INSERT INTO ColNames(name,nlen,chop,reps,suff)\
-  VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\
- ";
-   static const char const *zHasDupes = "\
- SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\
-  <count(name) FROM ColNames\
- ";
-   static const char const *zDedoctor = "\
- WITH chopped AS ( \
-  WITH RECURSIVE chopping(cpos, name, chop, nlen) AS ( \
-   SELECT cpos, name, 0, nlen FROM ColNames \
-   WHERE cpos IN ( \
-     WITH RECURSIVE choppable(nc, name, cpos) AS \
-      (SELECT nlen AS nc, name, cpos \
-       FROM ColNames \
-       UNION ALL \
-       SELECT nc-1 AS nc, name, cpos \
-       FROM choppable \
-       WHERE substring(name, nc, 1) BETWEEN '0' AND '9'\
-      ) SELECT cpos /*name*/ FROM choppable \
-        WHERE nc<length(name) and \
-          substring(name, nc, 1)='"AUTOCOLUMN_SEP"'\
-   )\
-   UNION ALL\
-   SELECT cpos, name, chop+1 AS chop, nlen \
-   FROM chopping \
-   WHERE \
-    instr('"AUTOCOLUMN_SEP"0123456789', substring(name, nlen-chop, 1))>0 \
-  )\
-  SELECT cpos, name, max(chop) AS chop FROM chopping s \
-  GROUP BY cpos \
- ) UPDATE ColNames AS c \
-   SET chop=n.chop FROM chopped n WHERE c.cpos=n.cpos \
- ";
-   static const char const *zSetReps = "\
- UPDATE ColNames AS t SET reps=\
- (SELECT count(*) FROM ColNames d \
-  WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\
-  COLLATE NOCASE\
- )\
- ";
- #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
-   static const char const *zColDigits = "\
- SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
- ";
- #endif
-   static const char const *zRenameRank =
- #ifndef SHELL_COLUMN_RENAME_DML
-     "UPDATE ColNames AS t SET suff="
-     "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
- #else
-     SHELL_COLUMN_RENAME_DML
- #endif
-     ;
-   static const char const *zCollectVar = "\
- SELECT\
-  '('||\
-  group_concat(\
-   cname||' TEXT',\
-   ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
-  ||')' AS ColsSpec \
- FROM (\
-  SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
-  FROM ColNames ORDER BY cpos\
- )";
-   int rc;
-   sqlite3_stmt *pStmt = 0;
-   assert(pDb!=0);
-   if( zColNew ){
-     /* Add initial or additional column. Init db if necessary. */
-     if( *pDb==0 ){
-       if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
- #ifdef SHELL_COLFIX_DB
-       if(*zCOL_DB!=':')
-         sqlite3_exec(*pDb,"drop table if exists ColNames",0,0,0);
- #endif
-       rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
-       rc_err_oom_die(rc);
-     }
-     assert(*pDb!=0);
-     rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
-     rc_err_oom_die(rc);
-     rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
-     rc_err_oom_die(rc);
-     rc = sqlite3_step(pStmt);
-     rc_err_oom_die(rc);
-     sqlite3_finalize(pStmt);
-     return 0;
-   }else if( *pDb==0 ){
-     return 0;
-   }else{
-     /* Formulate the columns spec, close the DB, zero *pDb. */
-     char *zColsSpec = 0;
-     int hasDupes = db_int(*pDb, zHasDupes);
- #ifdef SQLITE_ENABLE_MATH_FUNCTIONS
-     int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
- #else
- # define nDigits 2
- #endif
-     if( hasDupes ){
-       rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
-       rc_err_oom_die(rc);
-       rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0);
-       rc_err_oom_die(rc);
-       rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0);
-       rc_err_oom_die(rc);
-       rc = sqlite3_bind_int(pStmt, 1, nDigits);
-       rc_err_oom_die(rc);
-       rc = sqlite3_step(pStmt);
-       sqlite3_finalize(pStmt);
-       assert(rc==SQLITE_DONE);
-     }
-     assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
-     rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
-     rc_err_oom_die(rc);
-     rc = sqlite3_step(pStmt);
-     if( rc==SQLITE_ROW ){
-       zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
-     }else{
-       zColsSpec = 0;
-     }
-     if( pRenamed!=0 ) *pRenamed = hasDupes;
-     sqlite3_finalize(pStmt);
-     sqlite3_close(*pDb);
-     *pDb = 0;
-     return zColsSpec;
-   }
- }
 +
  /*
  ** When running the ".recover" command, each output table, and the special
  ** orphaned row table if it is required, is represented by an instance
@@@ -8000,6 -7819,6 +7820,166 @@@ static int recoverDatabaseCmd(ShellStat
  }
  #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
  
++
++/* 
++ * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
++ * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
++ *   close db and set it to 0, and return the columns spec, to later
++ *   be sqlite3_free()'ed by the caller.
++ * The return is 0 when either:
++ *   (a) The db was not initialized and zCol==0 (There are no columns.)
++ *   (b) zCol!=0  (Column was added, db initialized as needed.)
++ * The 3rd argument, pRenamed, references an out parameter. If the
++ * pointer is non-zero, its referent will be set to 1 if renaming was
++ * necessary, or set to 0 if none was done.
++ */
++#ifdef SHELL_DEBUG
++#define rc_err_oom_die(rc) \
++  if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
++  else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
++    fprintf(stderr,"E:%d\n",rc), assert(0)
++#else
++static void rc_err_oom_die(int rc){
++  if( rc==SQLITE_NOMEM ) shell_check_oom(0);
++  assert(rc==SQLITE_OK||rc==SQLITE_DONE);
++}
++#endif
++
++#ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */
++static char zCOL_DB[] = SHELL_STRINGIFY(SHELL_COLFIX_DB);
++#else  /* Otherwise, memory is faster/better for the transient DB. */
++static const char *zCOL_DB = ":memory:";
++#endif
++
++/* Define character (as C string) to separate generated column ordinal
++ * from protected part of incoming column names. This defaults to "_"
++ * so that incoming column identifiers that did not need not be quoted
++ * remain usable without being quoted. It must be one character.
++ */
++#ifndef SHELL_AUTOCOLUMN_SEP
++# define AUTOCOLUMN_SEP "_"
++#else
++# define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP)
++#endif
++
++static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, int *pRenamed){
++  /* Queries and D{D,M}L used here */
++  static const char * const zTabMake = "\
++CREATE TABLE ColNames(\
++ cpos INTEGER PRIMARY KEY,\
++ name TEXT, nlen INT, chop INT, reps INT, suff TEXT)\
++";
++  static const char * const zTabFill = "\
++INSERT INTO ColNames(name,nlen,chop,reps,suff)\
++ VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\
++";
++  static const char * const zHasDupes = "\
++SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\
++ <count(name) FROM ColNames\
++";
++  static const char * const zDedoctor = "\
++UPDATE ColNames SET chop=iif(\
++  (substring(name,nlen,1) BETWEEN '0' AND '9')\
++  AND (rtrim(name,'0123456790') glob '*"AUTOCOLUMN_SEP"'),\
++ nlen-length(rtrim(name, '"AUTOCOLUMN_SEP"0123456789')),\
++ 0\
++)\
++";
++  static const char * const zSetReps = "\
++UPDATE ColNames AS t SET reps=\
++(SELECT count(*) FROM ColNames d \
++ WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\
++ COLLATE NOCASE\
++)\
++";
++#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
++  static const char * const zColDigits = "\
++SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
++";
++#endif
++  static const char * const zRenameRank =
++#ifndef SHELL_COLUMN_RENAME_DML
++    "UPDATE ColNames AS t SET suff="
++    "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
++#else
++    SHELL_COLUMN_RENAME_DML
++#endif
++    ;
++  static const char * const zCollectVar = "\
++SELECT\
++ '('||x'0a'\
++ || group_concat(\
++  cname||' TEXT',\
++  ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\
++ ||')' AS ColsSpec \
++FROM (\
++ SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
++ FROM ColNames ORDER BY cpos\
++)";
++
++  int rc;
++  sqlite3_stmt *pStmt = 0;
++  assert(pDb!=0);
++  if( zColNew ){
++    /* Add initial or additional column. Init db if necessary. */
++    if( *pDb==0 ){
++      if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
++#ifdef SHELL_COLFIX_DB
++      if(*zCOL_DB!=':')
++        sqlite3_exec(*pDb,"drop table if exists ColNames",0,0,0);
++#endif
++      rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
++      rc_err_oom_die(rc);
++    }
++    assert(*pDb!=0);
++    rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
++    rc_err_oom_die(rc);
++    rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
++    rc_err_oom_die(rc);
++    rc = sqlite3_step(pStmt);
++    rc_err_oom_die(rc);
++    sqlite3_finalize(pStmt);
++    return 0;
++  }else if( *pDb==0 ){
++    return 0;
++  }else{
++    /* Formulate the columns spec, close the DB, zero *pDb. */
++    char *zColsSpec = 0;
++    int hasDupes = db_int(*pDb, zHasDupes);
++#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
++    int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
++#else
++# define nDigits 2
++#endif
++    if( hasDupes ){
++      rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
++      rc_err_oom_die(rc);
++      rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0);
++      rc_err_oom_die(rc);
++      rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0);
++      rc_err_oom_die(rc);
++      sqlite3_bind_int(pStmt, 1, nDigits);
++      rc = sqlite3_step(pStmt);
++      sqlite3_finalize(pStmt);
++      assert(rc==SQLITE_DONE);
++    }
++    assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
++    rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
++    rc_err_oom_die(rc);
++    rc = sqlite3_step(pStmt);
++    if( rc==SQLITE_ROW ){
++      zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
++    }else{
++      zColsSpec = 0;
++    }
++    if( pRenamed!=0 ) *pRenamed = hasDupes;
++    sqlite3_finalize(pStmt);
++    sqlite3_close(*pDb);
++    *pDb = 0;
++    return zColsSpec;
++  }
++}
++
  /*
  ** If an input line begins with "." then invoke this routine to
  ** process that line.