/ Check-in [9dcd8569]
Login

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

Overview
Comment:Fix the VList object so that it actually works.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | VList
Files: files | file ages | folders
SHA1: 9dcd85698af46fd5ba34004ca690d368c4ae3078
User & Date: drh 2016-12-23 13:30:53
Context
2016-12-23
13:52
Add check to prevent a VList from growing after pointers to labels have been taken. Closed-Leaf check-in: aa23d7ea user: drh tags: VList
13:30
Fix the VList object so that it actually works. check-in: 9dcd8569 user: drh tags: VList
03:59
Use the VList object to replace Parse.azVar for tracking the mapping between SQL parameter names and parameter numbers. There is a performance improvement, though there are still a few hiccups in the current code. check-in: 68ecafa1 user: drh tags: VList
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

   941    941   ** as the previous instance of the same wildcard.  Or if this is the first
   942    942   ** instance of the wildcard, the next sequential variable number is
   943    943   ** assigned.
   944    944   */
   945    945   void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
   946    946     sqlite3 *db = pParse->db;
   947    947     const char *z;
          948  +  ynVar x;
   948    949   
   949    950     if( pExpr==0 ) return;
   950    951     assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
   951    952     z = pExpr->u.zToken;
   952    953     assert( z!=0 );
   953    954     assert( z[0]!=0 );
   954    955     assert( n==sqlite3Strlen30(z) );
   955    956     if( z[1]==0 ){
   956    957       /* Wildcard of the form "?".  Assign the next variable number */
   957    958       assert( z[0]=='?' );
   958         -    pExpr->iColumn = (ynVar)(++pParse->nVar);
          959  +    x = (ynVar)(++pParse->nVar);
   959    960     }else{
   960         -    ynVar x;
          961  +    int doAdd = 0;
   961    962       if( z[0]=='?' ){
   962    963         /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
   963    964         ** use it as the variable number */
   964    965         i64 i;
   965    966         int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
   966    967         x = (ynVar)i;
   967    968         testcase( i==0 );
................................................................................
   969    970         testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
   970    971         testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
   971    972         if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
   972    973           sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
   973    974               db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
   974    975           return;
   975    976         }
   976         -      if( i>pParse->nVar ){
   977         -        pParse->nVar = (int)i;
          977  +      if( x>pParse->nVar ){
          978  +        pParse->nVar = (int)x;
          979  +        doAdd = 1;
          980  +      }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){
          981  +        doAdd = 1;
   978    982         }
   979    983       }else{
   980    984         /* Wildcards like ":aaa", "$aaa" or "@aaa".  Reuse the same variable
   981    985         ** number as the prior appearance of the same name, or if the name
   982    986         ** has never appeared before, reuse the same variable number
   983    987         */
   984    988         x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n);
   985    989         if( x==0 ){
   986    990           x = (ynVar)(++pParse->nVar);
   987         -        pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
          991  +        doAdd = 1;
   988    992         }
   989    993       }
   990         -    pExpr->iColumn = x;
   991         -  } 
   992         -  if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
          994  +    if( doAdd ){
          995  +      pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
          996  +    }
          997  +  }
          998  +  pExpr->iColumn = x;
          999  +  if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
   993   1000       sqlite3ErrorMsg(pParse, "too many SQL variables");
   994   1001     }
   995   1002   }
   996   1003   
   997   1004   /*
   998   1005   ** Recursively delete an expression tree.
   999   1006   */
................................................................................
  3410   3417       case TK_VARIABLE: {
  3411   3418         assert( !ExprHasProperty(pExpr, EP_IntValue) );
  3412   3419         assert( pExpr->u.zToken!=0 );
  3413   3420         assert( pExpr->u.zToken[0]!=0 );
  3414   3421         sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
  3415   3422         if( pExpr->u.zToken[1]!=0 ){
  3416   3423           const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
  3417         -        if( z ){
  3418         -          assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
  3419         -          sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
  3420         -        }
         3424  +        assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
         3425  +        sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
  3421   3426         }
  3422   3427         return target;
  3423   3428       }
  3424   3429       case TK_REGISTER: {
  3425   3430         return pExpr->iTable;
  3426   3431       }
  3427   3432   #ifndef SQLITE_OMIT_CAST

Changes to src/vdbeaux.c.

  2966   2966   **
  2967   2967   ** The difference between this function and sqlite3VdbeDelete() is that
  2968   2968   ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
  2969   2969   ** the database connection and frees the object itself.
  2970   2970   */
  2971   2971   void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
  2972   2972     SubProgram *pSub, *pNext;
  2973         -  int i;
  2974   2973     assert( p->db==0 || p->db==db );
  2975   2974     releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  2976   2975     for(pSub=p->pProgram; pSub; pSub=pNext){
  2977   2976       pNext = pSub->pNext;
  2978   2977       vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
  2979   2978       sqlite3DbFree(db, pSub);
  2980   2979     }
................................................................................
  2983   2982       sqlite3DbFree(db, p->pVList);
  2984   2983       sqlite3DbFree(db, p->pFree);
  2985   2984     }
  2986   2985     vdbeFreeOpArray(db, p->aOp, p->nOp);
  2987   2986     sqlite3DbFree(db, p->aColName);
  2988   2987     sqlite3DbFree(db, p->zSql);
  2989   2988   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  2990         -  for(i=0; i<p->nScan; i++){
  2991         -    sqlite3DbFree(db, p->aScan[i].zName);
         2989  +  {
         2990  +    int i;
         2991  +    for(i=0; i<p->nScan; i++){
         2992  +      sqlite3DbFree(db, p->aScan[i].zName);
         2993  +    }
         2994  +    sqlite3DbFree(db, p->aScan);
  2992   2995     }
  2993         -  sqlite3DbFree(db, p->aScan);
  2994   2996   #endif
  2995   2997   }
  2996   2998   
  2997   2999   /*
  2998   3000   ** Delete an entire VDBE.
  2999   3001   */
  3000   3002   void sqlite3VdbeDelete(Vdbe *p){