/ Check-in [acf10b3f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge ALTER TABLE and sqlite3_normalized_sql() fixes from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA3-256: acf10b3f8d6675ddf787f7db55a9ff0ec5729adb6fa70b48b13d2cd71862cffd
User & Date: drh 2018-12-06 00:05:18
Wiki:begin-concurrent
Context
2018-12-06
02:08
Merge bug fixes from trunk. check-in: 1e13aaa2 user: drh tags: begin-concurrent
00:08
Merge ALTER TABLE and sqlite3_normalized_sql() bug fixes from trunk. check-in: 3793e5d5 user: drh tags: begin-concurrent-pnu
00:05
Merge ALTER TABLE and sqlite3_normalized_sql() fixes from trunk. check-in: acf10b3f user: drh tags: begin-concurrent
2018-12-05
23:56
Get rid of the hash table used to track IN operators in the sqlite3_normalized_sql() implementation. Use simple integer variables instead. check-in: 272dc74f user: drh tags: trunk
13:44
Merge enhancements from trunk, especially the enhanced sqlite3_normalized_sql() interface. check-in: 47b73f6b user: drh tags: begin-concurrent
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to VERSION.

     1         -3.26.0
            1  +3.27.0

Changes to configure.

     1      1   #! /bin/sh
     2      2   # Guess values for system-dependent variables and create Makefiles.
     3         -# Generated by GNU Autoconf 2.69 for sqlite 3.26.0.
            3  +# Generated by GNU Autoconf 2.69 for sqlite 3.27.0.
     4      4   #
     5      5   #
     6      6   # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
     7      7   #
     8      8   #
     9      9   # This configure script is free software; the Free Software Foundation
    10     10   # gives unlimited permission to copy, distribute and modify it.
................................................................................
   722    722   subdirs=
   723    723   MFLAGS=
   724    724   MAKEFLAGS=
   725    725   
   726    726   # Identity of this package.
   727    727   PACKAGE_NAME='sqlite'
   728    728   PACKAGE_TARNAME='sqlite'
   729         -PACKAGE_VERSION='3.26.0'
   730         -PACKAGE_STRING='sqlite 3.26.0'
          729  +PACKAGE_VERSION='3.27.0'
          730  +PACKAGE_STRING='sqlite 3.27.0'
   731    731   PACKAGE_BUGREPORT=''
   732    732   PACKAGE_URL=''
   733    733   
   734    734   # Factoring default headers for most tests.
   735    735   ac_includes_default="\
   736    736   #include <stdio.h>
   737    737   #ifdef HAVE_SYS_TYPES_H
................................................................................
  1462   1462   #
  1463   1463   # Report the --help message.
  1464   1464   #
  1465   1465   if test "$ac_init_help" = "long"; then
  1466   1466     # Omit some internal or obsolete options to make the list less imposing.
  1467   1467     # This message is too long to be a string in the A/UX 3.1 sh.
  1468   1468     cat <<_ACEOF
  1469         -\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems.
         1469  +\`configure' configures sqlite 3.27.0 to adapt to many kinds of systems.
  1470   1470   
  1471   1471   Usage: $0 [OPTION]... [VAR=VALUE]...
  1472   1472   
  1473   1473   To assign environment variables (e.g., CC, CFLAGS...), specify them as
  1474   1474   VAR=VALUE.  See below for descriptions of some of the useful variables.
  1475   1475   
  1476   1476   Defaults for the options are specified in brackets.
................................................................................
  1527   1527     --build=BUILD     configure for building on BUILD [guessed]
  1528   1528     --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  1529   1529   _ACEOF
  1530   1530   fi
  1531   1531   
  1532   1532   if test -n "$ac_init_help"; then
  1533   1533     case $ac_init_help in
  1534         -     short | recursive ) echo "Configuration of sqlite 3.26.0:";;
         1534  +     short | recursive ) echo "Configuration of sqlite 3.27.0:";;
  1535   1535      esac
  1536   1536     cat <<\_ACEOF
  1537   1537   
  1538   1538   Optional Features:
  1539   1539     --disable-option-checking  ignore unrecognized --enable/--with options
  1540   1540     --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  1541   1541     --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
  1653   1653       cd "$ac_pwd" || { ac_status=$?; break; }
  1654   1654     done
  1655   1655   fi
  1656   1656   
  1657   1657   test -n "$ac_init_help" && exit $ac_status
  1658   1658   if $ac_init_version; then
  1659   1659     cat <<\_ACEOF
  1660         -sqlite configure 3.26.0
         1660  +sqlite configure 3.27.0
  1661   1661   generated by GNU Autoconf 2.69
  1662   1662   
  1663   1663   Copyright (C) 2012 Free Software Foundation, Inc.
  1664   1664   This configure script is free software; the Free Software Foundation
  1665   1665   gives unlimited permission to copy, distribute and modify it.
  1666   1666   _ACEOF
  1667   1667     exit
................................................................................
  2072   2072     eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  2073   2073   
  2074   2074   } # ac_fn_c_check_header_mongrel
  2075   2075   cat >config.log <<_ACEOF
  2076   2076   This file contains any messages produced by compilers while
  2077   2077   running configure, to aid debugging if configure makes a mistake.
  2078   2078   
  2079         -It was created by sqlite $as_me 3.26.0, which was
         2079  +It was created by sqlite $as_me 3.27.0, which was
  2080   2080   generated by GNU Autoconf 2.69.  Invocation command line was
  2081   2081   
  2082   2082     $ $0 $@
  2083   2083   
  2084   2084   _ACEOF
  2085   2085   exec 5>>config.log
  2086   2086   {
................................................................................
 12228  12228   test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
 12229  12229   
 12230  12230   cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 12231  12231   # Save the log message, to keep $0 and so on meaningful, and to
 12232  12232   # report actual input values of CONFIG_FILES etc. instead of their
 12233  12233   # values after options handling.
 12234  12234   ac_log="
 12235         -This file was extended by sqlite $as_me 3.26.0, which was
        12235  +This file was extended by sqlite $as_me 3.27.0, which was
 12236  12236   generated by GNU Autoconf 2.69.  Invocation command line was
 12237  12237   
 12238  12238     CONFIG_FILES    = $CONFIG_FILES
 12239  12239     CONFIG_HEADERS  = $CONFIG_HEADERS
 12240  12240     CONFIG_LINKS    = $CONFIG_LINKS
 12241  12241     CONFIG_COMMANDS = $CONFIG_COMMANDS
 12242  12242     $ $0 $@
................................................................................
 12294  12294   
 12295  12295   Report bugs to the package provider."
 12296  12296   
 12297  12297   _ACEOF
 12298  12298   cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 12299  12299   ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 12300  12300   ac_cs_version="\\
 12301         -sqlite config.status 3.26.0
        12301  +sqlite config.status 3.27.0
 12302  12302   configured by $0, generated by GNU Autoconf 2.69,
 12303  12303     with options \\"\$ac_cs_config\\"
 12304  12304   
 12305  12305   Copyright (C) 2012 Free Software Foundation, Inc.
 12306  12306   This config.status script is free software; the Free Software Foundation
 12307  12307   gives unlimited permission to copy, distribute and modify it."
 12308  12308   

Changes to src/alter.c.

   775    775         pToken->pNext = pCtx->pList;
   776    776         pCtx->pList = pToken;
   777    777         pCtx->nList++;
   778    778         break;
   779    779       }
   780    780     }
   781    781   }
          782  +
          783  +/*
          784  +** Iterate through the Select objects that are part of WITH clauses attached
          785  +** to select statement pSelect.
          786  +*/
          787  +static void renameWalkWith(Walker *pWalker, Select *pSelect){
          788  +  if( pSelect->pWith ){
          789  +    int i;
          790  +    for(i=0; i<pSelect->pWith->nCte; i++){
          791  +      Select *p = pSelect->pWith->a[i].pSelect;
          792  +      NameContext sNC;
          793  +      memset(&sNC, 0, sizeof(sNC));
          794  +      sNC.pParse = pWalker->pParse;
          795  +      sqlite3SelectPrep(sNC.pParse, p, &sNC);
          796  +      sqlite3WalkSelect(pWalker, p);
          797  +    }
          798  +  }
          799  +}
   782    800   
   783    801   /*
   784    802   ** This is a Walker select callback. It does nothing. It is only required
   785    803   ** because without a dummy callback, sqlite3WalkExpr() and similar do not
   786    804   ** descend into sub-select statements.
   787    805   */
   788    806   static int renameColumnSelectCb(Walker *pWalker, Select *p){
   789         -  UNUSED_PARAMETER(pWalker);
   790         -  UNUSED_PARAMETER(p);
          807  +  renameWalkWith(pWalker, p);
   791    808     return WRC_Continue;
   792    809   }
   793    810   
   794    811   /*
   795    812   ** This is a Walker expression callback.
   796    813   **
   797    814   ** For every TK_COLUMN node in the expression tree, search to see
................................................................................
  1360   1377     SrcList *pSrc = pSelect->pSrc;
  1361   1378     for(i=0; i<pSrc->nSrc; i++){
  1362   1379       struct SrcList_item *pItem = &pSrc->a[i];
  1363   1380       if( pItem->pTab==p->pTab ){
  1364   1381         renameTokenFind(pWalker->pParse, p, pItem->zName);
  1365   1382       }
  1366   1383     }
         1384  +  renameWalkWith(pWalker, pSelect);
  1367   1385   
  1368   1386     return WRC_Continue;
  1369   1387   }
  1370   1388   
  1371   1389   
  1372   1390   /*
  1373   1391   ** This C function implements an SQL user function that is used by SQL code

Changes to src/callback.c.

   279    279     return match;
   280    280   }
   281    281   
   282    282   /*
   283    283   ** Search a FuncDefHash for a function with the given name.  Return
   284    284   ** a pointer to the matching FuncDef if found, or 0 if there is no match.
   285    285   */
   286         -static FuncDef *functionSearch(
          286  +FuncDef *sqlite3FunctionSearch(
   287    287     int h,               /* Hash of the name */
   288    288     const char *zFunc    /* Name of function */
   289    289   ){
   290    290     FuncDef *p;
   291    291     for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
   292    292       if( sqlite3StrICmp(p->zName, zFunc)==0 ){
   293    293         return p;
   294    294       }
   295    295     }
   296    296     return 0;
   297    297   }
   298         -#ifdef SQLITE_ENABLE_NORMALIZE
   299         -FuncDef *sqlite3FunctionSearchN(
   300         -  int h,               /* Hash of the name */
   301         -  const char *zFunc,   /* Name of function */
   302         -  int nFunc            /* Length of the name */
   303         -){
   304         -  FuncDef *p;
   305         -  for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
   306         -    if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
   307         -      return p;
   308         -    }
   309         -  }
   310         -  return 0;
   311         -}
   312         -#endif /* SQLITE_ENABLE_NORMALIZE */
   313    298   
   314    299   /*
   315    300   ** Insert a new FuncDef into a FuncDefHash hash table.
   316    301   */
   317    302   void sqlite3InsertBuiltinFuncs(
   318    303     FuncDef *aDef,      /* List of global functions to be inserted */
   319    304     int nDef            /* Length of the apDef[] list */
................................................................................
   321    306     int i;
   322    307     for(i=0; i<nDef; i++){
   323    308       FuncDef *pOther;
   324    309       const char *zName = aDef[i].zName;
   325    310       int nName = sqlite3Strlen30(zName);
   326    311       int h = SQLITE_FUNC_HASH(zName[0], nName);
   327    312       assert( zName[0]>='a' && zName[0]<='z' );
   328         -    pOther = functionSearch(h, zName);
          313  +    pOther = sqlite3FunctionSearch(h, zName);
   329    314       if( pOther ){
   330    315         assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
   331    316         aDef[i].pNext = pOther->pNext;
   332    317         pOther->pNext = &aDef[i];
   333    318       }else{
   334    319         aDef[i].pNext = 0;
   335    320         aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
................................................................................
   399    384     ** have fields overwritten with new information appropriate for the
   400    385     ** new function.  But the FuncDefs for built-in functions are read-only.
   401    386     ** So we must not search for built-ins when creating a new function.
   402    387     */ 
   403    388     if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
   404    389       bestScore = 0;
   405    390       h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
   406         -    p = functionSearch(h, zName);
          391  +    p = sqlite3FunctionSearch(h, zName);
   407    392       while( p ){
   408    393         int score = matchQuality(p, nArg, enc);
   409    394         if( score>bestScore ){
   410    395           pBest = p;
   411    396           bestScore = score;
   412    397         }
   413    398         p = p->pNext;

Changes to src/expr.c.

  2145   2145   */
  2146   2146   int sqlite3IsRowid(const char *z){
  2147   2147     if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
  2148   2148     if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
  2149   2149     if( sqlite3StrICmp(z, "OID")==0 ) return 1;
  2150   2150     return 0;
  2151   2151   }
  2152         -#ifdef SQLITE_ENABLE_NORMALIZE
  2153         -int sqlite3IsRowidN(const char *z, int n){
  2154         -  if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
  2155         -  if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
  2156         -  if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
  2157         -  return 0;
  2158         -}
  2159         -#endif
  2160   2152   
  2161   2153   /*
  2162   2154   ** pX is the RHS of an IN operator.  If pX is a SELECT statement 
  2163   2155   ** that can be simplified to a direct table access, then return
  2164   2156   ** a pointer to the SELECT statement.  If pX is not a SELECT statement,
  2165   2157   ** or if the SELECT statement needs to be manifested into a transient
  2166   2158   ** table, then return NULL.

Changes to src/hash.c.

    60     60       ** 0x9e3779b1 is 2654435761 which is the closest prime number to
    61     61       ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
    62     62       h += sqlite3UpperToLower[c];
    63     63       h *= 0x9e3779b1;
    64     64     }
    65     65     return h;
    66     66   }
    67         -#ifdef SQLITE_ENABLE_NORMALIZE
    68         -static unsigned int strHashN(const char *z, int n){
    69         -  unsigned int h = 0;
    70         -  int i;
    71         -  for(i=0; i<n; i++){
    72         -    /* Knuth multiplicative hashing.  (Sorting & Searching, p. 510).
    73         -    ** 0x9e3779b1 is 2654435761 which is the closest prime number to
    74         -    ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
    75         -    h += sqlite3UpperToLower[(unsigned char)z[i]];
    76         -    h *= 0x9e3779b1;
    77         -  }
    78         -  return h;
    79         -}
    80         -#endif /* SQLITE_ENABLE_NORMALIZE */
    81     67   
    82     68   
    83     69   /* Link pNew element into the hash table pH.  If pEntry!=0 then also
    84     70   ** insert pNew into the pEntry hash bucket.
    85     71   */
    86     72   static void insertElement(
    87     73     Hash *pH,              /* The complete hash table */
................................................................................
   185    171       if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ 
   186    172         return elem;
   187    173       }
   188    174       elem = elem->next;
   189    175     }
   190    176     return &nullElement;
   191    177   }
   192         -#ifdef SQLITE_ENABLE_NORMALIZE
   193         -static HashElem *findElementWithHashN(
   194         -  const Hash *pH,     /* The pH to be searched */
   195         -  const char *pKey,   /* The key we are searching for */
   196         -  int nKey,           /* Number of key bytes to use */
   197         -  unsigned int *pHash /* Write the hash value here */
   198         -){
   199         -  HashElem *elem;                /* Used to loop thru the element list */
   200         -  int count;                     /* Number of elements left to test */
   201         -  unsigned int h;                /* The computed hash */
   202         -  static HashElem nullElement = { 0, 0, 0, 0 };
   203         -
   204         -  if( pH->ht ){   /*OPTIMIZATION-IF-TRUE*/
   205         -    struct _ht *pEntry;
   206         -    h = strHashN(pKey, nKey) % pH->htsize;
   207         -    pEntry = &pH->ht[h];
   208         -    elem = pEntry->chain;
   209         -    count = pEntry->count;
   210         -  }else{
   211         -    h = 0;
   212         -    elem = pH->first;
   213         -    count = pH->count;
   214         -  }
   215         -  if( pHash ) *pHash = h;
   216         -  while( count-- ){
   217         -    assert( elem!=0 );
   218         -    if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ 
   219         -      return elem;
   220         -    }
   221         -    elem = elem->next;
   222         -  }
   223         -  return &nullElement;
   224         -}
   225         -#endif /* SQLITE_ENABLE_NORMALIZE */
   226    178   
   227    179   /* Remove a single entry from the hash table given a pointer to that
   228    180   ** element and a hash on the element's key.
   229    181   */
   230    182   static void removeElementGivenHash(
   231    183     Hash *pH,         /* The pH containing "elem" */
   232    184     HashElem* elem,   /* The element to be removed from the pH */
................................................................................
   263    215   ** found, or NULL if there is no match.
   264    216   */
   265    217   void *sqlite3HashFind(const Hash *pH, const char *pKey){
   266    218     assert( pH!=0 );
   267    219     assert( pKey!=0 );
   268    220     return findElementWithHash(pH, pKey, 0)->data;
   269    221   }
   270         -#ifdef SQLITE_ENABLE_NORMALIZE
   271         -void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
   272         -  assert( pH!=0 );
   273         -  assert( pKey!=0 );
   274         -  assert( nKey>=0 );
   275         -  return findElementWithHashN(pH, pKey, nKey, 0)->data;
   276         -}
   277         -#endif /* SQLITE_ENABLE_NORMALIZE */
   278    222   
   279    223   /* Insert an element into the hash table pH.  The key is pKey
   280    224   ** and the data is "data".
   281    225   **
   282    226   ** If no element exists with a matching key, then a new
   283    227   ** element is created and NULL is returned.
   284    228   **

Changes to src/hash.h.

    64     64   
    65     65   /*
    66     66   ** Access routines.  To delete, insert a NULL pointer.
    67     67   */
    68     68   void sqlite3HashInit(Hash*);
    69     69   void *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
    70     70   void *sqlite3HashFind(const Hash*, const char *pKey);
    71         -#ifdef SQLITE_ENABLE_NORMALIZE
    72         -void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey);
    73         -#endif
    74     71   void sqlite3HashClear(Hash*);
    75     72   
    76     73   /*
    77     74   ** Macros for looping over all elements of a hash table.  The idiom is
    78     75   ** like this:
    79     76   **
    80     77   **   Hash h;

Changes to src/prepare.c.

   706    706     rc = sqlite3ApiExit(db, rc);
   707    707     assert( (rc&db->errMask)==rc );
   708    708     sqlite3_mutex_leave(db->mutex);
   709    709     return rc;
   710    710   }
   711    711   
   712    712   #ifdef SQLITE_ENABLE_NORMALIZE
   713         -/*
   714         -** Checks if the specified token is a table, column, or function name,
   715         -** based on the databases associated with the statement being prepared.
   716         -** If the function fails, zero is returned and pRc is filled with the
   717         -** error code.
   718         -*/
   719         -static int shouldTreatAsIdentifier(
   720         -  sqlite3 *db,        /* Database handle. */
   721         -  const char *zToken, /* Pointer to start of token to be checked */
   722         -  int nToken,         /* Length of token to be checked */
   723         -  int *pRc            /* Pointer to error code upon failure */
   724         -){
   725         -  int bFound = 0;     /* Non-zero if token is an identifier name. */
   726         -  int i, j;           /* Database and column loop indexes. */
   727         -  Schema *pSchema;    /* Schema for current database. */
   728         -  Hash *pHash;        /* Hash table of tables for current database. */
   729         -  HashElem *e;        /* Hash element for hash table iteration. */
   730         -  Table *pTab;        /* Database table for columns being checked. */
   731         -
   732         -  if( sqlite3IsRowidN(zToken, nToken) ){
   733         -    return 1;
   734         -  }
   735         -  if( nToken>0 ){
   736         -    int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
   737         -    if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
   738         -  }
   739         -  assert( db!=0 );
   740         -  sqlite3_mutex_enter(db->mutex);
   741         -  sqlite3BtreeEnterAll(db);
   742         -  for(i=0; i<db->nDb; i++){
   743         -    pHash = &db->aFunc;
   744         -    if( sqlite3HashFindN(pHash, zToken, nToken) ){
   745         -      bFound = 1;
   746         -      break;
   747         -    }
   748         -    pSchema = db->aDb[i].pSchema;
   749         -    if( pSchema==0 ) continue;
   750         -    pHash = &pSchema->tblHash;
   751         -    if( sqlite3HashFindN(pHash, zToken, nToken) ){
   752         -      bFound = 1;
   753         -      break;
   754         -    }
   755         -    for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
   756         -      pTab = sqliteHashData(e);
   757         -      if( pTab==0 ) continue;
   758         -      pHash = pTab->pColHash;
   759         -      if( pHash==0 ){
   760         -        pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
   761         -        if( pHash ){
   762         -          sqlite3HashInit(pHash);
   763         -          for(j=0; j<pTab->nCol; j++){
   764         -            Column *pCol = &pTab->aCol[j];
   765         -            sqlite3HashInsert(pHash, pCol->zName, pCol);
   766         -          }
   767         -        }else{
   768         -          *pRc = SQLITE_NOMEM_BKPT;
   769         -          bFound = 0;
   770         -          goto done;
   771         -        }
   772         -      }
   773         -      if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
   774         -        bFound = 1;
   775         -        goto done;
   776         -      }
   777         -    }
   778         -  }
   779         -done:
   780         -  sqlite3BtreeLeaveAll(db);
   781         -  sqlite3_mutex_leave(db->mutex);
   782         -  return bFound;
   783         -}
   784    713   
   785    714   /*
   786    715   ** Attempt to estimate the final output buffer size needed for the fully
   787    716   ** normalized version of the specified SQL string.  This should take into
   788    717   ** account any potential expansion that could occur (e.g. via IN clauses
   789    718   ** being expanded, etc).  This size returned is the total number of bytes
   790    719   ** including the NUL terminator.
................................................................................
   860    789     int nZ;                /* Size of the output string in bytes */
   861    790     int i;                 /* Next character to read from zSql[] */
   862    791     int j;                 /* Next character to fill in on z[] */
   863    792     int tokenType = 0;     /* Type of the next token */
   864    793     int prevTokenType = 0; /* Type of the previous token, except spaces */
   865    794     int n;                 /* Size of the next token */
   866    795     int nParen = 0;        /* Nesting level of parenthesis */
   867         -  Hash inHash;           /* Table of parenthesis levels to output index. */
          796  +  int iStartIN = 0;      /* Start of RHS of IN operator in z[] */
          797  +  int nParenAtIN = 0;    /* Value of nParent at start of RHS of IN operator */
   868    798   
   869    799     db = sqlite3VdbeDb(pVdbe);
   870    800     assert( db!=0 );
   871    801     if( zSql==0 ) return 0;
   872    802     nZ = estimateNormalizedSize(zSql, nSql);
   873    803     z = sqlite3DbMallocRawNN(db, nZ);
   874    804     if( z==0 ) goto normalizeError;
   875         -  sqlite3HashInit(&inHash);
   876    805     for(i=j=0; i<nSql && zSql[i]; i+=n){
   877    806       int flags = 0;
   878    807       if( tokenType!=TK_SPACE ) prevTokenType = tokenType;
   879    808       n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags);
   880    809       switch( tokenType ){
   881    810         case TK_SPACE: {
   882    811           break;
................................................................................
   893    822           break;
   894    823         }
   895    824         case TK_LP:
   896    825         case TK_RP: {
   897    826           if( tokenType==TK_LP ){
   898    827             nParen++;
   899    828             if( prevTokenType==TK_IN ){
   900         -            assert( nParen<nSql );
   901         -            sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j));
          829  +            iStartIN = j;
          830  +            nParenAtIN = nParen;
   902    831             }
   903    832           }else{
   904         -          int jj;
   905         -          assert( nParen<nSql );
   906         -          jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen));
   907         -          if( jj>0 ){
   908         -            sqlite3HashInsert(&inHash, zSql+nParen, 0);
   909         -            assert( jj+6<nZ );
   910         -            memcpy(z+jj+1, "?,?,?", 5);
   911         -            j = jj+6;
          833  +          if( iStartIN>0 && nParen==nParenAtIN ){
          834  +            assert( iStartIN+6<nZ );
          835  +            memcpy(z+iStartIN+1, "?,?,?", 5);
          836  +            j = iStartIN+6;
   912    837               assert( nZ-1-j>=0 );
   913    838               assert( nZ-1-j<nZ );
   914    839               memset(z+j, 0, nZ-1-j);
          840  +            iStartIN = 0;
   915    841             }
   916    842             nParen--;
   917    843           }
   918    844           assert( nParen>=0 );
   919    845           /* Fall through */
   920    846         }
   921    847         case TK_MINUS:
................................................................................
   952    878               break;
   953    879             }
   954    880           }
   955    881           if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
   956    882             z[j++] = ' ';
   957    883           }
   958    884           if( tokenType==TK_ID ){
   959         -          int i2 = i, n2 = n, rc = SQLITE_OK;
   960         -          if( nParen>0 ){
   961         -            assert( nParen<nSql );
   962         -            sqlite3HashInsert(&inHash, zSql+nParen, 0);
   963         -          }
          885  +          int i2 = i, n2 = n;
          886  +          if( nParen==nParenAtIN ) iStartIN = 0;
   964    887             if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
   965         -          if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){
   966         -            if( rc!=SQLITE_OK ) goto normalizeError;
   967         -            if( sqlite3_keyword_check(zSql+i2, n2)==0 ){
   968         -              z[j++] = '?';
   969         -              break;
   970         -            }
   971         -          }
   972    888           }
   973    889           copyNormalizedToken(zSql, i, n, flags, z, &j);
   974    890           break;
   975    891         }
   976    892       }
   977    893     }
   978    894     assert( j<nZ && "one" );
   979    895     while( j>0 && z[j-1]==' ' ){ j--; }
   980    896     if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
   981    897     z[j] = 0;
   982    898     assert( j<nZ && "two" );
   983         -  sqlite3HashClear(&inHash);
   984    899     return z;
   985    900   
   986    901   normalizeError:
   987    902     sqlite3DbFree(db, z);
   988         -  sqlite3HashClear(&inHash);
   989    903     return 0;
   990    904   }
   991    905   #endif /* SQLITE_ENABLE_NORMALIZE */
   992    906   
   993    907   /*
   994    908   ** Rerun the compilation of a statement after a schema change.
   995    909   **

Changes to src/sqliteInt.h.

  4024   4024   #ifdef SQLITE_ENABLE_CURSOR_HINTS
  4025   4025   int sqlite3ExprContainsSubquery(Expr*);
  4026   4026   #endif
  4027   4027   int sqlite3ExprIsInteger(Expr*, int*);
  4028   4028   int sqlite3ExprCanBeNull(const Expr*);
  4029   4029   int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
  4030   4030   int sqlite3IsRowid(const char*);
  4031         -#ifdef SQLITE_ENABLE_NORMALIZE
  4032         -int sqlite3IsRowidN(const char*, int);
  4033         -#endif
  4034   4031   void sqlite3GenerateRowDelete(
  4035   4032       Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
  4036   4033   void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
  4037   4034   int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
  4038   4035   void sqlite3ResolvePartIdxLabel(Parse*,int);
  4039   4036   int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
  4040   4037   void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
................................................................................
  4053   4050   void sqlite3UniqueConstraint(Parse*, int, Index*);
  4054   4051   void sqlite3RowidConstraint(Parse*, int, Table*);
  4055   4052   Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
  4056   4053   ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
  4057   4054   SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
  4058   4055   IdList *sqlite3IdListDup(sqlite3*,IdList*);
  4059   4056   Select *sqlite3SelectDup(sqlite3*,Select*,int);
  4060         -#ifdef SQLITE_ENABLE_NORMALIZE
  4061         -FuncDef *sqlite3FunctionSearchN(int,const char*,int);
  4062         -#endif
         4057  +FuncDef *sqlite3FunctionSearch(int,const char*);
  4063   4058   void sqlite3InsertBuiltinFuncs(FuncDef*,int);
  4064   4059   FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
  4065   4060   void sqlite3RegisterBuiltinFunctions(void);
  4066   4061   void sqlite3RegisterDateTimeFunctions(void);
  4067   4062   void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
  4068   4063   int sqlite3SafetyCheckOk(sqlite3*);
  4069   4064   int sqlite3SafetyCheckSickOrOk(sqlite3*);

Changes to test/altertab2.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #*************************************************************************
    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15         -set testprefix altertab
           15  +set testprefix altertab2
    16     16   
    17     17   # If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
    18     18   ifcapable !altertable {
    19     19     finish_test
    20     20     return
    21     21   }
    22     22   
................................................................................
    81     81     SELECT sql FROM sqlite_master WHERE name LIKE 'c%';
    82     82   } {
    83     83     {CREATE TABLE c1(x REFERENCES "p3")}
    84     84     {CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p3")}
    85     85     {CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p3"(a))}
    86     86   }
    87     87   
           88  +#-------------------------------------------------------------------------
           89  +# Table name in WITH clauses that are part of views or triggers.
           90  +#
           91  +foreach {tn schema} {
           92  +  1 {
           93  +    CREATE TABLE log_entry(col1, y);
           94  +    CREATE INDEX i1 ON log_entry(col1);
           95  +  }
           96  +
           97  +  2 {
           98  +    CREATE TABLE t1(a, b, c);
           99  +    CREATE TABLE t2(x);
          100  +    CREATE TABLE log_entry(col1);
          101  +    CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
          102  +      INSERT INTO t2 SELECT col1 FROM log_entry;
          103  +    END;
          104  +  }
          105  +
          106  +  3 {
          107  +    CREATE TABLE t1(a, b, c);
          108  +    CREATE TABLE t2(x);
          109  +    CREATE TABLE log_entry(col1);
          110  +    CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
          111  +      INSERT INTO t2
          112  +        WITH xyz(x) AS (SELECT col1 FROM log_entry)
          113  +        SELECT x FROM xyz;
          114  +    END;
          115  +  }
          116  +
          117  +  4 {
          118  +    CREATE TABLE log_entry(col1);
          119  +    CREATE VIEW ttt AS
          120  +        WITH xyz(x) AS (SELECT col1 FROM log_entry)
          121  +        SELECT x FROM xyz;
          122  +  }
          123  +} {
          124  +  reset_db
          125  +  do_execsql_test 3.$tn.1 $schema
          126  +  set expect [db eval "SELECT sql FROM sqlite_master"]
          127  +  set expect [string map {log_entry {"newname"}} $expect]
          128  +
          129  +  do_execsql_test 3.$tn.2 {
          130  +    ALTER TABLE log_entry RENAME TO newname;
          131  +    SELECT sql FROM sqlite_master;
          132  +  } $expect
          133  +
          134  +  reset_db
          135  +  do_execsql_test 3.$tn.3 $schema
          136  +  set expect [db eval "SELECT sql FROM sqlite_master"]
          137  +  set expect [string map {col1 newname} $expect]
          138  +
          139  +  do_execsql_test 3.$tn.4 {
          140  +    ALTER TABLE log_entry RENAME col1 TO newname;
          141  +    SELECT sql FROM sqlite_master;
          142  +  } $expect
          143  +}
    88    144   
    89    145   finish_test

Changes to test/normalize.test.

    82     82     set STMT [sqlite3_prepare_v3 $DB \
    83     83         "SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 0 TAIL]
    84     84   
    85     85     sqlite3_bind_null $STMT 1
    86     86   } {}
    87     87   do_test 202 {
    88     88     sqlite3_normalized_sql $STMT
    89         -} {}
           89  +} {SELECT a,b FROM t1 WHERE b=?ORDER BY a;}
    90     90   do_test 203 {
    91     91     sqlite3_finalize $STMT
    92     92   } {SQLITE_OK}
    93     93   
    94     94   do_test 210 {
    95     95     set STMT [sqlite3_prepare_v3 $DB \
    96     96         "SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 2 TAIL]
................................................................................
   203    203     {SELECT a FROM t1 WHERE x IN (1,2,3) AND hex8('abc');}
   204    204     0x2
   205    205     {0 {SELECT a FROM t1 WHERE x IN(?,?,?)AND hex8(?);}}
   206    206   
   207    207     430
   208    208     {SELECT "a" FROM t1 WHERE "x" IN ("1","2",'3');}
   209    209     0x2
   210         -  {0 {SELECT"a"FROM t1 WHERE"x"IN(?,?,?);}}
          210  +  {0 {SELECT"a"FROM t1 WHERE"x"IN("1","2",?);}}
   211    211   
   212    212     440
   213    213     {SELECT 'a' FROM t1 WHERE 'x';}
   214    214     0x2
   215    215     {0 {SELECT?FROM t1 WHERE?;}}
   216    216   
   217    217     450