SQLite4
Check-in [5442b20bf6]
Not logged in

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

Overview
Comment:Enable the AUTOINCREMENT feature.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5442b20bf685564557964e2f9ac5cdd9bff0404f
User & Date: drh 2013-01-20 00:07:20
Context
2013-01-20
02:38
Fix a typo on the key-encoding documentation. check-in: b1ae0ca8c3 user: drh tags: trunk
00:07
Enable the AUTOINCREMENT feature. check-in: 5442b20bf6 user: drh tags: trunk
2013-01-19
19:49
Insert a value in place of NULL in an INTEGER PRIMARY KEY, even if the IPK column is omitted from the VALUES list in the INSERT statement. check-in: 4d1b506594 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Show Whitespace Changes Patch

Changes to main.mk.

63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
TCCX =  $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) 
TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
TCCX += -I$(TOP)/ext/async

TCPPX = g++ -Wall -g -I. -I$(TOP)/src $(OPTS)



LIBOBJ+= alter.o analyze.o attach.o auth.o \
         build.o \
         callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
	 fts5.o fts5func.o \
         func.o global.o hash.o \
         icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
         lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
         lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
         lsm_unix.o lsm_varint.o \
         main.o malloc.o math.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o \
         parse.o pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o \
         tokenize.o trigger.o \
         update.o util.o varint.o \
         vdbe.o vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
         vdbemem.o vdbetrace.o \
         walker.o where.o utf.o

# All of the source code files.
#
SRC = \
  $(TOP)/src/alter.c \







>
|











|



|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
TCCX =  $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) 
TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
TCCX += -I$(TOP)/ext/async

TCPPX = g++ -Wall -g -I. -I$(TOP)/src $(OPTS)


LIBOBJ+= vdbe.o parse.o \
         alter.o analyze.o attach.o auth.o \
         build.o \
         callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
	 fts5.o fts5func.o \
         func.o global.o hash.o \
         icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
         lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
         lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
         lsm_unix.o lsm_varint.o \
         main.o malloc.o math.o mem0.o mem1.o mem2.o mem3.o mem5.o \
         mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o \
         pragma.o prepare.o printf.o \
         random.o resolve.o rowset.o rtree.o select.o status.o \
         tokenize.o trigger.o \
         update.o util.o varint.o \
         vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
         vdbemem.o vdbetrace.o \
         walker.o where.o utf.o

# All of the source code files.
#
SRC = \
  $(TOP)/src/alter.c \

Changes to src/build.c.

1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094





1095
1096
1097
1098
1099
1100
1101
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].isPrimKey = i+1;
        pTab->aCol[iCol].notNull = 1;
      }
    }
    if( pList->nExpr>1 ) iCol = -1;
  }
  if( autoInc ){
    sqlite4ErrorMsg(pParse, "AUTOINCREMENT not yet implemented");
    goto primary_key_exit;
  }
  pPk = sqlite4CreateIndex(
     pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0, 1
  );

  if( iCol>=0 && iCol<pTab->nCol
   && (zType = pTab->aCol[iCol].zType)!=0
   && sqlite4StrICmp(zType, "INTEGER")==0
   && sortOrder==SQLITE4_SO_ASC
   && pPk
  ){
    pPk->fIndex |= IDX_IntPK;





  }
  pList = 0;

primary_key_exit:
  sqlite4ExprListDelete(pParse->db, pList);
  return;
}







<
<
<
<











>
>
>
>
>







1073
1074
1075
1076
1077
1078
1079




1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
      if( iCol<pTab->nCol ){
        pTab->aCol[iCol].isPrimKey = i+1;
        pTab->aCol[iCol].notNull = 1;
      }
    }
    if( pList->nExpr>1 ) iCol = -1;
  }




  pPk = sqlite4CreateIndex(
     pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0, 1
  );

  if( iCol>=0 && iCol<pTab->nCol
   && (zType = pTab->aCol[iCol].zType)!=0
   && sqlite4StrICmp(zType, "INTEGER")==0
   && sortOrder==SQLITE4_SO_ASC
   && pPk
  ){
    pPk->fIndex |= IDX_IntPK;
    assert( autoInc==0 || autoInc==1 );
    pTab->tabFlags |= (-autoInc)&TF_Autoincrement;
  }else if( autoInc ){
    sqlite4ErrorMsg(pParse, 
        "AUTOINCREMENT permitted on INTEGER PRIMARY KEY ASC only");
  }
  pList = 0;

