/ Check-in [87f261f0]
Login

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

Overview
Comment:Make the internal dynamic string interface available to extensions using the new sqlite3_str object and its associated methods. This is mostly just a renaming of internal objects and methods to use external names, through there are a few small wrapper functions.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 87f261f0cb800b06ad786f6df16f2c4dddd0d93dfdcc77b4a4eaa22920b56bf1
User & Date: drh 2018-05-09 13:46:26
Context
2018-05-09
14:29
Fix minor problems with the sqlite3_str interface. check-in: 43ea8a68 user: drh tags: trunk
13:46
Make the internal dynamic string interface available to extensions using the new sqlite3_str object and its associated methods. This is mostly just a renaming of internal objects and methods to use external names, through there are a few small wrapper functions. check-in: 87f261f0 user: drh tags: trunk
10:11
Fix a typo in a comment used for documentation. No code changes. check-in: b866693e user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  9246   9246   ){
  9247   9247     va_list ap;
  9248   9248     if( !pCheck->mxErr ) return;
  9249   9249     pCheck->mxErr--;
  9250   9250     pCheck->nErr++;
  9251   9251     va_start(ap, zFormat);
  9252   9252     if( pCheck->errMsg.nChar ){
  9253         -    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
         9253  +    sqlite3_str_append(&pCheck->errMsg, "\n", 1);
  9254   9254     }
  9255   9255     if( pCheck->zPfx ){
  9256         -    sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
         9256  +    sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
  9257   9257     }
  9258         -  sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
         9258  +  sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
  9259   9259     va_end(ap);
  9260         -  if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
         9260  +  if( pCheck->errMsg.accError==SQLITE_NOMEM ){
  9261   9261       pCheck->mallocFailed = 1;
  9262   9262     }
  9263   9263   }
  9264   9264   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  9265   9265   
  9266   9266   #ifndef SQLITE_OMIT_INTEGRITY_CHECK
  9267   9267   
................................................................................
  9837   9837   
  9838   9838     /* Clean  up and report errors.
  9839   9839     */
  9840   9840   integrity_ck_cleanup:
  9841   9841     sqlite3PageFree(sCheck.heap);
  9842   9842     sqlite3_free(sCheck.aPgRef);
  9843   9843     if( sCheck.mallocFailed ){
  9844         -    sqlite3StrAccumReset(&sCheck.errMsg);
         9844  +    sqlite3_str_reset(&sCheck.errMsg);
  9845   9845       sCheck.nErr++;
  9846   9846     }
  9847   9847     *pnErr = sCheck.nErr;
  9848         -  if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
         9848  +  if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
  9849   9849     /* Make sure this analysis did not leave any unref() pages. */
  9850   9850     assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
  9851   9851     sqlite3BtreeLeave(p);
  9852   9852     return sqlite3StrAccumFinish(&sCheck.errMsg);
  9853   9853   }
  9854   9854   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  9855   9855   

Changes to src/build.c.

  4203   4203     char *zErr;
  4204   4204     int j;
  4205   4205     StrAccum errMsg;
  4206   4206     Table *pTab = pIdx->pTable;
  4207   4207   
  4208   4208     sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
  4209   4209     if( pIdx->aColExpr ){
  4210         -    sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
         4210  +    sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
  4211   4211     }else{
  4212   4212       for(j=0; j<pIdx->nKeyCol; j++){
  4213   4213         char *zCol;
  4214   4214         assert( pIdx->aiColumn[j]>=0 );
  4215   4215         zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
  4216         -      if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
  4217         -      sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
  4218         -      sqlite3StrAccumAppend(&errMsg, ".", 1);
  4219         -      sqlite3StrAccumAppendAll(&errMsg, zCol);
         4216  +      if( j ) sqlite3_str_append(&errMsg, ", ", 2);
         4217  +      sqlite3_str_appendall(&errMsg, pTab->zName);
         4218  +      sqlite3_str_append(&errMsg, ".", 1);
         4219  +      sqlite3_str_appendall(&errMsg, zCol);
  4220   4220       }
  4221   4221     }
  4222   4222     zErr = sqlite3StrAccumFinish(&errMsg);
  4223   4223     sqlite3HaltConstraint(pParse, 
  4224   4224       IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY 
  4225   4225                               : SQLITE_CONSTRAINT_UNIQUE,
  4226   4226       onError, zErr, P4_DYNAMIC, P5_ConstraintUnique);

Changes to src/func.c.

   247    247   
   248    248     if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
   249    249       x.nArg = argc-1;
   250    250       x.nUsed = 0;
   251    251       x.apArg = argv+1;
   252    252       sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
   253    253       str.printfFlags = SQLITE_PRINTF_SQLFUNC;
   254         -    sqlite3XPrintf(&str, zFormat, &x);
          254  +    sqlite3_str_appendf(&str, zFormat, &x);
   255    255       n = str.nChar;
   256    256       sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
   257    257                           SQLITE_DYNAMIC);
   258    258     }
   259    259   }
   260    260   
   261    261   /*
................................................................................
  1650   1650         if( argc==2 ){
  1651   1651           zSep = (char*)sqlite3_value_text(argv[1]);
  1652   1652           nSep = sqlite3_value_bytes(argv[1]);
  1653   1653         }else{
  1654   1654           zSep = ",";
  1655   1655           nSep = 1;
  1656   1656         }
  1657         -      if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
         1657  +      if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
  1658   1658       }
  1659   1659       zVal = (char*)sqlite3_value_text(argv[0]);
  1660   1660       nVal = sqlite3_value_bytes(argv[0]);
  1661         -    if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
         1661  +    if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
  1662   1662     }
  1663   1663   }
  1664   1664   static void groupConcatFinalize(sqlite3_context *context){
  1665   1665     StrAccum *pAccum;
  1666   1666     pAccum = sqlite3_aggregate_context(context, 0);
  1667   1667     if( pAccum ){
  1668         -    if( pAccum->accError==STRACCUM_TOOBIG ){
         1668  +    if( pAccum->accError==SQLITE_TOOBIG ){
  1669   1669         sqlite3_result_error_toobig(context);
  1670         -    }else if( pAccum->accError==STRACCUM_NOMEM ){
         1670  +    }else if( pAccum->accError==SQLITE_NOMEM ){
  1671   1671         sqlite3_result_error_nomem(context);
  1672   1672       }else{    
  1673   1673         sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
  1674   1674                             sqlite3_free);
  1675   1675       }
  1676   1676     }
  1677   1677   }

Changes to src/mutex.c.

   354    354   int sqlite3_mutex_notheld(sqlite3_mutex *p){
   355    355     assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
   356    356     return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
   357    357   }
   358    358   #endif
   359    359   
   360    360   #endif /* !defined(SQLITE_MUTEX_OMIT) */
   361         -

Changes to src/pragma.c.

  2212   2212     char cSep = '(';
  2213   2213     StrAccum acc;
  2214   2214     char zBuf[200];
  2215   2215   
  2216   2216     UNUSED_PARAMETER(argc);
  2217   2217     UNUSED_PARAMETER(argv);
  2218   2218     sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  2219         -  sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
         2219  +  sqlite3_str_appendall(&acc, "CREATE TABLE x");
  2220   2220     for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
  2221         -    sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
         2221  +    sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]);
  2222   2222       cSep = ',';
  2223   2223     }
  2224   2224     if( i==0 ){
  2225         -    sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
         2225  +    sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName);
  2226   2226       cSep = ',';
  2227   2227       i++;
  2228   2228     }
  2229   2229     j = 0;
  2230   2230     if( pPragma->mPragFlg & PragFlg_Result1 ){
  2231         -    sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
         2231  +    sqlite3_str_appendall(&acc, ",arg HIDDEN");
  2232   2232       j++;
  2233   2233     }
  2234   2234     if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
  2235         -    sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
         2235  +    sqlite3_str_appendall(&acc, ",schema HIDDEN");
  2236   2236       j++;
  2237   2237     }
  2238         -  sqlite3StrAccumAppend(&acc, ")", 1);
         2238  +  sqlite3_str_append(&acc, ")", 1);
  2239   2239     sqlite3StrAccumFinish(&acc);
  2240   2240     assert( strlen(zBuf) < sizeof(zBuf)-1 );
  2241   2241     rc = sqlite3_declare_vtab(db, zBuf);
  2242   2242     if( rc==SQLITE_OK ){
  2243   2243       pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
  2244   2244       if( pTab==0 ){
  2245   2245         rc = SQLITE_NOMEM;
................................................................................
  2383   2383         pCsr->azArg[j] = sqlite3_mprintf("%s", zText);
  2384   2384         if( pCsr->azArg[j]==0 ){
  2385   2385           return SQLITE_NOMEM;
  2386   2386         }
  2387   2387       }
  2388   2388     }
  2389   2389     sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
  2390         -  sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
         2390  +  sqlite3_str_appendall(&acc, "PRAGMA ");
  2391   2391     if( pCsr->azArg[1] ){
  2392         -    sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
         2392  +    sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]);
  2393   2393     }
  2394         -  sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
         2394  +  sqlite3_str_appendall(&acc, pTab->pName->zName);
  2395   2395     if( pCsr->azArg[0] ){
  2396         -    sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
         2396  +    sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]);
  2397   2397     }
  2398   2398     zSql = sqlite3StrAccumFinish(&acc);
  2399   2399     if( zSql==0 ) return SQLITE_NOMEM;
  2400   2400     rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
  2401   2401     sqlite3_free(zSql);
  2402   2402     if( rc!=SQLITE_OK ){
  2403   2403       pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));

