SQLite4
Check-in [3e371e1a44]
Not logged in

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

Overview
Comment:Remove the unused OP_InsertInt opcode from the VDBE.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3e371e1a441b2b89246c27e7ab377bcc5624ba25
User & Date: drh 2013-07-29 19:31:34
Context
2013-07-29
20:26
Change the name of Column.isPrimKey to Column.iPrimKey, make it a u16, and make it hold the integer column number of the column within the primary key. check-in: 6d33ce14cd user: drh tags: trunk
19:31
Remove the unused OP_InsertInt opcode from the VDBE. check-in: 3e371e1a44 user: drh tags: trunk
18:07
Remove some rowid-related dead code from where.c. Fix other code issues in the same file. check-in: 4856f08944 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
....
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
....
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
....
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
....
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
....
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
      *prNotFound = rMayHaveNull = ++pParse->nMem;
      sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);
    }else{
      testcase( pParse->nQueryLoop>0 );
      pParse->nQueryLoop = 0;
      *piCov = 0;
    }
    sqlite4CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
    pParse->nQueryLoop = savedNQueryLoop;
  }else{
    pX->iTable = iTab;
  }
  return eType;
}
#endif
................................................................................
** For a SELECT or EXISTS operator, return the register that holds the
** result.  For IN operators or if an error occurs, the return value is 0.
*/
#ifndef SQLITE4_OMIT_SUBQUERY
int sqlite4CodeSubselect(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  int rMayHaveNull,       /* Register that records whether NULLs exist in RHS */
  int isRowid             /* If true, LHS of IN operator is a rowid */
){
  int testAddr = -1;                      /* One-time test address */
  int rReg = 0;                           /* Register storing resulting */
  Vdbe *v = sqlite4GetVdbe(pParse);
  if( NEVER(v==0) ) return 0;
  sqlite4ExprCachePush(pParse);

................................................................................
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        SelectDest dest;
        ExprList *pEList;

        assert( !isRowid );
        sqlite4SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affinity = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;
        if( sqlite4Select(pParse, pExpr->x.pSelect, &dest) ){
          return 0;
        }
................................................................................
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->x.pList;
        ExprListItem *pItem;
        int r1, r2, r3;

        if( !affinity ){
          affinity = SQLITE4_AFF_NONE;
        }
        keyInfo.aColl[0] = sqlite4ExprCollSeq(pParse, pExpr->pLeft);

        /* Loop through each expression in <exprlist>. */
................................................................................
          */
          if( testAddr>=0 && !sqlite4ExprIsConstant(pE2) ){
            sqlite4VdbeChangeToNoop(v, testAddr);
            testAddr = -1;
          }

          /* Evaluate the expression and insert it into the temp table */
          if( isRowid && sqlite4ExprIsInteger(pE2, &iValToIns) ){
            sqlite4VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
          }else{
            r3 = sqlite4ExprCodeTarget(pParse, pE2, r1);
            if( isRowid ){
              sqlite4VdbeAddOp2(v, OP_MustBeInt, r3,
                                sqlite4VdbeCurrentAddr(v)+2);
              sqlite4VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
            }else{
              int r4 = sqlite4GetTempReg(pParse);
              sqlite4VdbeAddOp2(v, OP_MakeKey, pExpr->iTable, r4);
              sqlite4VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
              sqlite4ExprCacheAffinityChange(pParse, r3, 1);
              sqlite4VdbeAddOp3(v, OP_IdxInsert, pExpr->iTable, r2, r4);
              sqlite4ReleaseTempReg(pParse, r4);
            }
          }
        }
        sqlite4ReleaseTempReg(pParse, r1);
        sqlite4ReleaseTempReg(pParse, r2);
      }
      if( !isRowid ){
        sqlite4VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
      }
      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {
      /* If this has to be a scalar SELECT.  Generate code to put the
................................................................................
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      inReg = sqlite4CodeSubselect(pParse, pExpr, 0, 0);
      break;
    }
    case TK_IN: {
      int destIfFalse = sqlite4VdbeMakeLabel(v);
      int destIfNull = sqlite4VdbeMakeLabel(v);
      sqlite4VdbeAddOp2(v, OP_Null, 0, target);
      sqlite4ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);







|







 







|
<







 







|












<







 







|







 







<
<
<
|
<
<
<
<
<
|
|
|
|
|
|
<
<




<
|
<







 







|







1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
....
1644
1645
1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
....
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722

1723
1724
1725
1726
1727
1728
1729
....
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
....
1765
1766
1767
1768
1769
1770
1771



1772





1773
1774
1775
1776
1777
1778


1779
1780
1781
1782

1783

1784
1785
1786
1787
1788
1789
1790
....
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
      *prNotFound = rMayHaveNull = ++pParse->nMem;
      sqlite4VdbeAddOp2(v, OP_Null, 0, *prNotFound);
    }else{
      testcase( pParse->nQueryLoop>0 );
      pParse->nQueryLoop = 0;
      *piCov = 0;
    }
    sqlite4CodeSubselect(pParse, pX, rMayHaveNull);
    pParse->nQueryLoop = savedNQueryLoop;
  }else{
    pX->iTable = iTab;
  }
  return eType;
}
#endif
................................................................................
** For a SELECT or EXISTS operator, return the register that holds the
** result.  For IN operators or if an error occurs, the return value is 0.
*/
#ifndef SQLITE4_OMIT_SUBQUERY
int sqlite4CodeSubselect(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  int rMayHaveNull        /* Register that records whether NULLs exist in RHS */

){
  int testAddr = -1;                      /* One-time test address */
  int rReg = 0;                           /* Register storing resulting */
  Vdbe *v = sqlite4GetVdbe(pParse);
  if( NEVER(v==0) ) return 0;
  sqlite4ExprCachePush(pParse);

................................................................................
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite4VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, 1);
      memset(&keyInfo, 0, sizeof(keyInfo));
      keyInfo.nField = 1;

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        SelectDest dest;
        ExprList *pEList;


        sqlite4SelectDestInit(&dest, SRT_Set, pExpr->iTable);
        dest.affinity = (u8)affinity;
        assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
        pExpr->x.pSelect->iLimit = 0;
        if( sqlite4Select(pParse, pExpr->x.pSelect, &dest) ){
          return 0;
        }
................................................................................
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        int i;
        ExprList *pList = pExpr->x.pList;
        ExprListItem *pItem;
        int r1, r2, r3, r4;

        if( !affinity ){
          affinity = SQLITE4_AFF_NONE;
        }
        keyInfo.aColl[0] = sqlite4ExprCollSeq(pParse, pExpr->pLeft);

        /* Loop through each expression in <exprlist>. */
................................................................................
          */
          if( testAddr>=0 && !sqlite4ExprIsConstant(pE2) ){
            sqlite4VdbeChangeToNoop(v, testAddr);
            testAddr = -1;
          }

          /* Evaluate the expression and insert it into the temp table */



          r3 = sqlite4ExprCodeTarget(pParse, pE2, r1);





          r4 = sqlite4GetTempReg(pParse);
          sqlite4VdbeAddOp2(v, OP_MakeKey, pExpr->iTable, r4);
          sqlite4VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
          sqlite4ExprCacheAffinityChange(pParse, r3, 1);
          sqlite4VdbeAddOp3(v, OP_IdxInsert, pExpr->iTable, r2, r4);
          sqlite4ReleaseTempReg(pParse, r4);


        }
        sqlite4ReleaseTempReg(pParse, r1);
        sqlite4ReleaseTempReg(pParse, r2);
      }

      sqlite4VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);

      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {
      /* If this has to be a scalar SELECT.  Generate code to put the
................................................................................
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case TK_EXISTS:
    case TK_SELECT: {
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      inReg = sqlite4CodeSubselect(pParse, pExpr, 0);
      break;
    }
    case TK_IN: {
      int destIfFalse = sqlite4VdbeMakeLabel(v);
      int destIfNull = sqlite4VdbeMakeLabel(v);
      sqlite4VdbeAddOp2(v, OP_Null, 0, target);
      sqlite4ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);

Changes to src/sqliteInt.h.

2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
#endif
void sqlite4Reindex(Parse*, Token*, Token*);
void sqlite4AlterFunctions(sqlite4_env*);
void sqlite4AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite4GetToken(const unsigned char *, int *);
void sqlite4NestedParse(Parse*, const char*, ...);
void sqlite4ExpirePreparedStatements(sqlite4*);
int sqlite4CodeSubselect(Parse *, Expr *, int, int);
void sqlite4SelectPrep(Parse*, Select*, NameContext*);
int sqlite4ResolveExprNames(NameContext*, Expr*);
void sqlite4ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite4ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite4ColumnDefault(Vdbe *, Table *, int, int);
void sqlite4AlterFinishAddColumn(Parse *, Token *);
void sqlite4AlterBeginAddColumn(Parse *, SrcList *);







|







2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
#endif
void sqlite4Reindex(Parse*, Token*, Token*);
void sqlite4AlterFunctions(sqlite4_env*);
void sqlite4AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite4GetToken(const unsigned char *, int *);
void sqlite4NestedParse(Parse*, const char*, ...);
void sqlite4ExpirePreparedStatements(sqlite4*);
int sqlite4CodeSubselect(Parse *, Expr *, int);
void sqlite4SelectPrep(Parse*, Select*, NameContext*);
int sqlite4ResolveExprNames(NameContext*, Expr*);
void sqlite4ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite4ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite4ColumnDefault(Vdbe *, Table *, int, int);
void sqlite4AlterFinishAddColumn(Parse *, Token *);
void sqlite4AlterBeginAddColumn(Parse *, SrcList *);

Changes to src/vdbe.c.

3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
....
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
** and register P2 becomes ephemeral.  If the cursor is changed, the
** value of register P2 will then change.  Make sure this does not
** cause any problems.)
**
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/
/* Opcode: InsertInt P1 P2 P3 P4 P5
**
** This works exactly like OP_Insert except that the key is the
** integer value P3, not the value of the integer stored in register P3.
*/
case OP_Insert:
case OP_InsertInt: {
  Mem *pData;       /* MEM cell holding data for the record to be inserted */
  Mem *pKey;        /* MEM cell holding key  for the record */
  i64 iKey;         /* The integer ROWID or key for the record to be inserted */
  VdbeCursor *pC;   /* Cursor to table into which insert is written */
  int n;
  KVByteArray aKey[24];

................................................................................
  pData = &aMem[pOp->p2];
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( memIsValid(pData) );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  REGISTER_TRACE(pOp->p2, pData);

  if( pOp->opcode==OP_Insert ){
    pKey = &aMem[pOp->p3];
    assert( pKey->flags & MEM_Int );
    assert( memIsValid(pKey) );
    REGISTER_TRACE(pOp->p3, pKey);
    iKey = sqlite4_num_to_int64(pKey->u.num, 0);
  }else{
    /* assert( pOp->opcode==OP_InsertInt ); */
    iKey = pOp->p3;
  }

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pData->flags & MEM_Null ){
    pData->z = 0;
    pData->n = 0;
  }else{
    assert( pData->flags & (MEM_Blob|MEM_Str) );







<
<
<
<
<
|
<







 







<
|
|
|
|
|
<
<
<
<







3401
3402
3403
3404
3405
3406
3407





3408

3409
3410
3411
3412
3413
3414
3415
....
3416
3417
3418
3419
3420
3421
3422

3423
3424
3425
3426
3427




3428
3429
3430
3431
3432
3433
3434
** and register P2 becomes ephemeral.  If the cursor is changed, the
** value of register P2 will then change.  Make sure this does not
** cause any problems.)
**
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/





case OP_Insert: {

  Mem *pData;       /* MEM cell holding data for the record to be inserted */
  Mem *pKey;        /* MEM cell holding key  for the record */
  i64 iKey;         /* The integer ROWID or key for the record to be inserted */
  VdbeCursor *pC;   /* Cursor to table into which insert is written */
  int n;
  KVByteArray aKey[24];

................................................................................
  pData = &aMem[pOp->p2];
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( memIsValid(pData) );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  REGISTER_TRACE(pOp->p2, pData);


  pKey = &aMem[pOp->p3];
  assert( pKey->flags & MEM_Int );
  assert( memIsValid(pKey) );
  REGISTER_TRACE(pOp->p3, pKey);
  iKey = sqlite4_num_to_int64(pKey->u.num, 0);





  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pData->flags & MEM_Null ){
    pData->z = 0;
    pData->n = 0;
  }else{
    assert( pData->flags & (MEM_Blob|MEM_Str) );