primary_key_exit:
  sqlite4ExprListDelete(pParse->db, pList);
  return;
}

Changes to src/insert.c.

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
513
514
515
516
517
518
519




520
521
522
523
524
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
...
625
626
627
628
629
630
631





632
633
634
635
636
637
638
...
856
857
858
859
860
861
862

863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
...
895
896
897
898
899
900
901









902
903
904
905
906
907
908
void sqlite4OpenTable(
  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  int iDb,        /* The database index in sqlite4.aDb[] */
  Table *pTab,    /* The table to be opened */
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  assert( 0 );

}

/*
** Open VDBE cursor iCur to access index pIdx. pIdx is guaranteed to be
** a part of database iDb.
*/
void sqlite4OpenIndex(
................................................................................
**   (1)  Register to hold the name of the pTab table.
**   (2)  Register to hold the maximum ROWID of pTab.
**   (3)  Register to hold the rowid in sqlite_sequence of pTab
**
** The 2nd register is the one that is returned.  That is all the
** insert routine needs to know about.
*/
/*static FIXME: make static when this function gets used. */ int autoIncBegin(
  Parse *pParse,      /* Parsing context */
  int iDb,            /* Index of the database holding pTab */
  Table *pTab         /* The table we are writing to */
){
  int memId = 0;      /* Register holding maximum rowid */
  if( pTab->tabFlags & TF_Autoincrement ){
    Parse *pToplevel = sqlite4ParseToplevel(pParse);
................................................................................
** Update the maximum rowid for an autoincrement calculation.
**
** This routine should be called when the top of the stack holds a
** new rowid that is about to be inserted.  If that new rowid is
** larger than the maximum rowid in the memId memory cell, then the
** memory cell is updated.  The stack is unchanged.
*/
/*static FIXME: make static when this function gets used. */ void autoIncStep(Parse *pParse, int memId, int regRowid){
  if( memId>0 ){
    sqlite4VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid);
  }
}

/*
** This routine generates the code needed to write autoincrement
................................................................................
  int addrInsTop = 0;   /* Jump to label "D" */
  int addrCont = 0;     /* Top of insert loop. Label "C" in templates 3 and 4 */
  int addrSelect = 0;   /* Address of coroutine that implements the SELECT */
  SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
  int iDb;              /* Index of database holding TABLE */
  Db *pDb;              /* The database containing table being inserted into */
  int appendFlag = 0;   /* True if the insert is likely to be an append */





  /* Register allocations */
  int regFromSelect = 0;/* Base register for data coming from SELECT */
  int regEof = 0;       /* Register recording end of SELECT data */
  int *aRegIdx = 0;     /* One register allocated to each index */

  int iPk;                        /* Cursor offset of PK index cursor */
  Index *pPk;                     /* Primary key for table pTab */
  int iIntPKCol = -1;             /* Column of INTEGER PRIMARY KEY or -1 */
  int bImplicitPK;                /* True if table pTab has an implicit PK */
  int regContent;                 /* First register in column value array */
  int regRowid;                   /* If bImplicitPK, register holding IPK */



#ifndef SQLITE4_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  Trigger *pTrigger;          /* List of triggers on pTab, if required */
  int tmask;                  /* Mask of trigger times */
#endif

................................................................................
  */
  if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
    assert( !pTrigger );
    assert( pList==0 );
    goto insert_end;
  }
#endif /* SQLITE4_OMIT_XFER_OPT */






  /* Figure out how many columns of data are supplied.  If the data
  ** is coming from a SELECT statement, then generate a co-routine that
  ** produces a single row of the SELECT on each invocation.  The
  ** co-routine is the common header to the 3rd and 4th templates.
  */
  if( pSelect ){
................................................................................
    regRowid++;
    pParse->nMem++;
  }

  endOfLoop = sqlite4VdbeMakeLabel(v);

  for(i=0; i<pTab->nCol; i++){

    j = i;
    if( pColumn ){
      for(j=0; j<pColumn->nId; j++){
        if( pColumn->a[j].idx==i ) break;
      }
    }

    if( nColumn==0 || (pColumn && j>=pColumn->nId) ){
      sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regContent+i);
    }else if( useTempTable ){
      sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, regContent+i);
    }else if( pSelect ){
      sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+j, regContent+i);
    }else{
      assert( pSelect==0 ); /* Otherwise useTempTable is true */
      sqlite4ExprCodeAndCache(pParse, pList->a[j].pExpr, regContent+i);
    }
    if( i==iIntPKCol ){
      int a1;
      a1 = sqlite4VdbeAddOp1(v, OP_NotNull, regContent+i);
      sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur, regContent+i);
      sqlite4VdbeJumpHere(v, a1);
    }
  }

  if( !isView ){
    sqlite4VdbeAddOp2(v, OP_Affinity, regContent, pTab->nCol);
    sqlite4TableAffinityStr(v, pTab);
  }