Changes to src/printf.c.

   130    130   }
   131    131   #endif /* SQLITE_OMIT_FLOATING_POINT */
   132    132   
   133    133   /*
   134    134   ** Set the StrAccum object to an error mode.
   135    135   */
   136    136   static void setStrAccumError(StrAccum *p, u8 eError){
   137         -  assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
          137  +  assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
   138    138     p->accError = eError;
   139    139     p->nAlloc = 0;
   140    140   }
   141    141   
   142    142   /*
   143    143   ** Extra argument values from a PrintfArguments object
   144    144   */
................................................................................
   164    164   # define SQLITE_PRINT_BUF_SIZE 70
   165    165   #endif
   166    166   #define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
   167    167   
   168    168   /*
   169    169   ** Render a string given by "fmt" into the StrAccum object.
   170    170   */
   171         -void sqlite3VXPrintf(
   172         -  StrAccum *pAccum,          /* Accumulate results here */
          171  +void sqlite3_str_vappendf(
          172  +  sqlite3_str *pAccum,       /* Accumulate results here */
   173    173     const char *fmt,           /* Format string */
   174    174     va_list ap                 /* arguments */
   175    175   ){
   176    176     int c;                     /* Next character in the format string */
   177    177     char *bufpt;               /* Pointer to the conversion buffer */
   178    178     int precision;             /* Precision of the current field */
   179    179     int length;                /* Length of the field */
................................................................................
   222    222       if( c!='%' ){
   223    223         bufpt = (char *)fmt;
   224    224   #if HAVE_STRCHRNUL
   225    225         fmt = strchrnul(fmt, '%');
   226    226   #else
   227    227         do{ fmt++; }while( *fmt && *fmt != '%' );
   228    228   #endif
   229         -      sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
          229  +      sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
   230    230         if( *fmt==0 ) break;
   231    231       }
   232    232       if( (c=(*++fmt))==0 ){
   233         -      sqlite3StrAccumAppend(pAccum, "%", 1);
          233  +      sqlite3_str_append(pAccum, "%", 1);
   234    234         break;
   235    235       }
   236    236       /* Find out what flags are present */
   237    237       flag_leftjustify = flag_prefix = cThousand =
   238    238        flag_alternateform = flag_altform2 = flag_zeropad = 0;
   239    239       done = 0;
   240    240       do{
................................................................................
   404    404           if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
   405    405             nOut = etBUFSIZE;
   406    406             zOut = buf;
   407    407           }else{
   408    408             u64 n = (u64)precision + 10 + precision/3;
   409    409             zOut = zExtra = sqlite3Malloc( n );
   410    410             if( zOut==0 ){
   411         -            setStrAccumError(pAccum, STRACCUM_NOMEM);
          411  +            setStrAccumError(pAccum, SQLITE_NOMEM);
   412    412               return;
   413    413             }
   414    414             nOut = (int)n;
   415    415           }
   416    416           bufpt = &zOut[nOut-1];
   417    417           if( xtype==etORDINAL ){
   418    418             static const char zOrd[] = "thstndrd";
................................................................................
   529    529           }else{
   530    530             e2 = exp;
   531    531           }
   532    532           if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
   533    533             bufpt = zExtra 
   534    534                 = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
   535    535             if( bufpt==0 ){
   536         -            setStrAccumError(pAccum, STRACCUM_NOMEM);
          536  +            setStrAccumError(pAccum, SQLITE_NOMEM);
   537    537               return;
   538    538             }
   539    539           }
   540    540           zOut = bufpt;
   541    541           nsd = 16 + flag_altform2*10;
   542    542           flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
   543    543           /* The sign in front of the number */
................................................................................
   661    661               buf[3] = 0x80 + (u8)(ch & 0x3f);
   662    662               length = 4;
   663    663             }
   664    664           }
   665    665           if( precision>1 ){
   666    666             width -= precision-1;
   667    667             if( width>1 && !flag_leftjustify ){
   668         -            sqlite3AppendChar(pAccum, width-1, ' ');
          668  +            sqlite3_str_appendchar(pAccum, width-1, ' ');
   669    669               width = 0;
   670    670             }
   671    671             while( precision-- > 1 ){
   672         -            sqlite3StrAccumAppend(pAccum, buf, length);
          672  +            sqlite3_str_append(pAccum, buf, length);
   673    673             }
   674    674           }
   675    675           bufpt = buf;
   676    676           flag_altform2 = 1;
   677    677           goto adjust_width_for_utf8;
   678    678         case etSTRING:
   679    679         case etDYNSTRING:
................................................................................
   751    751             }
   752    752           }
   753    753           needQuote = !isnull && xtype==etSQLESCAPE2;
   754    754           n += i + 3;
   755    755           if( n>etBUFSIZE ){
   756    756             bufpt = zExtra = sqlite3Malloc( n );
   757    757             if( bufpt==0 ){
   758         -            setStrAccumError(pAccum, STRACCUM_NOMEM);
          758  +            setStrAccumError(pAccum, SQLITE_NOMEM);
   759    759               return;
   760    760             }
   761    761           }else{
   762    762             bufpt = buf;
   763    763           }
   764    764           j = 0;
   765    765           if( needQuote ) bufpt[j++] = q;
................................................................................
   775    775         }
   776    776         case etTOKEN: {
   777    777           Token *pToken;
   778    778           if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
   779    779           pToken = va_arg(ap, Token*);
   780    780           assert( bArgList==0 );
   781    781           if( pToken && pToken->n ){
   782         -          sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
          782  +          sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n);
   783    783           }
   784    784           length = width = 0;
   785    785           break;
   786    786         }
   787    787         case etSRCLIST: {
   788    788           SrcList *pSrc;
   789    789           int k;
................................................................................
   791    791           if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
   792    792           pSrc = va_arg(ap, SrcList*);
   793    793           k = va_arg(ap, int);
   794    794           pItem = &pSrc->a[k];
   795    795           assert( bArgList==0 );
   796    796           assert( k>=0 && k<pSrc->nSrc );
   797    797           if( pItem->zDatabase ){
   798         -          sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
   799         -          sqlite3StrAccumAppend(pAccum, ".", 1);
          798  +          sqlite3_str_appendall(pAccum, pItem->zDatabase);
          799  +          sqlite3_str_append(pAccum, ".", 1);
   800    800           }
   801         -        sqlite3StrAccumAppendAll(pAccum, pItem->zName);
          801  +        sqlite3_str_appendall(pAccum, pItem->zName);
   802    802           length = width = 0;
   803    803           break;
   804    804         }
   805    805         default: {
   806    806           assert( xtype==etINVALID );
   807    807           return;
   808    808         }
