/ Check-in [0a5b00e4]
Login

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

Overview
Comment:Add and use the sqlite3VdbeChangeOpcode() routine. Simplify the implementation of the other sqlite3VdbeChange*() routines.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0a5b00e493efae58252f9fc7bde5a469645942d5
User & Date: drh 2015-09-02 18:40:33
Context
2015-09-02
21:00
Optimizations to the printf formatter. check-in: a3b35dde user: drh tags: trunk
18:40
Add and use the sqlite3VdbeChangeOpcode() routine. Simplify the implementation of the other sqlite3VdbeChange*() routines. check-in: 0a5b00e4 user: drh tags: trunk
18:19
Add the sqlite3VdbeAddGoto(v,i) routine as a shorthand for sqlite3VdbeAddOp2(v,OP_Goto,0,i). check-in: be78f413 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
....
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729

  /* Convert the OP_CreateTable opcode that would normally create the
  ** root-page for the table into an OP_CreateIndex opcode.  The index
  ** created will become the PRIMARY KEY index.
  */
  if( pParse->addrCrTab ){
    assert( v );
    sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
  }

  /* Locate the PRIMARY KEY index.  Or, if this table was originally
  ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. 
  */
  if( pTab->iPKey>=0 ){
    ExprList *pList;
................................................................................

    /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
    ** table entry. This is only required if currently generating VDBE
    ** code for a CREATE TABLE (not when parsing one as part of reading
    ** a database schema).  */
    if( v ){
      assert( db->init.busy==0 );
      sqlite3VdbeGetOp(v, pPk->tnum)->opcode = OP_Goto;
    }

    /*
    ** Remove all redundant columns from the PRIMARY KEY.  For example, change
    ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
    ** code assumes the PRIMARY KEY contains no repeated columns.
    */







|







 







|







1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
....
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729

  /* Convert the OP_CreateTable opcode that would normally create the
  ** root-page for the table into an OP_CreateIndex opcode.  The index
  ** created will become the PRIMARY KEY index.
  */
  if( pParse->addrCrTab ){
    assert( v );
    sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex);
  }

  /* Locate the PRIMARY KEY index.  Or, if this table was originally
  ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. 
  */
  if( pTab->iPKey>=0 ){
    ExprList *pList;
................................................................................

    /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
    ** table entry. This is only required if currently generating VDBE
    ** code for a CREATE TABLE (not when parsing one as part of reading
    ** a database schema).  */
    if( v ){
      assert( db->init.busy==0 );
      sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
    }

    /*
    ** Remove all redundant columns from the PRIMARY KEY.  For example, change
    ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
    ** code assumes the PRIMARY KEY contains no repeated columns.
    */

Changes to src/select.c.

5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085

  /* Set the limiter.
  */
  iEnd = sqlite3VdbeMakeLabel(v);
  p->nSelectRow = LARGEST_INT64;
  computeLimitRegisters(pParse, p, iEnd);
  if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
    sqlite3VdbeGetOp(v, sSort.addrSortIndex)->opcode = OP_SorterOpen;
    sSort.sortFlags |= SORTFLAG_UseSorter;
  }

  /* Open an ephemeral index to use for the distinct set.
  */
  if( p->selFlags & SF_Distinct ){
    sDistinct.tabTnct = pParse->nTab++;







|







5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085

  /* Set the limiter.
  */
  iEnd = sqlite3VdbeMakeLabel(v);
  p->nSelectRow = LARGEST_INT64;
  computeLimitRegisters(pParse, p, iEnd);
  if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
    sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
    sSort.sortFlags |= SORTFLAG_UseSorter;
  }

  /* Open an ephemeral index to use for the distinct set.
  */
  if( p->selFlags & SF_Distinct ){
    sDistinct.tabTnct = pParse->nTab++;

Changes to src/vdbe.h.

172
173
174
175
176
177
178

179
180
181
182
183
184
185
int sqlite3VdbeAddGoto(Vdbe*,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);

void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);







>







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
int sqlite3VdbeAddGoto(Vdbe*,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);

Changes to src/vdbeaux.c.

660
661
662
663
664
665
666

667
668
669
670
671
672
673
674
675

676


677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
704
705
706
707
708
709

710
711
712
713
714
715
716
717
718

719
720
721
722
723
724
725
    p->aScan = aNew;
  }
}
#endif


/*

** Change the value of the P1 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
** few minor changes to the program.
*/
void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
  assert( p!=0 );
  if( ((u32)p->nOp)>addr ){
    p->aOp[addr].p1 = val;

  }


}

/*
** Change the value of the P2 operand for a specific instruction.
** This routine is useful for setting a jump destination.
*/
void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
  assert( p!=0 );
  if( ((u32)p->nOp)>addr ){
    p->aOp[addr].p2 = val;

  }
}

/*
** Change the value of the P3 operand for a specific instruction.
*/
void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
  assert( p!=0 );
  if( ((u32)p->nOp)>addr ){
    p->aOp[addr].p3 = val;

  }
}

/*
** Change the value of the P5 operand for the most recently
** added operation.
*/
void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
  assert( p!=0 );
  if( p->aOp ){
    assert( p->nOp>0 );
    p->aOp[p->nOp-1].p5 = val;
  }

}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);
  p->pParse->iFixedOp = p->nOp - 1;

}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
*/







>
|
<
<
<

|
<
<
<
>
|
>
>

<
<
<
<
<

<
<
<
>
|
<
<
<
<
<

<
<
<
>
|
<
<
<
<
<
<
|
<
<
<
<
<
>







<

>







660
661
662
663
664
665
666
667
668



669
670



671
672
673
674
675





676



677
678





679



680
681






682





683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
    p->aScan = aNew;
  }
}
#endif


/*
** Change the value of the opcode, or P1, P2, P3, or P5 operands
** for a specific instruction.



*/
void sqlite3VdbeChangeOpcode(Vdbe *p, u32 addr, u8 iNewOpcode){



  sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode;
}
void sqlite3VdbeChangeP1(Vdbe *p, u32 addr, int val){
  sqlite3VdbeGetOp(p,addr)->p1 = val;
}





void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){



  sqlite3VdbeGetOp(p,addr)->p2 = val;
}





void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){



  sqlite3VdbeGetOp(p,addr)->p3 = val;
}






void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){





  sqlite3VdbeGetOp(p,-1)->p5 = p5;
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){

  p->pParse->iFixedOp = p->nOp - 1;
  sqlite3VdbeChangeP2(p, addr, p->nOp);
}


/*
** If the input FuncDef structure is ephemeral, then free it.  If
** the FuncDef is not ephermal, then do nothing.
*/