................................................................................
    sqlite4VdbeAddOp2(v, OP_Integer, -1, regRowid);
    VdbeComment((v, "new.rowid value for BEFORE triggers"));
    sqlite4CodeRowTrigger(
        pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
        pTab, (regRowid - pTab->nCol - 1), onError, endOfLoop
    );
  }










  if( bImplicitPK ){
    assert( !isView );
    sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur+iPk, regRowid);
  }

  if( !isView ){







|
>







 







|







 







|







 







>
>
>
>





<
<
<
<
<
|
|
<
>







 







>
>
>
>
>







 







>








|

|

|


|
<
<
<
<
<
<







 







>
>
>
>
>
>
>
>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
...
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
...
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529





530
531

532
533
534
535
536
537
538
539
...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
...
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884






885
886
887
888
889
890
891
...
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
void sqlite4OpenTable(
  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  int iDb,        /* The database index in sqlite4.aDb[] */
  Table *pTab,    /* The table to be opened */
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  Index *pPk = sqlite4FindPrimaryKey(pTab, 0);
  sqlite4OpenIndex(p, iCur, iDb, pPk, opcode);
}

/*
** Open VDBE cursor iCur to access index pIdx. pIdx is guaranteed to be
** a part of database iDb.
*/
void sqlite4OpenIndex(
................................................................................
**   (1)  Register to hold the name of the pTab table.
**   (2)  Register to hold the maximum ROWID of pTab.
**   (3)  Register to hold the rowid in sqlite_sequence of pTab
**
** The 2nd register is the one that is returned.  That is all the
** insert routine needs to know about.
*/
static int autoIncBegin(
  Parse *pParse,      /* Parsing context */
  int iDb,            /* Index of the database holding pTab */
  Table *pTab         /* The table we are writing to */
){
  int memId = 0;      /* Register holding maximum rowid */
  if( pTab->tabFlags & TF_Autoincrement ){
    Parse *pToplevel = sqlite4ParseToplevel(pParse);
................................................................................
** Update the maximum rowid for an autoincrement calculation.
**
** This routine should be called when the top of the stack holds a
** new rowid that is about to be inserted.  If that new rowid is
** larger than the maximum rowid in the memId memory cell, then the
** memory cell is updated.  The stack is unchanged.
*/
static void autoIncStep(Parse *pParse, int memId, int regRowid){
  if( memId>0 ){
    sqlite4VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid);
  }
}

/*
** This routine generates the code needed to write autoincrement
................................................................................
  int addrInsTop = 0;   /* Jump to label "D" */
  int addrCont = 0;     /* Top of insert loop. Label "C" in templates 3 and 4 */
  int addrSelect = 0;   /* Address of coroutine that implements the SELECT */
  SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
  int iDb;              /* Index of database holding TABLE */
  Db *pDb;              /* The database containing table being inserted into */
  int appendFlag = 0;   /* True if the insert is likely to be an append */
  int iPk;              /* Cursor offset of PK index cursor */
  Index *pPk;           /* Primary key for table pTab */
  int iIntPKCol = -1;   /* Column of INTEGER PRIMARY KEY or -1 */
  int bImplicitPK;      /* True if table pTab has an implicit PK */

  /* Register allocations */
  int regFromSelect = 0;/* Base register for data coming from SELECT */
  int regEof = 0;       /* Register recording end of SELECT data */
  int *aRegIdx = 0;     /* One register allocated to each index */





  int regContent;       /* First register in column value array */
  int regRowid;         /* If bImplicitPK, register holding IPK */

  int regAutoinc;       /* Register holding the AUTOINCREMENT counter */

#ifndef SQLITE4_OMIT_TRIGGER
  int isView;                 /* True if attempting to insert into a view */
  Trigger *pTrigger;          /* List of triggers on pTab, if required */
  int tmask;                  /* Mask of trigger times */
#endif

................................................................................
  */
  if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
    assert( !pTrigger );
    assert( pList==0 );
    goto insert_end;
  }
#endif /* SQLITE4_OMIT_XFER_OPT */

  /* If this is an AUTOINCREMENT table, look up the sequence number in the
  ** sqlite_sequence table and store it in memory cell regAutoinc.
  */
  regAutoinc = autoIncBegin(pParse, iDb, pTab);

  /* Figure out how many columns of data are supplied.  If the data
  ** is coming from a SELECT statement, then generate a co-routine that
  ** produces a single row of the SELECT on each invocation.  The
  ** co-routine is the common header to the 3rd and 4th templates.
  */
  if( pSelect ){
................................................................................
    regRowid++;
    pParse->nMem++;
  }

  endOfLoop = sqlite4VdbeMakeLabel(v);

  for(i=0; i<pTab->nCol; i++){
    int regDest = regContent+i;
    j = i;
    if( pColumn ){
      for(j=0; j<pColumn->nId; j++){
        if( pColumn->a[j].idx==i ) break;
      }
    }

    if( nColumn==0 || (pColumn && j>=pColumn->nId) ){
      sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regDest);
    }else if( useTempTable ){
      sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, regDest);
    }else if( pSelect ){
      sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+j, regDest);
    }else{
      assert( pSelect==0 ); /* Otherwise useTempTable is true */
      sqlite4ExprCodeAndCache(pParse, pList->a[j].pExpr, regDest);






    }
  }

  if( !isView ){
    sqlite4VdbeAddOp2(v, OP_Affinity, regContent, pTab->nCol);
    sqlite4TableAffinityStr(v, pTab);
  }
