/ Check-in [5708bc24]
Login

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

Overview
Comment:Faster and smaller implementation of sqlite3_value_type().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5708bc24b8cab623b833121183042b43e5a7021b
User & Date: drh 2014-02-10 03:21:57
Context
2014-02-10
12:59
Faster implementation for sqlite3MulInt64(). check-in: 010c48f6 user: drh tags: trunk
03:21
Faster and smaller implementation of sqlite3_value_type(). check-in: 5708bc24 user: drh tags: trunk
2014-02-09
23:59
Add a compound-query test to the speedtest1 test program. check-in: 53299575 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test5.c.

    72     72     }
    73     73   
    74     74     if( Tcl_GetIntFromObj(interp, objv[1], &repeat_count) ) return TCL_ERROR;
    75     75     if( Tcl_GetIntFromObj(interp, objv[2], &do_calls) ) return TCL_ERROR;
    76     76   
    77     77     val.flags = MEM_Str|MEM_Term|MEM_Static;
    78     78     val.z = "hello world";
    79         -  val.type = SQLITE_TEXT;
           79  +  val.memType = MEM_Str;
    80     80     val.enc = SQLITE_UTF8;
    81     81   
    82     82     for(i=0; i<repeat_count; i++){
    83     83       if( do_calls ){
    84     84         sqlite3_value_text(&val);
    85     85       }
    86     86     }

