/ Check-in [39ae92f5]
Login

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

Overview
Comment:Experiments with an OP_Unpack opcode that extracts multiple columns from a record without caching.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | unpack-opcode
Files: files | file ages | folders
SHA1: 39ae92f5c63de4b95502f438dc7e9f2669efdf91
User & Date: drh 2015-10-15 20:17:15
Context
2015-10-15
20:17
Experiments with an OP_Unpack opcode that extracts multiple columns from a record without caching. Leaf check-in: 39ae92f5 user: drh tags: unpack-opcode
19:21
Enhance the use of the column cache for UPDATE statements, making them more efficient for the case where a column is modified to be an expression of other unmodified columns. check-in: 871e091d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/select.c.

  1226   1226       sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
  1227   1227       if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
  1228   1228       addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
  1229   1229       VdbeCoverage(v);
  1230   1230       codeOffset(v, p->iOffset, addrContinue);
  1231   1231       sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
  1232   1232       bSeq = 0;
         1233  +    sqlite3VdbeAddOp4Int(v, OP_Unpack, regSortOut, regRow, nSortData, nKey);
  1233   1234     }else{
  1234   1235       addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
  1235   1236       codeOffset(v, p->iOffset, addrContinue);
  1236   1237       iSortTab = iTab;
  1237   1238       bSeq = 1;
  1238         -  }
  1239         -  for(i=0; i<nSortData; i++){
  1240         -    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
  1241         -    VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
         1239  +    for(i=0; i<nSortData; i++){
         1240  +      sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
         1241  +      VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
         1242  +    }
  1242   1243     }
  1243   1244     switch( eDest ){
  1244   1245       case SRT_EphemTab: {
  1245   1246         sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
  1246   1247         sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
  1247   1248         sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
  1248   1249         break;
................................................................................
  5336   5337         ** from the previous row currently stored in a0, a1, a2...
  5337   5338         */
  5338   5339         addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
  5339   5340         sqlite3ExprCacheClear(pParse);
  5340   5341         if( groupBySort ){
  5341   5342           sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
  5342   5343                             sortOut, sortPTab);
  5343         -      }
  5344         -      for(j=0; j<pGroupBy->nExpr; j++){
  5345         -        if( groupBySort ){
  5346         -          sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
  5347         -        }else{
         5344  +        sqlite3VdbeAddOp4Int(v, OP_Unpack, sortOut, iBMem, pGroupBy->nExpr, 0);
         5345  +      }else{
         5346  +        for(j=0; j<pGroupBy->nExpr; j++){
  5348   5347             sAggInfo.directMode = 1;
  5349   5348             sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
  5350   5349           }
  5351   5350         }
  5352   5351         sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
  5353   5352                             (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
  5354   5353         addr1 = sqlite3VdbeCurrentAddr(v);

Changes to src/vdbe.c.

  2609   2609       pDest->flags = fx|MEM_Term;
  2610   2610     }
  2611   2611   op_column_error:
  2612   2612     UPDATE_MAX_BLOBSIZE(pDest);
  2613   2613     REGISTER_TRACE(pOp->p3, pDest);
  2614   2614     break;
  2615   2615   }
         2616  +
         2617  +/* Opcode: Unpack P1 P2 P3 P4 *
         2618  +** Synopsis: r[P2@P3] = unpack(P1)
         2619  +**
         2620  +** Decode the P3 fields of the record object held in register P1
         2621  +** start with the P4-th field and store the values in registers P2
         2622  +** and following.
         2623  +*/
         2624  +case OP_Unpack: {
         2625  +  const unsigned char *aKey;
         2626  +  int d; 
         2627  +  u32 idx;                        /* Offset in aKey[] to read from */
         2628  +  u16 u;                          /* Unsigned loop counter */
         2629  +  u32 szHdr;
         2630  +  int nField;     
         2631  +  u32 serial_type;
         2632  +  int iOfst;                      /* Skip this many fields */
         2633  +
         2634  +  pIn1 = &aMem[pOp->p1];
         2635  +  assert( pIn1->flags & MEM_Blob );
         2636  +  aKey = (const unsigned char*)pIn1->z;
         2637  +  pOut = &aMem[pOp->p2];
         2638  +  nField = pOp->p3;
         2639  +  assert( pOp->p4type==P4_INT32 );
         2640  +  iOfst = pOp->p4.i;
         2641  +  idx = getVarint32(aKey, szHdr);
         2642  +  d = szHdr;
         2643  +  u = 0;
         2644  +  while( idx<szHdr && d<=pIn1->n ){
         2645  +    idx += getVarint32(&aKey[idx], serial_type);
         2646  +    if( iOfst ){
         2647  +      iOfst--;
         2648  +      d += sqlite3VdbeSerialTypeLen(serial_type);
         2649  +    }else{
         2650  +      memAboutToChange(p, pOut);
         2651  +      sqlite3VdbeMemSetNull(pOut);
         2652  +      pOut->enc = encoding;
         2653  +      d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pOut);
         2654  +      REGISTER_TRACE((int)(pOut - aMem), pOut);
         2655  +      pOut++;
         2656  +      if( (++u)>=nField ) break;
         2657  +    }
         2658  +  }
         2659  +  break;
         2660  +}
  2616   2661   
  2617   2662   /* Opcode: Affinity P1 P2 * P4 *
  2618   2663   ** Synopsis: affinity(r[P1@P2])
  2619   2664   **
  2620   2665   ** Apply affinities to a range of P2 registers starting with P1.
  2621   2666   **
  2622   2667   ** P4 is a string that is P2 characters long. The nth character of the