................................................................................
   813    813       ** the output.  Both length and width are in bytes, not characters,
   814    814       ** at this point.  If the "!" flag was present on string conversions
   815    815       ** indicating that width and precision should be expressed in characters,
   816    816       ** then the values have been translated prior to reaching this point.
   817    817       */
   818    818       width -= length;
   819    819       if( width>0 ){
   820         -      if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
   821         -      sqlite3StrAccumAppend(pAccum, bufpt, length);
   822         -      if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
          820  +      if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
          821  +      sqlite3_str_append(pAccum, bufpt, length);
          822  +      if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' ');
   823    823       }else{
   824         -      sqlite3StrAccumAppend(pAccum, bufpt, length);
          824  +      sqlite3_str_append(pAccum, bufpt, length);
   825    825       }
   826    826   
   827    827       if( zExtra ){
   828    828         sqlite3DbFree(pAccum->db, zExtra);
   829    829         zExtra = 0;
   830    830       }
   831    831     }/* End for loop over the format string */
................................................................................
   838    838   ** Return the number of bytes of text that StrAccum is able to accept
   839    839   ** after the attempted enlargement.  The value returned might be zero.
   840    840   */
   841    841   static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
   842    842     char *zNew;
   843    843     assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
   844    844     if( p->accError ){
   845         -    testcase(p->accError==STRACCUM_TOOBIG);
   846         -    testcase(p->accError==STRACCUM_NOMEM);
          845  +    testcase(p->accError==SQLITE_TOOBIG);
          846  +    testcase(p->accError==SQLITE_NOMEM);
   847    847       return 0;
   848    848     }
   849    849     if( p->mxAlloc==0 ){
   850    850       N = p->nAlloc - p->nChar - 1;
   851         -    setStrAccumError(p, STRACCUM_TOOBIG);
          851  +    setStrAccumError(p, SQLITE_TOOBIG);
   852    852       return N;
   853    853     }else{
   854    854       char *zOld = isMalloced(p) ? p->zText : 0;
   855    855       i64 szNew = p->nChar;
   856    856       szNew += N + 1;
   857    857       if( szNew+p->nChar<=p->mxAlloc ){
   858    858         /* Force exponential buffer size growth as long as it does not overflow,
   859    859         ** to avoid having to call this routine too often */
   860    860         szNew += p->nChar;
   861    861       }
   862    862       if( szNew > p->mxAlloc ){
   863         -      sqlite3StrAccumReset(p);
   864         -      setStrAccumError(p, STRACCUM_TOOBIG);
          863  +      sqlite3_str_reset(p);
          864  +      setStrAccumError(p, SQLITE_TOOBIG);
   865    865         return 0;
   866    866       }else{
   867    867         p->nAlloc = (int)szNew;
   868    868       }
   869    869       if( p->db ){
   870    870         zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
   871    871       }else{
................................................................................
   874    874       if( zNew ){
   875    875         assert( p->zText!=0 || p->nChar==0 );
   876    876         if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
   877    877         p->zText = zNew;
   878    878         p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
   879    879         p->printfFlags |= SQLITE_PRINTF_MALLOCED;
   880    880       }else{
   881         -      sqlite3StrAccumReset(p);
   882         -      setStrAccumError(p, STRACCUM_NOMEM);
          881  +      sqlite3_str_reset(p);
          882  +      setStrAccumError(p, SQLITE_NOMEM);
   883    883         return 0;
   884    884       }
   885    885     }
   886    886     return N;
   887    887   }
   888    888   
   889    889   /*
   890    890   ** Append N copies of character c to the given string buffer.
   891    891   */
   892         -void sqlite3AppendChar(StrAccum *p, int N, char c){
          892  +void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){
   893    893     testcase( p->nChar + (i64)N > 0x7fffffff );
   894    894     if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
   895    895       return;
   896    896     }
   897    897     while( (N--)>0 ) p->zText[p->nChar++] = c;
   898    898   }
   899    899   
   900    900   /*
   901    901   ** The StrAccum "p" is not large enough to accept N new bytes of z[].
   902    902   ** So enlarge if first, then do the append.
   903    903   **
   904         -** This is a helper routine to sqlite3StrAccumAppend() that does special-case
          904  +** This is a helper routine to sqlite3_str_append() that does special-case
   905    905   ** work (enlarging the buffer) using tail recursion, so that the
   906         -** sqlite3StrAccumAppend() routine can use fast calling semantics.
          906  +** sqlite3_str_append() routine can use fast calling semantics.
   907    907   */
   908    908   static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
   909    909     N = sqlite3StrAccumEnlarge(p, N);
   910    910     if( N>0 ){
   911    911       memcpy(&p->zText[p->nChar], z, N);
   912    912       p->nChar += N;
   913    913     }
   914    914   }
   915    915   
   916    916   /*
   917    917   ** Append N bytes of text from z to the StrAccum object.  Increase the
   918    918   ** size of the memory allocation for StrAccum if necessary.
   919    919   */
   920         -void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
          920  +void sqlite3_str_append(sqlite3_str *p, const char *z, int N){
   921    921     assert( z!=0 || N==0 );
   922    922     assert( p->zText!=0 || p->nChar==0 || p->accError );
   923    923     assert( N>=0 );
   924    924     assert( p->accError==0 || p->nAlloc==0 );
   925    925     if( p->nChar+N >= p->nAlloc ){
   926    926       enlargeAndAppend(p,z,N);
   927    927     }else if( N ){
................................................................................
   930    930       memcpy(&p->zText[p->nChar-N], z, N);
   931    931     }
   932    932   }
   933    933   
   934    934   /*
   935    935   ** Append the complete text of zero-terminated string z[] to the p string.
   936    936   */
   937         -void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
   938         -  sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
          937  +void sqlite3_str_appendall(sqlite3_str *p, const char *z){
          938  +  sqlite3_str_append(p, z, sqlite3Strlen30(z));
   939    939   }
   940    940   
   941    941   
   942    942   /*
   943    943   ** Finish off a string by making sure it is zero-terminated.
   944    944   ** Return a pointer to the resulting string.  Return a NULL
   945    945   ** pointer if any kind of error was encountered.
................................................................................
   948    948     char *zText;
   949    949     assert( p->mxAlloc>0 && !isMalloced(p) );
   950    950     zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
   951    951     if( zText ){
   952    952       memcpy(zText, p->zText, p->nChar+1);
   953    953       p->printfFlags |= SQLITE_PRINTF_MALLOCED;
   954    954     }else{
   955         -    setStrAccumError(p, STRACCUM_NOMEM);
          955  +    setStrAccumError(p, SQLITE_NOMEM);
   956    956     }
   957    957     p->zText = zText;
   958    958     return zText;
   959    959   }
   960    960   char *sqlite3StrAccumFinish(StrAccum *p){
   961    961     if( p->zText ){
   962    962       p->zText[p->nChar] = 0;
   963    963       if( p->mxAlloc>0 && !isMalloced(p) ){
   964    964         return strAccumFinishRealloc(p);
   965    965       }
   966    966     }
   967    967     return p->zText;
   968    968   }
          969  +
          970  +/* Finalize a string created using sqlite3_str_new().
          971  +*/
          972  +char *sqlite3_str_finish(sqlite3_str *p){
          973  +  char *z;
          974  +  if( p ){
          975  +    z = sqlite3StrAccumFinish(p);
          976  +    sqlite3DbFree(p->db, p);
          977  +  }else{
          978  +    z = 0;
          979  +  }
          980  +  return z;
          981  +}
          982  +
          983  +/* Return any error code associated with p */
          984  +int sqlite3_str_errcode(sqlite3_str *p){
          985  +  return p ? p->accError : SQLITE_NOMEM;
          986  +}
          987  +
          988  +/* Return the current length of p in bytes */
          989  +int sqlite3_str_length(sqlite3_str *p){
          990  +  return p ? p->nChar : 0;
          991  +}
          992  +
          993  +/* Return the current value for p */
          994  +char *sqlite3_str_value(sqlite3_str *p){
          995  +  return p ? p->zText : 0;
          996  +}
   969    997   
   970    998   /*
   971    999   ** Reset an StrAccum string.  Reclaim all malloced memory.
   972   1000   */
   973         -void sqlite3StrAccumReset(StrAccum *p){
         1001  +void sqlite3_str_reset(StrAccum *p){
   974   1002     if( isMalloced(p) ){
   975   1003       sqlite3DbFree(p->db, p->zText);
   976   1004       p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
   977   1005     }
   978   1006     p->zText = 0;
   979   1007   }
   980   1008   
................................................................................
   997   1025     p->db = db;
   998   1026     p->nAlloc = n;
   999   1027     p->mxAlloc = mx;
  1000   1028     p->nChar = 0;
  1001   1029     p->accError = 0;
  1002   1030     p->printfFlags = 0;
  1003   1031   }
         1032  +
         1033  +/* Allocate and initialize a new dynamic string object */
         1034  +sqlite3_str *sqlite3_str_new(sqlite3 *db){
         1035  +  sqlite3_str *p = sqlite3DbMallocRaw(db, sizeof(*p));
         1036  +  if( p ){
         1037  +    sqlite3StrAccumInit(p, db, 0, 0, SQLITE_MAX_LENGTH);
         1038  +  }
         1039  +  return p;
         1040  +}
  1004   1041   
  1005   1042   /*
  1006   1043   ** Print into memory obtained from sqliteMalloc().  Use the internal
  1007   1044   ** %-conversion extensions.
  1008   1045   */
  1009   1046   char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
  1010   1047     char *z;
  1011   1048     char zBase[SQLITE_PRINT_BUF_SIZE];
  1012   1049     StrAccum acc;
  1013   1050     assert( db!=0 );
  1014   1051     sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
  1015   1052                         db->aLimit[SQLITE_LIMIT_LENGTH]);
  1016   1053     acc.printfFlags = SQLITE_PRINTF_INTERNAL;
  1017         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1054  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1018   1055     z = sqlite3StrAccumFinish(&acc);
  1019         -  if( acc.accError==STRACCUM_NOMEM ){
         1056  +  if( acc.accError==SQLITE_NOMEM ){
  1020   1057       sqlite3OomFault(db);
  1021   1058     }
  1022   1059     return z;
  1023   1060   }
  1024   1061   
  1025   1062   /*
  1026   1063   ** Print into memory obtained from sqliteMalloc().  Use the internal
................................................................................
  1050   1087       return 0;
  1051   1088     }
  1052   1089   #endif
  1053   1090   #ifndef SQLITE_OMIT_AUTOINIT
  1054   1091     if( sqlite3_initialize() ) return 0;
  1055   1092   #endif
  1056   1093     sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
  1057         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1094  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1058   1095     z = sqlite3StrAccumFinish(&acc);
  1059   1096     return z;
  1060   1097   }
  1061   1098   
  1062   1099   /*
  1063   1100   ** Print into memory obtained from sqlite3_malloc()().  Omit the internal
  1064   1101   ** %-conversion extensions.
................................................................................
  1095   1132     if( zBuf==0 || zFormat==0 ) {
  1096   1133       (void)SQLITE_MISUSE_BKPT;
  1097   1134       if( zBuf ) zBuf[0] = 0;
  1098   1135       return zBuf;
  1099   1136     }
  1100   1137   #endif
  1101   1138     sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
  1102         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1139  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1103   1140     zBuf[acc.nChar] = 0;
  1104   1141     return zBuf;
  1105   1142   }
  1106   1143   char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
  1107   1144     char *z;
  1108   1145     va_list ap;
  1109   1146     va_start(ap,zFormat);
................................................................................
  1117   1154   ** We house it in a separate routine from sqlite3_log() to avoid using
  1118   1155   ** stack space on small-stack systems when logging is disabled.
  1119   1156   **
  1120   1157   ** sqlite3_log() must render into a static buffer.  It cannot dynamically
  1121   1158   ** allocate memory because it might be called while the memory allocator
  1122   1159   ** mutex is held.
  1123   1160   **
  1124         -** sqlite3VXPrintf() might ask for *temporary* memory allocations for
         1161  +** sqlite3_str_vappendf() might ask for *temporary* memory allocations for
  1125   1162   ** certain format characters (%q) or for very large precisions or widths.
  1126   1163   ** Care must be taken that any sqlite3_log() calls that occur while the
  1127   1164   ** memory mutex is held do not use these mechanisms.
  1128   1165   */
  1129   1166   static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
  1130   1167     StrAccum acc;                          /* String accumulator */
  1131   1168     char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
  1132   1169   
  1133   1170     sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
  1134         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1171  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1135   1172     sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
  1136   1173                              sqlite3StrAccumFinish(&acc));
  1137   1174   }
  1138   1175   
  1139   1176   /*
  1140   1177   ** Format and write a message to the log if logging is enabled.
  1141   1178   */