................................................................................
    sqlite4VdbeAddOp2(v, OP_Integer, -1, regRowid);
    VdbeComment((v, "new.rowid value for BEFORE triggers"));
    sqlite4CodeRowTrigger(
        pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
        pTab, (regRowid - pTab->nCol - 1), onError, endOfLoop
    );
  }

  if( iIntPKCol>=0 ){
    int regDest = regContent+iIntPKCol;
    int a1;
    a1 = sqlite4VdbeAddOp1(v, OP_NotNull, regDest);
    sqlite4VdbeAddOp3(v, OP_NewRowid, baseCur, regDest, regAutoinc);
    sqlite4VdbeJumpHere(v, a1);
    autoIncStep(pParse, regAutoinc, regDest);
  }

  if( bImplicitPK ){
    assert( !isView );
    sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur+iPk, regRowid);
  }

  if( !isView ){

Changes to src/vdbe.c.

460
461
462
463
464
465
466












467
468
469
470
471
472
473
....
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245




3246
3247
3248
3249
3250
3251
3252
....
3290
3291
3292
3293
3294
3295
3296













3297
3298
3299
3300
3301
3302
3303
....
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281

4282
4283
4284
4285

4286
4287
4288
4289
4290
4291
4292
  sqlite4 *db = p->db;
  sqlite4DbFree(db, p->zErrMsg);
  p->zErrMsg = sqlite4DbStrDup(db, pVtab->zErrMsg);
  sqlite4_free(db->pEnv, pVtab->zErrMsg);
  pVtab->zErrMsg = 0;
}














/*
** Execute as much of a VDBE program as we can then return.
**
** sqlite4VdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
  break;
}


/* Opcode: NewRowid P1 P2 * * *
**
** Get a new integer primary key (a.k.a "rowid") for table P1.  The integer
** should not be currently in use as a primary key on that table.




*/
case OP_NewRowid: {           /* out2-prerelease */
  i64 v;                   /* The new rowid */
  VdbeCursor *pC;          /* Cursor of table to get the new rowid */
  const KVByteArray *aKey; /* Key of an existing row */
  KVSize nKey;             /* Size of the existing row key */
  int n;                   /* Number of bytes decoded */
................................................................................
    if( rc==SQLITE4_OK ){
      n = sqlite4VdbeDecodeIntKey(&aKey[n], nKey-n, &v);
      if( n==0 || v==LARGEST_INT64 ) rc = SQLITE4_FULL;
    }
  }else{
    break;
  }













  pOut->flags = MEM_Int;
  pOut->u.i = v+1;
  break;
}