Changes to src/vdbe.c.

   129    129   #define Deephemeralize(P) \
   130    130      if( ((P)->flags&MEM_Ephem)!=0 \
   131    131          && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
   132    132   
   133    133   /* Return true if the cursor was opened using the OP_OpenSorter opcode. */
   134    134   #define isSorter(x) ((x)->pSorter!=0)
   135    135   
   136         -/*
   137         -** Argument pMem points at a register that will be passed to a
   138         -** user-defined function or returned to the user as the result of a query.
   139         -** This routine sets the pMem->type variable used by the sqlite3_value_*() 
   140         -** routines.
   141         -*/
   142         -void sqlite3VdbeMemStoreType(Mem *pMem){
   143         -  int flags = pMem->flags;
   144         -  if( flags & MEM_Null ){
   145         -    pMem->type = SQLITE_NULL;
   146         -  }
   147         -  else if( flags & MEM_Int ){
   148         -    pMem->type = SQLITE_INTEGER;
   149         -  }
   150         -  else if( flags & MEM_Real ){
   151         -    pMem->type = SQLITE_FLOAT;
   152         -  }
   153         -  else if( flags & MEM_Str ){
   154         -    pMem->type = SQLITE_TEXT;
   155         -  }else{
   156         -    pMem->type = SQLITE_BLOB;
   157         -  }
   158         -}
   159         -
   160    136   /*
   161    137   ** Allocate VdbeCursor number iCur.  Return a pointer to it.  Return NULL
   162    138   ** if we run out of memory.
   163    139   */
   164    140   static VdbeCursor *allocateCursor(
   165    141     Vdbe *p,              /* The virtual machine */
   166    142     int iCur,             /* Index of the new VdbeCursor */
................................................................................
   281    257   /*
   282    258   ** Try to convert the type of a function argument or a result column
   283    259   ** into a numeric representation.  Use either INTEGER or REAL whichever
   284    260   ** is appropriate.  But only do the conversion if it is possible without
   285    261   ** loss of information and return the revised type of the argument.
   286    262   */
   287    263   int sqlite3_value_numeric_type(sqlite3_value *pVal){
   288         -  Mem *pMem = (Mem*)pVal;
   289         -  if( pMem->type==SQLITE_TEXT ){
          264  +  int eType = sqlite3_value_type(pVal);
          265  +  if( eType==SQLITE_TEXT ){
          266  +    Mem *pMem = (Mem*)pVal;
   290    267       applyNumericAffinity(pMem);
   291    268       sqlite3VdbeMemStoreType(pMem);
          269  +    eType = sqlite3_value_type(pVal);
   292    270     }
   293         -  return pMem->type;
          271  +  return eType;
   294    272   }
   295    273   
   296    274   /*
   297    275   ** Exported version of applyAffinity(). This one works on sqlite3_value*, 
   298    276   ** not the internal Mem* type.
   299    277   */
   300    278   void sqlite3ValueApplyAffinity(

Changes to src/vdbeInt.h.

   164    164       int nZero;          /* Used when bit MEM_Zero is set in flags */
   165    165       FuncDef *pDef;      /* Used only when flags==MEM_Agg */
   166    166       RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
   167    167       VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
   168    168     } u;
   169    169     int n;              /* Number of characters in string value, excluding '\0' */
   170    170     u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   171         -  u8  type;           /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
          171  +  u8  memType;        /* Lower 5 bits of flags */
   172    172     u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
   173    173   #ifdef SQLITE_DEBUG
   174    174     Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
   175    175     void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
   176    176   #endif
   177    177     void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
   178    178     char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
................................................................................
   430    430     if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X);
   431    431   int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
   432    432   const char *sqlite3OpcodeName(int);
   433    433   int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
   434    434   int sqlite3VdbeCloseStatement(Vdbe *, int);
   435    435   void sqlite3VdbeFrameDelete(VdbeFrame*);
   436    436   int sqlite3VdbeFrameRestore(VdbeFrame *);
   437         -void sqlite3VdbeMemStoreType(Mem *pMem);
          437  +#define sqlite3VdbeMemStoreType(X)  (X)->memType = (u8)((X)->flags&0x1f)
          438  +/* void sqlite3VdbeMemStoreType(Mem *pMem); */
   438    439   int sqlite3VdbeTransferError(Vdbe *p);
   439    440   
   440    441   int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
   441    442   void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
   442    443   int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
   443    444   int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
   444    445   int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);

Changes to src/vdbeapi.c.

   168    168     return sqlite3ValueText(pVal, SQLITE_UTF16BE);
   169    169   }
   170    170   const void *sqlite3_value_text16le(sqlite3_value *pVal){
   171    171     return sqlite3ValueText(pVal, SQLITE_UTF16LE);
   172    172   }
   173    173   #endif /* SQLITE_OMIT_UTF16 */
   174    174   int sqlite3_value_type(sqlite3_value* pVal){
   175         -  return pVal->type;
          175  +  static const u8 aType[] = {
          176  +     SQLITE_BLOB,     /* 0x00 */
          177  +     SQLITE_NULL,     /* 0x01 */
          178  +     SQLITE_TEXT,     /* 0x02 */
          179  +     SQLITE_NULL,     /* 0x03 */
          180  +     SQLITE_INTEGER,  /* 0x04 */
          181  +     SQLITE_NULL,     /* 0x05 */
          182  +     SQLITE_INTEGER,  /* 0x06 */
          183  +     SQLITE_NULL,     /* 0x07 */
          184  +     SQLITE_FLOAT,    /* 0x08 */
          185  +     SQLITE_NULL,     /* 0x09 */
          186  +     SQLITE_FLOAT,    /* 0x0a */
          187  +     SQLITE_NULL,     /* 0x0b */
          188  +     SQLITE_INTEGER,  /* 0x0c */
          189  +     SQLITE_NULL,     /* 0x0d */
          190  +     SQLITE_INTEGER,  /* 0x0e */
          191  +     SQLITE_NULL,     /* 0x0f */
          192  +     SQLITE_BLOB,     /* 0x10 */
          193  +     SQLITE_NULL,     /* 0x11 */
          194  +     SQLITE_TEXT,     /* 0x12 */
          195  +     SQLITE_NULL,     /* 0x13 */
          196  +     SQLITE_INTEGER,  /* 0x14 */
          197  +     SQLITE_NULL,     /* 0x15 */
          198  +     SQLITE_INTEGER,  /* 0x16 */
          199  +     SQLITE_NULL,     /* 0x17 */
          200  +     SQLITE_FLOAT,    /* 0x18 */
          201  +     SQLITE_NULL,     /* 0x19 */
          202  +     SQLITE_FLOAT,    /* 0x1a */
          203  +     SQLITE_NULL,     /* 0x1b */
          204  +     SQLITE_INTEGER,  /* 0x1c */
          205  +     SQLITE_NULL,     /* 0x1d */
          206  +     SQLITE_INTEGER,  /* 0x1e */
          207  +     SQLITE_NULL,     /* 0x1f */
          208  +  };
          209  +  return aType[pVal->memType&0x1f];
   176    210   }
   177    211   
   178    212   /**************************** sqlite3_result_  *******************************
   179    213   ** The following routines are used by user-defined functions to specify
   180    214   ** the function result.
   181    215   **
   182    216   ** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the
................................................................................
  1127   1161     void (*xDel)(void*)
  1128   1162   ){
  1129   1163     return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
  1130   1164   }
  1131   1165   #endif /* SQLITE_OMIT_UTF16 */
  1132   1166   int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
  1133   1167     int rc;
  1134         -  switch( pValue->type ){
         1168  +  switch( sqlite3_value_type((sqlite3_value*)pValue) ){
  1135   1169       case SQLITE_INTEGER: {
  1136   1170         rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
  1137   1171         break;
  1138   1172       }
  1139   1173       case SQLITE_FLOAT: {
  1140   1174         rc = sqlite3_bind_double(pStmt, i, pValue->r);
  1141   1175         break;

Changes to src/vdbeaux.c.

  1341   1341         for(j=0; i>=apSub[j]->nOp; j++){
  1342   1342           i -= apSub[j]->nOp;
  1343   1343         }
  1344   1344         pOp = &apSub[j]->aOp[i];
  1345   1345       }
  1346   1346       if( p->explain==1 ){
  1347   1347         pMem->flags = MEM_Int;
  1348         -      pMem->type = SQLITE_INTEGER;
         1348  +      pMem->memType = MEM_Int;
  1349   1349         pMem->u.i = i;                                /* Program counter */
  1350   1350         pMem++;
  1351   1351     
  1352   1352         pMem->flags = MEM_Static|MEM_Str|MEM_Term;
  1353   1353         pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
  1354   1354         assert( pMem->z!=0 );
  1355   1355         pMem->n = sqlite3Strlen30(pMem->z);
  1356         -      pMem->type = SQLITE_TEXT;
         1356  +      pMem->memType = MEM_Str;
  1357   1357         pMem->enc = SQLITE_UTF8;
  1358   1358         pMem++;
  1359   1359   
  1360   1360         /* When an OP_Program opcode is encounter (the only opcode that has
  1361   1361         ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
  1362   1362         ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
  1363   1363         ** has not already been seen.
................................................................................
  1375   1375             pSub->n = nSub*sizeof(SubProgram*);
  1376   1376           }
  1377   1377         }
  1378   1378       }
  1379   1379   
  1380   1380       pMem->flags = MEM_Int;
  1381   1381       pMem->u.i = pOp->p1;                          /* P1 */
  1382         -    pMem->type = SQLITE_INTEGER;
         1382  +    pMem->memType = MEM_Int;
  1383   1383       pMem++;
  1384   1384   
  1385   1385       pMem->flags = MEM_Int;
  1386   1386       pMem->u.i = pOp->p2;                          /* P2 */
  1387         -    pMem->type = SQLITE_INTEGER;
         1387  +    pMem->memType = MEM_Int;
  1388   1388       pMem++;
  1389   1389   
  1390   1390       pMem->flags = MEM_Int;
  1391   1391       pMem->u.i = pOp->p3;                          /* P3 */
  1392         -    pMem->type = SQLITE_INTEGER;
         1392  +    pMem->memType = MEM_Int;
  1393   1393       pMem++;
  1394   1394   
  1395   1395       if( sqlite3VdbeMemGrow(pMem, 32, 0) ){            /* P4 */
  1396   1396         assert( p->db->mallocFailed );
  1397   1397         return SQLITE_ERROR;
  1398   1398       }
  1399   1399       pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
................................................................................
  1401   1401       if( zP4!=pMem->z ){
  1402   1402         sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
  1403   1403       }else{
  1404   1404         assert( pMem->z!=0 );
  1405   1405         pMem->n = sqlite3Strlen30(pMem->z);
  1406   1406         pMem->enc = SQLITE_UTF8;
  1407   1407       }
  1408         -    pMem->type = SQLITE_TEXT;
         1408  +    pMem->memType = MEM_Str;
  1409   1409       pMem++;
  1410   1410   
  1411   1411       if( p->explain==1 ){
  1412   1412         if( sqlite3VdbeMemGrow(pMem, 4, 0) ){
  1413   1413           assert( p->db->mallocFailed );
  1414   1414           return SQLITE_ERROR;
  1415   1415         }
  1416   1416         pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
  1417   1417         pMem->n = 2;
  1418   1418         sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5);   /* P5 */
  1419         -      pMem->type = SQLITE_TEXT;
         1419  +      pMem->memType = MEM_Str;
  1420   1420         pMem->enc = SQLITE_UTF8;
  1421   1421         pMem++;
  1422   1422     
  1423   1423   #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  1424   1424         if( sqlite3VdbeMemGrow(pMem, 500, 0) ){
  1425   1425           assert( p->db->mallocFailed );
  1426   1426           return SQLITE_ERROR;
  1427   1427         }
  1428   1428         pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
  1429   1429         pMem->n = displayComment(pOp, zP4, pMem->z, 500);
  1430         -      pMem->type = SQLITE_TEXT;
         1430  +      pMem->memType = MEM_Str;
  1431   1431         pMem->enc = SQLITE_UTF8;
  1432   1432   #else
  1433   1433         pMem->flags = MEM_Null;                       /* Comment */
  1434         -      pMem->type = SQLITE_NULL;
         1434  +      pMem->memType = MEM_Null;
  1435   1435   #endif
  1436   1436       }
  1437   1437   
  1438   1438       p->nResColumn = 8 - 4*(p->explain-1);
  1439   1439       p->pResultSet = &p->aMem[1];
  1440   1440       p->rc = SQLITE_OK;
  1441   1441       rc = SQLITE_ROW;

Changes to src/vdbemem.c.

   285    285       sqlite3VdbeMemSetNull(p);
   286    286     }
   287    287   }
   288    288   
   289    289   /*
   290    290   ** Release any memory held by the Mem. This may leave the Mem in an
   291    291   ** inconsistent state, for example with (Mem.z==0) and
   292         -** (Mem.type==SQLITE_TEXT).
          292  +** (Mem.memType==MEM_Str).
   293    293   */
   294    294   void sqlite3VdbeMemRelease(Mem *p){
   295    295     VdbeMemRelease(p);
   296    296     if( p->zMalloc ){
   297    297       sqlite3DbFree(p->db, p->zMalloc);
   298    298       p->zMalloc = 0;
   299    299     }
................................................................................
   476    476       pFrame->pParent = pFrame->v->pDelFrame;
   477    477       pFrame->v->pDelFrame = pFrame;
   478    478     }
   479    479     if( pMem->flags & MEM_RowSet ){
   480    480       sqlite3RowSetClear(pMem->u.pRowSet);
   481    481     }
   482    482     MemSetTypeFlag(pMem, MEM_Null);
   483         -  pMem->type = SQLITE_NULL;
          483  +  pMem->memType = MEM_Null;
   484    484   }
   485    485   void sqlite3ValueSetNull(sqlite3_value *p){
   486    486     sqlite3VdbeMemSetNull((Mem*)p); 
   487    487   }
   488    488   
   489    489   /*
   490    490   ** Delete any previous value and set the value to be a BLOB of length
   491    491   ** n containing all zeros.
   492    492   */
   493    493   void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
   494    494     sqlite3VdbeMemRelease(pMem);
   495    495     pMem->flags = MEM_Blob|MEM_Zero;
   496         -  pMem->type = SQLITE_BLOB;
          496  +  pMem->memType = MEM_Blob;
   497    497     pMem->n = 0;
   498    498     if( n<0 ) n = 0;
   499    499     pMem->u.nZero = n;
   500    500     pMem->enc = SQLITE_UTF8;
   501    501   
   502    502   #ifdef SQLITE_OMIT_INCRBLOB
   503    503     sqlite3VdbeMemGrow(pMem, n, 0);