................................................................................
  1156   1193   */
  1157   1194   void sqlite3DebugPrintf(const char *zFormat, ...){
  1158   1195     va_list ap;
  1159   1196     StrAccum acc;
  1160   1197     char zBuf[500];
  1161   1198     sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  1162   1199     va_start(ap,zFormat);
  1163         -  sqlite3VXPrintf(&acc, zFormat, ap);
         1200  +  sqlite3_str_vappendf(&acc, zFormat, ap);
  1164   1201     va_end(ap);
  1165   1202     sqlite3StrAccumFinish(&acc);
  1166   1203   #ifdef SQLITE_OS_TRACE_PROC
  1167   1204     {
  1168   1205       extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf);
  1169   1206       SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf));
  1170   1207     }
................................................................................
  1173   1210     fflush(stdout);
  1174   1211   #endif
  1175   1212   }
  1176   1213   #endif
  1177   1214   
  1178   1215   
  1179   1216   /*
  1180         -** variable-argument wrapper around sqlite3VXPrintf().  The bFlags argument
         1217  +** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument
  1181   1218   ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
  1182   1219   */
  1183         -void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
         1220  +void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
  1184   1221     va_list ap;
  1185   1222     va_start(ap,zFormat);
  1186         -  sqlite3VXPrintf(p, zFormat, ap);
         1223  +  sqlite3_str_vappendf(p, zFormat, ap);
  1187   1224     va_end(ap);
  1188   1225   }