/* Opcode: NewIdxid P1 P2 * * *
**
................................................................................
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: {        /* in2 */
  Mem *pIn1;
  VdbeFrame *pFrame;
  if( p->pFrame ){
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    pIn1 = &pFrame->aMem[pOp->p1];
  }else{
    pIn1 = &aMem[pOp->p1];
  }
  assert( memIsValid(pIn1) );
  sqlite4VdbeMemIntegerify(pIn1);
  pIn2 = &aMem[pOp->p2];

  sqlite4VdbeMemIntegerify(pIn2);
  if( pIn1->u.i<pIn2->u.i){
    pIn1->u.i = pIn2->u.i;
  }

  break;
}
#endif /* SQLITE4_OMIT_AUTOINCREMENT */

/* Opcode: IfPos P1 P2 * * *
**
** If the value of register P1 is 1 or greater, jump to P2.







>
>
>
>
>
>
>
>
>
>
>
>







 







|



>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<
<
<
<
<



>




>







460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
....
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
....
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
....
4295
4296
4297
4298
4299
4300
4301
4302





4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
  sqlite4 *db = p->db;
  sqlite4DbFree(db, p->zErrMsg);
  p->zErrMsg = sqlite4DbStrDup(db, pVtab->zErrMsg);
  sqlite4_free(db->pEnv, pVtab->zErrMsg);
  pVtab->zErrMsg = 0;
}

/*
** Return a pointer to a register in the root frame.
*/
static Mem *sqlite4RegisterInRootFrame(Vdbe *p, int i){
  if( p->pFrame ){
    VdbeFrame *pFrame;
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
    return &pFrame->aMem[i];
  }else{
    return &p->aMem[i];
  }
}

/*
** Execute as much of a VDBE program as we can then return.
**
** sqlite4VdbeMakeReady() must be called before this routine in order to
** close the program with a final OP_Halt and to set up the callbacks
** and the error message pointer.
................................................................................
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( p->apCsr[pOp->p1]!=0 );
  pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
  break;
}


/* Opcode: NewRowid P1 P2 P3 * *
**
** Get a new integer primary key (a.k.a "rowid") for table P1.  The integer
** should not be currently in use as a primary key on that table.
**
** If P3 is not zero, then it is the number of a register in the top-level
** frame that holds a lower bound for the new rowid.  In other words, the
** new rowid must be no less than reg[P3]+1.
*/
case OP_NewRowid: {           /* out2-prerelease */
  i64 v;                   /* The new rowid */
  VdbeCursor *pC;          /* Cursor of table to get the new rowid */
  const KVByteArray *aKey; /* Key of an existing row */
  KVSize nKey;             /* Size of the existing row key */
  int n;                   /* Number of bytes decoded */
................................................................................
    if( rc==SQLITE4_OK ){
      n = sqlite4VdbeDecodeIntKey(&aKey[n], nKey-n, &v);
      if( n==0 || v==LARGEST_INT64 ) rc = SQLITE4_FULL;
    }
  }else{
    break;
  }
#ifndef SQLITE_OMIT_AUTOINCREMENT
  if( pOp->p3 && rc==SQLITE4_OK ){
    pIn3 = sqlite4RegisterInRootFrame(p, pOp->p3);
    assert( memIsValid(pIn3) );
    REGISTER_TRACE(pOp->p3, pIn3);
    sqlite4VdbeMemIntegerify(pIn3);
    assert( (pIn3->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
    if( pIn3->u.i==MAX_ROWID ){
      rc = SQLITE4_FULL;
    }
    if( v<pIn3->u.i ) v = pIn3->u.i;
  }
#endif
  pOut->flags = MEM_Int;
  pOut->u.i = v+1;
  break;
}

/* Opcode: NewIdxid P1 P2 * * *
**
................................................................................
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: {        /* in2 */
  Mem *pIn1;
  VdbeFrame *pFrame;
  pIn1 = sqlite4RegisterInRootFrame(p, pOp->p1);





  assert( memIsValid(pIn1) );
  sqlite4VdbeMemIntegerify(pIn1);
  pIn2 = &aMem[pOp->p2];
  REGISTER_TRACE(pOp->p1, pIn1);
  sqlite4VdbeMemIntegerify(pIn2);
  if( pIn1->u.i<pIn2->u.i){
    pIn1->u.i = pIn2->u.i;
  }
  REGISTER_TRACE(pOp->p1, pIn1);
  break;
}
#endif /* SQLITE4_OMIT_AUTOINCREMENT */

/* Opcode: IfPos P1 P2 * * *
**
** If the value of register P1 is 1 or greater, jump to P2.