/ Check-in [076be547]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Performance optimization for the OP_Column opcode.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 076be5474df628bbbfd2b645adba30e1e093acd0
User & Date: drh 2015-10-15 21:30:24
Context
2015-10-16
12:39
Improved header comment on the tool/vdbe_profile.tcl script. No changes to code. check-in: b17ad8fc user: drh tags: trunk
03:34
Whenever two or more OP_Column opcodes on the same cursor occur in succession, try to reordering them so that the one that extracts the right-most column is first, so that it will warm up the row cache for all those that follow. This gives a small performance boost. Leaf check-in: 08e8f04d user: drh tags: reorder-column-opcodes
2015-10-15
21:30
Performance optimization for the OP_Column opcode. check-in: 076be547 user: drh tags: trunk
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/vdbe.c.

  2364   2364     int i;             /* Loop counter */
  2365   2365     Mem *pDest;        /* Where to write the extracted value */
  2366   2366     Mem sMem;          /* For storing the record being decoded */
  2367   2367     const u8 *zData;   /* Part of the record being decoded */
  2368   2368     const u8 *zHdr;    /* Next unparsed byte of the header */
  2369   2369     const u8 *zEndHdr; /* Pointer to first byte after the header */
  2370   2370     u32 offset;        /* Offset into the data */
         2371  +  u64 offset64;      /* 64-bit offset */
  2371   2372     u32 szField;       /* Number of bytes in the content of a field */
  2372   2373     u32 avail;         /* Number of bytes of available data */
  2373   2374     u32 t;             /* A type code from the record header */
  2374   2375     u16 fx;            /* pDest->flags value */
  2375   2376     Mem *pReg;         /* PseudoTable input register */
  2376   2377   
  2377   2378     p2 = pOp->p2;
................................................................................
  2490   2491           zData = (u8*)sMem.z;
  2491   2492         }else{
  2492   2493           zData = pC->aRow;
  2493   2494         }
  2494   2495     
  2495   2496         /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
  2496   2497         i = pC->nHdrParsed;
  2497         -      offset = aOffset[i];
         2498  +      offset64 = aOffset[i];
  2498   2499         zHdr = zData + pC->iHdrOffset;
  2499   2500         zEndHdr = zData + aOffset[0];
  2500   2501         assert( i<=p2 && zHdr<zEndHdr );
  2501   2502         do{
  2502   2503           if( zHdr[0]<0x80 ){
  2503   2504             t = zHdr[0];
  2504   2505             zHdr++;
  2505   2506           }else{
  2506   2507             zHdr += sqlite3GetVarint32(zHdr, &t);
  2507   2508           }
  2508   2509           pC->aType[i] = t;
  2509   2510           szField = sqlite3VdbeSerialTypeLen(t);
  2510         -        offset += szField;
  2511         -        if( offset<szField ){  /* True if offset overflows */
  2512         -          zHdr = &zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */
  2513         -          break;
  2514         -        }
         2511  +        offset64 += szField;
  2515   2512           i++;
  2516         -        aOffset[i] = offset;
         2513  +        aOffset[i] = (u32)(offset64 & 0xffffffff);
  2517   2514         }while( i<=p2 && zHdr<zEndHdr );
  2518   2515         pC->nHdrParsed = i;
  2519   2516         pC->iHdrOffset = (u32)(zHdr - zData);
  2520   2517         if( pC->aRow==0 ){
  2521   2518           sqlite3VdbeMemRelease(&sMem);
  2522   2519           sMem.flags = MEM_Null;
  2523   2520         }
  2524   2521     
  2525   2522         /* The record is corrupt if any of the following are true:
  2526   2523         ** (1) the bytes of the header extend past the declared header size
  2527   2524         **          (zHdr>zEndHdr)
  2528   2525         ** (2) the entire header was used but not all data was used
  2529         -      **          (zHdr==zEndHdr && offset!=pC->payloadSize)
         2526  +      **          (zHdr==zEndHdr && offset64!=pC->payloadSize)
  2530   2527         ** (3) the end of the data extends beyond the end of the record.
  2531         -      **          (offset > pC->payloadSize)
         2528  +      **          (offset64 > pC->payloadSize)
  2532   2529         */
  2533         -      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
  2534         -       || (offset > pC->payloadSize)
         2530  +      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
         2531  +       || (offset64 > pC->payloadSize)
  2535   2532         ){
  2536   2533           rc = SQLITE_CORRUPT_BKPT;
  2537   2534           goto op_column_error;
  2538   2535         }
  2539   2536       }
  2540   2537   
  2541   2538       /* If after trying to extract new entries from the header, nHdrParsed is