Changes to src/sqlite.h.in.

  7128   7128   ** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option.  Also,
  7129   7129   ** new keywords may be added to future releases of SQLite.
  7130   7130   */
  7131   7131   int sqlite3_keyword_count(void);
  7132   7132   int sqlite3_keyword_name(int,const char**,int*);
  7133   7133   int sqlite3_keyword_check(const char*,int);
  7134   7134   
         7135  +/*
         7136  +** CAPI3REF: Dynamic String Object
         7137  +** KEYWORDS: {dynamic string}
         7138  +**
         7139  +** An instance of the sqlite3_str object contains a dynamically-sized
         7140  +** string under construction.
         7141  +**
         7142  +** The lifecycle of an sqlite3_str object is as follows:
         7143  +** <ol>
         7144  +** <li> The sqlite3_str object is created using [sqlite3_str_new()].
         7145  +** <li> Text is appended to the sqlite3_str object using various
         7146  +** methods, such as [sqlite3_str_appendf()].
         7147  +** <li> The sqlite3_str object is destroyed and the string it created
         7148  +** is returned using the [sqlite3_str_finish()] interface.
         7149  +** </ol>
         7150  +*/
         7151  +typedef struct sqlite3_str sqlite3_str;
         7152  +
         7153  +/*
         7154  +** CAPI3REF: Create A New Dynamic String Object
         7155  +** CONSTRUCTOR: sqlite3_str
         7156  +**
         7157  +** The [sqlite3_str_new(D)] allocates and initializes a new [sqlite3_str]
         7158  +** object.  The [sqlite3_str_new(D)] interface returns NULL on an out-of-memory
         7159  +** condition.  To avoid memory leaks, the object returned by
         7160  +** [sqlite3_str_new(D)] must be freed by a subsequent call to 
         7161  +** [sqlite3_str_finish(S)].
         7162  +**
         7163  +** If the D argument to [sqlite3_str_new(D)] is NULL then memory used to
         7164  +** construct the string is always taken from the global memory pool used
         7165  +** by [sqlite3_malloc64()].  If D is not NULL, then a private memory pool
         7166  +** used by connection D might also be used.  This private memory pool is
         7167  +** faster, but is limited in space, and should only be used for transient
         7168  +** allocations.  The final string returned by [sqlite3_str_finish(X)] is
         7169  +** always stored in space obtained from [sqlite3_malloc64()] regardless
         7170  +** of whether or not the private per-connection memory pool is used during
         7171  +** its construction.
         7172  +*/
         7173  +sqlite3_str *sqlite3_str_new(sqlite3*);
         7174  +
         7175  +/*
         7176  +** CAPI3REF: Finalize A Dynamic String
         7177  +** DESTRUCTOR: sqlite3_str
         7178  +**
         7179  +** The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
         7180  +** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
         7181  +** that contains the constructed string.  The calling application should
         7182  +** pass the returned value to [sqlite3_free()] to avoid a memory leak.
         7183  +** The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
         7184  +** errors were encountered during construction of the string.  The
         7185  +** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
         7186  +** string in [sqlite3_str] object X is zero bytes long.
         7187  +*/
         7188  +char *sqlite3_str_finish(sqlite3_str*);
         7189  +
         7190  +/*
         7191  +** CAPI3REF: Add Content To A Dynamic String
         7192  +** METHOD: sqlite3_str
         7193  +**
         7194  +** These interfaces add content to an sqlite3_str object previously obtained
         7195  +** from [sqlite3_str_new()].
         7196  +**
         7197  +** The [sqlite3_str_appendf(X,F,...)] and 
         7198  +** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
         7199  +** functionality of SQLite to append formatted text onto the end of 
         7200  +** [sqlite3_str] object X.
         7201  +**
         7202  +** The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
         7203  +** onto the end of the [sqlite3_str] object X.  N must be non-negative.
         7204  +** S must contain at least N non-zero bytes of content.  To append a
         7205  +** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
         7206  +** method instead.
         7207  +**
         7208  +** The [sqlite3_str_appendall(X,S)] method the complete content of
         7209  +** zero-terminated string S onto the end of [sqlite3_str] object X.
         7210  +**
         7211  +** The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
         7212  +** single-byte character C onto the end of [sqlite3_str] object X.
         7213  +** This method can be used, for example, to add whitespace indentation.
         7214  +**
         7215  +** The [sqlite3_str_reset(X)] method resets the string under construction
         7216  +** inside [sqlite3_str] object X back to zero bytes in length.  
         7217  +**
         7218  +** These methods do not return a result code.  If an error occurs, that fact
         7219  +** is recorded in the [sqlite3_str] object and can be recovered by a
         7220  +** subsequent call to [sqlite3_str_errcode(X)].
         7221  +*/
         7222  +void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
         7223  +void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
         7224  +void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
         7225  +void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
         7226  +void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
         7227  +void sqlite3_str_reset(sqlite3_str*);
         7228  +
         7229  +/*
         7230  +** CAPI3REF: Status Of A Dynamic String
         7231  +** METHOD: sqlite3_str
         7232  +**
         7233  +** These interfaces return the current status of an [sqlite3_str] object.
         7234  +**
         7235  +** If any prior errors have occurred while constructing the dynamic string
         7236  +** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
         7237  +** an appropriate error code.  The [sqlite3_str_errcode(X)] method returns
         7238  +** [SQLITE_NOMEM] following any out-of-memory error, or
         7239  +** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
         7240  +** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
         7241  +**
         7242  +** The [sqlite3_str_length(X)] method returns the current length, in bytes,
         7243  +** of the dynamic string under construction in [sqlite3_str] object X.
         7244  +** The length returned by [sqlite3_str_length(X)] does not include the
         7245  +** zero-termination byte.
         7246  +**
         7247  +** The [sqlite3_str_value(X)] method returns a pointer to the current
         7248  +** content of the dynamic string under construction in X.  The value
         7249  +** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
         7250  +** and might be freed or altered by any subsequent method on the same
         7251  +** [sqlite3_str] object.  Applications must not used the pointer returned
         7252  +** [sqlite3_str_value(X)] after any subsequent method call on the same
         7253  +** object.  Applications may change the content of the string returned
         7254  +** by [sqlite3_str_value(X)] as long as they do not write into any bytes
         7255  +** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
         7256  +** write any byte after any subsequent sqlite3_str method call.
         7257  +*/
         7258  +int sqlite3_str_errcode(sqlite3_str*);
         7259  +int sqlite3_str_length(sqlite3_str*);
         7260  +char *sqlite3_str_value(sqlite3_str*);
         7261  +
  7135   7262   /*
  7136   7263   ** CAPI3REF: SQLite Runtime Status
  7137   7264   **
  7138   7265   ** ^These interfaces are used to retrieve runtime status information
  7139   7266   ** about the performance of SQLite, and optionally to reset various
  7140   7267   ** highwater marks.  ^The first argument is an integer code for
  7141   7268   ** the specific parameter to measure.  ^(Recognized integer codes

Changes to src/sqliteInt.h.

  1089   1089   typedef struct PrintfArguments PrintfArguments;
  1090   1090   typedef struct RowSet RowSet;
  1091   1091   typedef struct Savepoint Savepoint;
  1092   1092   typedef struct Select Select;
  1093   1093   typedef struct SQLiteThread SQLiteThread;
  1094   1094   typedef struct SelectDest SelectDest;
  1095   1095   typedef struct SrcList SrcList;
  1096         -typedef struct StrAccum StrAccum;
         1096  +typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */
  1097   1097   typedef struct Table Table;
  1098   1098   typedef struct TableLock TableLock;
  1099   1099   typedef struct Token Token;
  1100   1100   typedef struct TreeView TreeView;
  1101   1101   typedef struct Trigger Trigger;
  1102   1102   typedef struct TriggerPrg TriggerPrg;
  1103   1103   typedef struct TriggerStep TriggerStep;
................................................................................
  3269   3269     const Token *pName; /* Name of the container - used for error messages */
  3270   3270   };
  3271   3271   
  3272   3272   /*
  3273   3273   ** An objected used to accumulate the text of a string where we
  3274   3274   ** do not necessarily know how big the string will be in the end.
  3275   3275   */
  3276         -struct StrAccum {
         3276  +struct sqlite3_str {
  3277   3277     sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
  3278   3278     char *zText;         /* The string collected so far */
  3279   3279     u32  nAlloc;         /* Amount of space allocated in zText */
  3280   3280     u32  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
  3281   3281     u32  nChar;          /* Length of the string so far */
  3282         -  u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
         3282  +  u8   accError;       /* SQLITE_NOMEM or SQLITE_TOOBIG */
  3283   3283     u8   printfFlags;    /* SQLITE_PRINTF flags below */
  3284   3284   };
  3285         -#define STRACCUM_NOMEM   1
  3286         -#define STRACCUM_TOOBIG  2
  3287   3285   #define SQLITE_PRINTF_INTERNAL 0x01  /* Internal-use-only converters allowed */
  3288   3286   #define SQLITE_PRINTF_SQLFUNC  0x02  /* SQL function arguments to VXPrintf */
  3289   3287   #define SQLITE_PRINTF_MALLOCED 0x04  /* True if xText is allocated space */
  3290   3288   
  3291   3289   #define isMalloced(X)  (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
  3292   3290   
  3293   3291   
................................................................................
  3648   3646   */
  3649   3647   struct PrintfArguments {
  3650   3648     int nArg;                /* Total number of arguments */
  3651   3649     int nUsed;               /* Number of arguments used so far */
  3652   3650     sqlite3_value **apArg;   /* The argument values */
  3653   3651   };
  3654   3652   
  3655         -void sqlite3VXPrintf(StrAccum*, const char*, va_list);
  3656         -void sqlite3XPrintf(StrAccum*, const char*, ...);
  3657   3653   char *sqlite3MPrintf(sqlite3*,const char*, ...);
  3658   3654   char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
  3659   3655   #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
  3660   3656     void sqlite3DebugPrintf(const char*, ...);
  3661   3657   #endif
  3662   3658   #if defined(SQLITE_TEST)
  3663   3659     void *sqlite3TestTextToPtr(const char*);
................................................................................
  4172   4168   );
  4173   4169   void sqlite3OomFault(sqlite3*);
  4174   4170   void sqlite3OomClear(sqlite3*);
  4175   4171   int sqlite3ApiExit(sqlite3 *db, int);
  4176   4172   int sqlite3OpenTempDatabase(Parse *);
  4177   4173   
  4178   4174   void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
  4179         -void sqlite3StrAccumAppend(StrAccum*,const char*,int);
  4180         -void sqlite3StrAccumAppendAll(StrAccum*,const char*);
  4181         -void sqlite3AppendChar(StrAccum*,int,char);
  4182   4175   char *sqlite3StrAccumFinish(StrAccum*);
  4183         -void sqlite3StrAccumReset(StrAccum*);
  4184   4176   void sqlite3SelectDestInit(SelectDest*,int,int);
  4185   4177   Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
  4186   4178   
  4187   4179   void sqlite3BackupRestart(sqlite3_backup *);
  4188   4180   void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
  4189   4181   
  4190   4182   #ifndef SQLITE_OMIT_SUBQUERY