................................................................................
   512    512   ** Delete any previous value and set the value stored in *pMem to val,
   513    513   ** manifest type INTEGER.
   514    514   */
   515    515   void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
   516    516     sqlite3VdbeMemRelease(pMem);
   517    517     pMem->u.i = val;
   518    518     pMem->flags = MEM_Int;
   519         -  pMem->type = SQLITE_INTEGER;
          519  +  pMem->memType = MEM_Int;
   520    520   }
   521    521   
   522    522   #ifndef SQLITE_OMIT_FLOATING_POINT
   523    523   /*
   524    524   ** Delete any previous value and set the value stored in *pMem to val,
   525    525   ** manifest type REAL.
   526    526   */
................................................................................
   527    527   void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
   528    528     if( sqlite3IsNaN(val) ){
   529    529       sqlite3VdbeMemSetNull(pMem);
   530    530     }else{
   531    531       sqlite3VdbeMemRelease(pMem);
   532    532       pMem->r = val;
   533    533       pMem->flags = MEM_Real;
   534         -    pMem->type = SQLITE_FLOAT;
          534  +    pMem->memType = MEM_Real;
   535    535     }
   536    536   }
   537    537   #endif
   538    538   
   539    539   /*
   540    540   ** Delete any previous value and set the value of pMem to be an
   541    541   ** empty boolean index.
................................................................................
   735    735       pMem->xDel = xDel;
   736    736       flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn);
   737    737     }
   738    738   
   739    739     pMem->n = nByte;
   740    740     pMem->flags = flags;
   741    741     pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
   742         -  pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT);
          742  +  pMem->memType = flags&0x1f;
   743    743   
   744    744   #ifndef SQLITE_OMIT_UTF16
   745    745     if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
   746    746       return SQLITE_NOMEM;
   747    747     }
   748    748   #endif
   749    749   
................................................................................
   906    906     if( offset+amt<=available ){
   907    907       sqlite3VdbeMemRelease(pMem);
   908    908       pMem->z = &zData[offset];
   909    909       pMem->flags = MEM_Blob|MEM_Ephem;
   910    910     }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
   911    911       pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
   912    912       pMem->enc = 0;
   913         -    pMem->type = SQLITE_BLOB;
          913  +    pMem->memType = MEM_Blob;
   914    914       if( key ){
   915    915         rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
   916    916       }else{
   917    917         rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
   918    918       }
   919    919       pMem->z[amt] = 0;
   920    920       pMem->z[amt+1] = 0;
................................................................................
   976    976   /*
   977    977   ** Create a new sqlite3_value object.
   978    978   */
   979    979   sqlite3_value *sqlite3ValueNew(sqlite3 *db){
   980    980     Mem *p = sqlite3DbMallocZero(db, sizeof(*p));
   981    981     if( p ){
   982    982       p->flags = MEM_Null;
   983         -    p->type = SQLITE_NULL;
          983  +    p->memType = MEM_Null;
   984    984       p->db = db;
   985    985     }
   986    986     return p;
   987    987   }
   988    988   
   989    989   /*
   990    990   ** Context object passed by sqlite3Stat4ProbeSetValue() through to 
................................................................................
  1026   1026           if( pRec->pKeyInfo ){
  1027   1027             assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
  1028   1028             assert( pRec->pKeyInfo->enc==ENC(db) );
  1029   1029             pRec->flags = UNPACKED_PREFIX_MATCH;
  1030   1030             pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
  1031   1031             for(i=0; i<nCol; i++){
  1032   1032               pRec->aMem[i].flags = MEM_Null;
  1033         -            pRec->aMem[i].type = SQLITE_NULL;
         1033  +            pRec->aMem[i].memType = MEM_Null;
  1034   1034               pRec->aMem[i].db = db;
  1035   1035             }
  1036   1036           }else{
  1037   1037             sqlite3DbFree(db, pRec);
  1038   1038             pRec = 0;
  1039   1039           }
  1040   1040         }
................................................................................
  1099   1099       if( pVal==0 ) goto no_mem;
  1100   1100       if( ExprHasProperty(pExpr, EP_IntValue) ){
  1101   1101         sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
  1102   1102       }else{
  1103   1103         zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
  1104   1104         if( zVal==0 ) goto no_mem;
  1105   1105         sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
  1106         -      if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
         1106  +      if( op==TK_FLOAT ) pVal->memType = MEM_Real;
  1107   1107       }
  1108   1108       if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
  1109   1109         sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
  1110   1110       }else{
  1111   1111         sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8);
  1112   1112       }
  1113   1113       if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;