Changes to src/treeview.c.

    54     54     va_list ap;
    55     55     int i;
    56     56     StrAccum acc;
    57     57     char zBuf[500];
    58     58     sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
    59     59     if( p ){
    60     60       for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
    61         -      sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
           61  +      sqlite3_str_append(&acc, p->bLine[i] ? "|   " : "    ", 4);
    62     62       }
    63         -    sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
           63  +    sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
    64     64     }
    65     65     if( zFormat!=0 ){
    66     66       va_start(ap, zFormat);
    67         -    sqlite3VXPrintf(&acc, zFormat, ap);
           67  +    sqlite3_str_vappendf(&acc, zFormat, ap);
    68     68       va_end(ap);
    69     69       assert( acc.nChar>0 );
    70         -    sqlite3StrAccumAppend(&acc, "\n", 1);
           70  +    sqlite3_str_append(&acc, "\n", 1);
    71     71     }
    72     72     sqlite3StrAccumFinish(&acc);
    73     73     fprintf(stdout,"%s", zBuf);
    74     74     fflush(stdout);
    75     75   }
    76     76   
    77     77   /*
................................................................................
    97     97     if( pWith->nCte>0 ){
    98     98       pView = sqlite3TreeViewPush(pView, 1);
    99     99       for(i=0; i<pWith->nCte; i++){
   100    100         StrAccum x;
   101    101         char zLine[1000];
   102    102         const struct Cte *pCte = &pWith->a[i];
   103    103         sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
   104         -      sqlite3XPrintf(&x, "%s", pCte->zName);
          104  +      sqlite3_str_appendf(&x, "%s", pCte->zName);
   105    105         if( pCte->pCols && pCte->pCols->nExpr>0 ){
   106    106           char cSep = '(';
   107    107           int j;
   108    108           for(j=0; j<pCte->pCols->nExpr; j++){
   109         -          sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
          109  +          sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
   110    110             cSep = ',';
   111    111           }
   112         -        sqlite3XPrintf(&x, ")");
          112  +        sqlite3_str_appendf(&x, ")");
   113    113         }
   114         -      sqlite3XPrintf(&x, " AS");
          114  +      sqlite3_str_appendf(&x, " AS");
   115    115         sqlite3StrAccumFinish(&x);
   116    116         sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
   117    117         sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
   118    118         sqlite3TreeViewPop(pView);
   119    119       }
   120    120       sqlite3TreeViewPop(pView);
   121    121     }
................................................................................
   172    172         pView = sqlite3TreeViewPush(pView, (n--)>0);
   173    173         sqlite3TreeViewLine(pView, "FROM");
   174    174         for(i=0; i<p->pSrc->nSrc; i++){
   175    175           struct SrcList_item *pItem = &p->pSrc->a[i];
   176    176           StrAccum x;
   177    177           char zLine[100];
   178    178           sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
   179         -        sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
          179  +        sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
   180    180           if( pItem->zDatabase ){
   181         -          sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
          181  +          sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
   182    182           }else if( pItem->zName ){
   183         -          sqlite3XPrintf(&x, " %s", pItem->zName);
          183  +          sqlite3_str_appendf(&x, " %s", pItem->zName);
   184    184           }
   185    185           if( pItem->pTab ){
   186         -          sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
          186  +          sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
   187    187           }
   188    188           if( pItem->zAlias ){
   189         -          sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
          189  +          sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
   190    190           }
   191    191           if( pItem->fg.jointype & JT_LEFT ){
   192         -          sqlite3XPrintf(&x, " LEFT-JOIN");
          192  +          sqlite3_str_appendf(&x, " LEFT-JOIN");
   193    193           }
   194    194           sqlite3StrAccumFinish(&x);
   195    195           sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
   196    196           if( pItem->pSelect ){
   197    197             sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
   198    198           }
   199    199           if( pItem->fg.isTabFunc ){

Changes to src/vdbeaux.c.

  1302   1302   ** Translate the P4.pExpr value for an OP_CursorHint opcode into text
  1303   1303   ** that can be displayed in the P4 column of EXPLAIN output.
  1304   1304   */
  1305   1305   static void displayP4Expr(StrAccum *p, Expr *pExpr){
  1306   1306     const char *zOp = 0;
  1307   1307     switch( pExpr->op ){
  1308   1308       case TK_STRING:
  1309         -      sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
         1309  +      sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
  1310   1310         break;
  1311   1311       case TK_INTEGER:
  1312         -      sqlite3XPrintf(p, "%d", pExpr->u.iValue);
         1312  +      sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
  1313   1313         break;
  1314   1314       case TK_NULL:
  1315         -      sqlite3XPrintf(p, "NULL");
         1315  +      sqlite3_str_appendf(p, "NULL");
  1316   1316         break;
  1317   1317       case TK_REGISTER: {
  1318         -      sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
         1318  +      sqlite3_str_appendf(p, "r[%d]", pExpr->iTable);
  1319   1319         break;
  1320   1320       }
  1321   1321       case TK_COLUMN: {
  1322   1322         if( pExpr->iColumn<0 ){
  1323         -        sqlite3XPrintf(p, "rowid");
         1323  +        sqlite3_str_appendf(p, "rowid");
  1324   1324         }else{
  1325         -        sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
         1325  +        sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn);
  1326   1326         }
  1327   1327         break;
  1328   1328       }
  1329   1329       case TK_LT:      zOp = "LT";      break;
  1330   1330       case TK_LE:      zOp = "LE";      break;
  1331   1331       case TK_GT:      zOp = "GT";      break;
  1332   1332       case TK_GE:      zOp = "GE";      break;
................................................................................
  1350   1350       case TK_UPLUS:   zOp = "PLUS";    break;
  1351   1351       case TK_BITNOT:  zOp = "BITNOT";  break;
  1352   1352       case TK_NOT:     zOp = "NOT";     break;
  1353   1353       case TK_ISNULL:  zOp = "ISNULL";  break;
  1354   1354       case TK_NOTNULL: zOp = "NOTNULL"; break;
  1355   1355   
  1356   1356       default:
  1357         -      sqlite3XPrintf(p, "%s", "expr");
         1357  +      sqlite3_str_appendf(p, "%s", "expr");
  1358   1358         break;
  1359   1359     }
  1360   1360   
  1361   1361     if( zOp ){
  1362         -    sqlite3XPrintf(p, "%s(", zOp);
         1362  +    sqlite3_str_appendf(p, "%s(", zOp);
  1363   1363       displayP4Expr(p, pExpr->pLeft);
  1364   1364       if( pExpr->pRight ){
  1365         -      sqlite3StrAccumAppend(p, ",", 1);
         1365  +      sqlite3_str_append(p, ",", 1);
  1366   1366         displayP4Expr(p, pExpr->pRight);
  1367   1367       }
  1368         -    sqlite3StrAccumAppend(p, ")", 1);
         1368  +    sqlite3_str_append(p, ")", 1);
  1369   1369     }
  1370   1370   }
  1371   1371   #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
  1372   1372   
  1373   1373   
  1374   1374   #if VDBE_DISPLAY_P4
  1375   1375   /*
................................................................................
  1382   1382     assert( nTemp>=20 );
  1383   1383     sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
  1384   1384     switch( pOp->p4type ){
  1385   1385       case P4_KEYINFO: {
  1386   1386         int j;
  1387   1387         KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  1388   1388         assert( pKeyInfo->aSortOrder!=0 );
  1389         -      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField);
         1389  +      sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField);
  1390   1390         for(j=0; j<pKeyInfo->nKeyField; j++){
  1391   1391           CollSeq *pColl = pKeyInfo->aColl[j];
  1392   1392           const char *zColl = pColl ? pColl->zName : "";
  1393   1393           if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
  1394         -        sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
         1394  +        sqlite3_str_appendf(&x, ",%s%s", 
         1395  +               pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
  1395   1396         }
  1396         -      sqlite3StrAccumAppend(&x, ")", 1);
         1397  +      sqlite3_str_append(&x, ")", 1);
  1397   1398         break;
  1398   1399       }
  1399   1400   #ifdef SQLITE_ENABLE_CURSOR_HINTS
  1400   1401       case P4_EXPR: {
  1401   1402         displayP4Expr(&x, pOp->p4.pExpr);
  1402   1403         break;
  1403   1404       }
  1404   1405   #endif
  1405   1406       case P4_COLLSEQ: {
  1406   1407         CollSeq *pColl = pOp->p4.pColl;
  1407         -      sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
         1408  +      sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
  1408   1409         break;
  1409   1410       }
  1410   1411       case P4_FUNCDEF: {
  1411   1412         FuncDef *pDef = pOp->p4.pFunc;
  1412         -      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
         1413  +      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
  1413   1414         break;
  1414   1415       }
  1415   1416   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
  1416   1417       case P4_FUNCCTX: {
  1417   1418         FuncDef *pDef = pOp->p4.pCtx->pFunc;
  1418         -      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
         1419  +      sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
  1419   1420         break;
  1420   1421       }
  1421   1422   #endif
  1422   1423       case P4_INT64: {
  1423         -      sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
         1424  +      sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
  1424   1425         break;
  1425   1426       }
  1426   1427       case P4_INT32: {
  1427         -      sqlite3XPrintf(&x, "%d", pOp->p4.i);
         1428  +      sqlite3_str_appendf(&x, "%d", pOp->p4.i);
  1428   1429         break;
  1429   1430       }
  1430   1431       case P4_REAL: {
  1431         -      sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
         1432  +      sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal);
  1432   1433         break;
  1433   1434       }
  1434   1435       case P4_MEM: {
  1435   1436         Mem *pMem = pOp->p4.pMem;
  1436   1437         if( pMem->flags & MEM_Str ){
  1437   1438           zP4 = pMem->z;
  1438   1439         }else if( pMem->flags & MEM_Int ){
  1439         -        sqlite3XPrintf(&x, "%lld", pMem->u.i);
         1440  +        sqlite3_str_appendf(&x, "%lld", pMem->u.i);
  1440   1441         }else if( pMem->flags & MEM_Real ){
  1441         -        sqlite3XPrintf(&x, "%.16g", pMem->u.r);
         1442  +        sqlite3_str_appendf(&x, "%.16g", pMem->u.r);
  1442   1443         }else if( pMem->flags & MEM_Null ){
  1443   1444           zP4 = "NULL";
  1444   1445         }else{
  1445   1446           assert( pMem->flags & MEM_Blob );
  1446   1447           zP4 = "(blob)";
  1447   1448         }
  1448   1449         break;
  1449   1450       }
  1450   1451   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1451   1452       case P4_VTAB: {
  1452   1453         sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
  1453         -      sqlite3XPrintf(&x, "vtab:%p", pVtab);
         1454  +      sqlite3_str_appendf(&x, "vtab:%p", pVtab);
  1454   1455         break;
  1455   1456       }
  1456   1457   #endif
  1457   1458       case P4_INTARRAY: {
  1458   1459         int i;
  1459   1460         int *ai = pOp->p4.ai;
  1460   1461         int n = ai[0];   /* The first element of an INTARRAY is always the
  1461   1462                          ** count of the number of elements to follow */
  1462   1463         for(i=1; i<=n; i++){
  1463         -        sqlite3XPrintf(&x, ",%d", ai[i]);
         1464  +        sqlite3_str_appendf(&x, ",%d", ai[i]);
  1464   1465         }
  1465   1466         zTemp[0] = '[';
  1466         -      sqlite3StrAccumAppend(&x, "]", 1);
         1467  +      sqlite3_str_append(&x, "]", 1);
  1467   1468         break;
  1468   1469       }
  1469   1470       case P4_SUBPROGRAM: {
  1470         -      sqlite3XPrintf(&x, "program");
         1471  +      sqlite3_str_appendf(&x, "program");
  1471   1472         break;
  1472   1473       }
  1473   1474       case P4_DYNBLOB:
  1474   1475       case P4_ADVANCE: {
  1475   1476         zTemp[0] = 0;
  1476   1477         break;
  1477   1478       }
  1478   1479       case P4_TABLE: {
  1479         -      sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
         1480  +      sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
  1480   1481         break;
  1481   1482       }
  1482   1483       default: {
  1483   1484         zP4 = pOp->p4.z;
  1484   1485         if( zP4==0 ){
  1485   1486           zP4 = zTemp;
  1486   1487           zTemp[0] = 0;

Changes to src/vdbetrace.c.

    89     89     db = p->db;
    90     90     sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), 
    91     91                         db->aLimit[SQLITE_LIMIT_LENGTH]);
    92     92     if( db->nVdbeExec>1 ){
    93     93       while( *zRawSql ){
    94     94         const char *zStart = zRawSql;
    95     95         while( *(zRawSql++)!='\n' && *zRawSql );
    96         -      sqlite3StrAccumAppend(&out, "-- ", 3);
           96  +      sqlite3_str_append(&out, "-- ", 3);
    97     97         assert( (zRawSql - zStart) > 0 );
    98         -      sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
           98  +      sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
    99     99       }
   100    100     }else if( p->nVar==0 ){
   101         -    sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
          101  +    sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql));
   102    102     }else{
   103    103       while( zRawSql[0] ){
   104    104         n = findNextHostParameter(zRawSql, &nToken);
   105    105         assert( n>0 );
   106         -      sqlite3StrAccumAppend(&out, zRawSql, n);
          106  +      sqlite3_str_append(&out, zRawSql, n);
   107    107         zRawSql += n;
   108    108         assert( zRawSql[0] || nToken==0 );
   109    109         if( nToken==0 ) break;
   110    110         if( zRawSql[0]=='?' ){
   111    111           if( nToken>1 ){
   112    112             assert( sqlite3Isdigit(zRawSql[1]) );
   113    113             sqlite3GetInt32(&zRawSql[1], &idx);
................................................................................
   125    125           assert( idx>0 );
   126    126         }
   127    127         zRawSql += nToken;
   128    128         nextIndex = idx + 1;
   129    129         assert( idx>0 && idx<=p->nVar );
   130    130         pVar = &p->aVar[idx-1];
   131    131         if( pVar->flags & MEM_Null ){
   132         -        sqlite3StrAccumAppend(&out, "NULL", 4);
          132  +        sqlite3_str_append(&out, "NULL", 4);
   133    133         }else if( pVar->flags & MEM_Int ){
   134         -        sqlite3XPrintf(&out, "%lld", pVar->u.i);
          134  +        sqlite3_str_appendf(&out, "%lld", pVar->u.i);
   135    135         }else if( pVar->flags & MEM_Real ){
   136         -        sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
          136  +        sqlite3_str_appendf(&out, "%!.15g", pVar->u.r);
   137    137         }else if( pVar->flags & MEM_Str ){
   138    138           int nOut;  /* Number of bytes of the string text to include in output */
   139    139   #ifndef SQLITE_OMIT_UTF16
   140    140           u8 enc = ENC(db);
   141    141           if( enc!=SQLITE_UTF8 ){
   142    142             memset(&utf8, 0, sizeof(utf8));
   143    143             utf8.db = db;
   144    144             sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
   145    145             if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
   146         -            out.accError = STRACCUM_NOMEM;
          146  +            out.accError = SQLITE_NOMEM;
   147    147               out.nAlloc = 0;
   148    148             }
   149    149             pVar = &utf8;
   150    150           }
   151    151   #endif
   152    152           nOut = pVar->n;
   153    153   #ifdef SQLITE_TRACE_SIZE_LIMIT
   154    154           if( nOut>SQLITE_TRACE_SIZE_LIMIT ){
   155    155             nOut = SQLITE_TRACE_SIZE_LIMIT;
   156    156             while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
   157    157           }
   158    158   #endif    
   159         -        sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
          159  +        sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z);
   160    160   #ifdef SQLITE_TRACE_SIZE_LIMIT
   161    161           if( nOut<pVar->n ){
   162         -          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
          162  +          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
   163    163           }
   164    164   #endif
   165    165   #ifndef SQLITE_OMIT_UTF16
   166    166           if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
   167    167   #endif
   168    168         }else if( pVar->flags & MEM_Zero ){
   169         -        sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
          169  +        sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero);
   170    170         }else{
   171    171           int nOut;  /* Number of bytes of the blob to include in output */
   172    172           assert( pVar->flags & MEM_Blob );
   173         -        sqlite3StrAccumAppend(&out, "x'", 2);
          173  +        sqlite3_str_append(&out, "x'", 2);
   174    174           nOut = pVar->n;
   175    175   #ifdef SQLITE_TRACE_SIZE_LIMIT
   176    176           if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
   177    177   #endif
   178    178           for(i=0; i<nOut; i++){
   179         -          sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
          179  +          sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff);
   180    180           }
   181         -        sqlite3StrAccumAppend(&out, "'", 1);
          181  +        sqlite3_str_append(&out, "'", 1);
   182    182   #ifdef SQLITE_TRACE_SIZE_LIMIT
   183    183           if( nOut<pVar->n ){
   184         -          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
          184  +          sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut);
   185    185           }
   186    186   #endif
   187    187         }
   188    188       }
   189    189     }
   190         -  if( out.accError ) sqlite3StrAccumReset(&out);
          190  +  if( out.accError ) sqlite3_str_reset(&out);
   191    191     return sqlite3StrAccumFinish(&out);
   192    192   }
   193    193   
   194    194   #endif /* #ifndef SQLITE_OMIT_TRACE */

Changes to src/wherecode.c.

    47     47     int iTerm,                  /* Zero-based index of first term. */
    48     48     int bAnd,                   /* Non-zero to append " AND " */
    49     49     const char *zOp             /* Name of the operator */
    50     50   ){
    51     51     int i;
    52     52   
    53     53     assert( nTerm>=1 );
    54         -  if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
           54  +  if( bAnd ) sqlite3_str_append(pStr, " AND ", 5);
    55     55   
    56         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
           56  +  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
    57     57     for(i=0; i<nTerm; i++){
    58         -    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
    59         -    sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
           58  +    if( i ) sqlite3_str_append(pStr, ",", 1);
           59  +    sqlite3_str_appendall(pStr, explainIndexColumnName(pIdx, iTerm+i));
    60     60     }
    61         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
           61  +  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
    62     62   
    63         -  sqlite3StrAccumAppend(pStr, zOp, 1);
           63  +  sqlite3_str_append(pStr, zOp, 1);
    64     64   
    65         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
           65  +  if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1);
    66     66     for(i=0; i<nTerm; i++){
    67         -    if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
    68         -    sqlite3StrAccumAppend(pStr, "?", 1);
           67  +    if( i ) sqlite3_str_append(pStr, ",", 1);
           68  +    sqlite3_str_append(pStr, "?", 1);
    69     69     }
    70         -  if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
           70  +  if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1);
    71     71   }
    72     72   
    73     73   /*
    74     74   ** Argument pLevel describes a strategy for scanning table pTab. This 
    75     75   ** function appends text to pStr that describes the subset of table
    76     76   ** rows scanned by the strategy in the form of an SQL expression.
    77     77   **
................................................................................
    87     87   static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
    88     88     Index *pIndex = pLoop->u.btree.pIndex;
    89     89     u16 nEq = pLoop->u.btree.nEq;
    90     90     u16 nSkip = pLoop->nSkip;
    91     91     int i, j;
    92     92   
    93     93     if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
    94         -  sqlite3StrAccumAppend(pStr, " (", 2);
           94  +  sqlite3_str_append(pStr, " (", 2);
    95     95     for(i=0; i<nEq; i++){
    96     96       const char *z = explainIndexColumnName(pIndex, i);
    97         -    if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
    98         -    sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
           97  +    if( i ) sqlite3_str_append(pStr, " AND ", 5);
           98  +    sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
    99     99     }
   100    100   
   101    101     j = i;
   102    102     if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
   103    103       explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">");
   104    104       i = 1;
   105    105     }
   106    106     if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
   107    107       explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
   108    108     }
   109         -  sqlite3StrAccumAppend(pStr, ")", 1);
          109  +  sqlite3_str_append(pStr, ")", 1);
   110    110   }
   111    111   
   112    112   /*
   113    113   ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
   114    114   ** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
   115    115   ** defined at compile-time. If it is not a no-op, a single OP_Explain opcode 
   116    116   ** is added to the output to describe the table scan strategy in pLevel.
................................................................................
   144    144       if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_OR_SUBCLAUSE) ) return 0;
   145    145   
   146    146       isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
   147    147               || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
   148    148               || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
   149    149   
   150    150       sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
   151         -    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
          151  +    sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN");
   152    152       if( pItem->pSelect ){
   153         -      sqlite3XPrintf(&str, " SUBQUERY 0x%p", pItem->pSelect);
          153  +      sqlite3_str_appendf(&str, " SUBQUERY 0x%p", pItem->pSelect);
   154    154       }else{
   155         -      sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
          155  +      sqlite3_str_appendf(&str, " TABLE %s", pItem->zName);
   156    156       }
   157    157   
   158    158       if( pItem->zAlias ){
   159         -      sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
          159  +      sqlite3_str_appendf(&str, " AS %s", pItem->zAlias);
   160    160       }
   161    161       if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
   162    162         const char *zFmt = 0;
   163    163         Index *pIdx;
   164    164   
   165    165         assert( pLoop->u.btree.pIndex!=0 );
   166    166         pIdx = pLoop->u.btree.pIndex;
................................................................................
   175    175           zFmt = "AUTOMATIC COVERING INDEX";
   176    176         }else if( flags & WHERE_IDX_ONLY ){
   177    177           zFmt = "COVERING INDEX %s";
   178    178         }else{
   179    179           zFmt = "INDEX %s";
   180    180         }
   181    181         if( zFmt ){
   182         -        sqlite3StrAccumAppend(&str, " USING ", 7);
   183         -        sqlite3XPrintf(&str, zFmt, pIdx->zName);
          182  +        sqlite3_str_append(&str, " USING ", 7);
          183  +        sqlite3_str_appendf(&str, zFmt, pIdx->zName);
   184    184           explainIndexRange(&str, pLoop);
   185    185         }
   186    186       }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
   187    187         const char *zRangeOp;
   188    188         if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
   189    189           zRangeOp = "=";
   190    190         }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
................................................................................
   191    191           zRangeOp = ">? AND rowid<";
   192    192         }else if( flags&WHERE_BTM_LIMIT ){
   193    193           zRangeOp = ">";
   194    194         }else{
   195    195           assert( flags&WHERE_TOP_LIMIT);
   196    196           zRangeOp = "<";
   197    197         }
   198         -      sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
          198  +      sqlite3_str_appendf(&str, 
          199  +          " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
   199    200       }
   200    201   #ifndef SQLITE_OMIT_VIRTUALTABLE
   201    202       else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
   202         -      sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
          203  +      sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
   203    204                     pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
   204    205       }
   205    206   #endif
   206    207   #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
   207    208       if( pLoop->nOut>=10 ){
   208         -      sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
          209  +      sqlite3_str_appendf(&str, " (~%llu rows)",
          210  +             sqlite3LogEstToInt(pLoop->nOut));
   209    211       }else{
   210         -      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
          212  +      sqlite3_str_append(&str, " (~1 row)", 9);
   211    213       }
   212    214   #endif
   213    215       zMsg = sqlite3StrAccumFinish(&str);
   214    216       ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
   215    217                               pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
   216    218     }
   217    219     return ret;