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 Side-by-Side Diffs Ignore Whitespace Patch

Changes to main.mk.

    63     63   TCCX =  $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) 
    64     64   TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
    65     65   TCCX += -I$(TOP)/ext/async
    66     66   
    67     67   TCPPX = g++ -Wall -g -I. -I$(TOP)/src $(OPTS)
    68     68   
    69     69   
    70         -LIBOBJ+= alter.o analyze.o attach.o auth.o \
           70  +LIBOBJ+= vdbe.o parse.o \
           71  +         alter.o analyze.o attach.o auth.o \
    71     72            build.o \
    72     73            callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
    73     74   	 fts5.o fts5func.o \
    74     75            func.o global.o hash.o \
    75     76            icu.o insert.o kv.o kvlsm.o kvmem.o legacy.o \
    76     77            lsm_ckpt.o lsm_file.o lsm_log.o lsm_main.o lsm_mem.o lsm_mutex.o \
    77     78            lsm_shared.o lsm_str.o lsm_sorted.o lsm_tree.o \
    78     79            lsm_unix.o lsm_varint.o \
    79     80            main.o malloc.o math.o mem0.o mem1.o mem2.o mem3.o mem5.o \
    80     81            mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
    81     82            opcodes.o os.o \
    82         -         parse.o pragma.o prepare.o printf.o \
           83  +         pragma.o prepare.o printf.o \
    83     84            random.o resolve.o rowset.o rtree.o select.o status.o \
    84     85            tokenize.o trigger.o \
    85     86            update.o util.o varint.o \
    86         -         vdbe.o vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
           87  +         vdbeapi.o vdbeaux.o vdbecodec.o vdbecursor.o \
    87     88            vdbemem.o vdbetrace.o \
    88     89            walker.o where.o utf.o
    89     90   
    90     91   # All of the source code files.
    91     92   #
    92     93   SRC = \
    93     94     $(TOP)/src/alter.c \

Changes to src/build.c.

  1073   1073         if( iCol<pTab->nCol ){
  1074   1074           pTab->aCol[iCol].isPrimKey = i+1;
  1075   1075           pTab->aCol[iCol].notNull = 1;
  1076   1076         }
  1077   1077       }
  1078   1078       if( pList->nExpr>1 ) iCol = -1;
  1079   1079     }
  1080         -  if( autoInc ){
  1081         -    sqlite4ErrorMsg(pParse, "AUTOINCREMENT not yet implemented");
  1082         -    goto primary_key_exit;
  1083         -  }
  1084   1080     pPk = sqlite4CreateIndex(
  1085   1081        pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0, 1
  1086   1082     );
  1087   1083   
  1088   1084     if( iCol>=0 && iCol<pTab->nCol
  1089   1085      && (zType = pTab->aCol[iCol].zType)!=0
  1090   1086      && sqlite4StrICmp(zType, "INTEGER")==0
  1091   1087      && sortOrder==SQLITE4_SO_ASC
  1092   1088      && pPk
  1093   1089     ){
  1094   1090       pPk->fIndex |= IDX_IntPK;
         1091  +    assert( autoInc==0 || autoInc==1 );
         1092  +    pTab->tabFlags |= (-autoInc)&TF_Autoincrement;
         1093  +  }else if( autoInc ){
         1094  +    sqlite4ErrorMsg(pParse, 
         1095  +        "AUTOINCREMENT permitted on INTEGER PRIMARY KEY ASC only");
  1095   1096     }
  1096   1097     pList = 0;
  1097   1098   
  1098   1099   primary_key_exit:
  1099   1100     sqlite4ExprListDelete(pParse->db, pList);
  1100   1101     return;
  1101   1102   }

Changes to src/insert.c.

    20     20   void sqlite4OpenTable(
    21     21     Parse *p,       /* Generate code into this VDBE */
    22     22     int iCur,       /* The cursor number of the table */
    23     23     int iDb,        /* The database index in sqlite4.aDb[] */
    24     24     Table *pTab,    /* The table to be opened */
    25     25     int opcode      /* OP_OpenRead or OP_OpenWrite */
    26     26   ){
    27         -  assert( 0 );
           27  +  Index *pPk = sqlite4FindPrimaryKey(pTab, 0);
           28  +  sqlite4OpenIndex(p, iCur, iDb, pPk, opcode);
    28     29   }
    29     30   
    30     31   /*
    31     32   ** Open VDBE cursor iCur to access index pIdx. pIdx is guaranteed to be
    32     33   ** a part of database iDb.
    33     34   */
    34     35   void sqlite4OpenIndex(
................................................................................
   244    245   **   (1)  Register to hold the name of the pTab table.
   245    246   **   (2)  Register to hold the maximum ROWID of pTab.
   246    247   **   (3)  Register to hold the rowid in sqlite_sequence of pTab
   247    248   **
   248    249   ** The 2nd register is the one that is returned.  That is all the
   249    250   ** insert routine needs to know about.
   250    251   */
   251         -/*static FIXME: make static when this function gets used. */ int autoIncBegin(
          252  +static int autoIncBegin(
   252    253     Parse *pParse,      /* Parsing context */
   253    254     int iDb,            /* Index of the database holding pTab */
   254    255     Table *pTab         /* The table we are writing to */
   255    256   ){
   256    257     int memId = 0;      /* Register holding maximum rowid */
   257    258     if( pTab->tabFlags & TF_Autoincrement ){
   258    259       Parse *pToplevel = sqlite4ParseToplevel(pParse);
................................................................................
   318    319   ** Update the maximum rowid for an autoincrement calculation.
   319    320   **
   320    321   ** This routine should be called when the top of the stack holds a
   321    322   ** new rowid that is about to be inserted.  If that new rowid is
   322    323   ** larger than the maximum rowid in the memId memory cell, then the
   323    324   ** memory cell is updated.  The stack is unchanged.
   324    325   */
   325         -/*static FIXME: make static when this function gets used. */ void autoIncStep(Parse *pParse, int memId, int regRowid){
          326  +static void autoIncStep(Parse *pParse, int memId, int regRowid){
   326    327     if( memId>0 ){
   327    328       sqlite4VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid);
   328    329     }
   329    330   }
   330    331   
   331    332   /*
   332    333   ** This routine generates the code needed to write autoincrement
................................................................................
   513    514     int addrInsTop = 0;   /* Jump to label "D" */
   514    515     int addrCont = 0;     /* Top of insert loop. Label "C" in templates 3 and 4 */
   515    516     int addrSelect = 0;   /* Address of coroutine that implements the SELECT */
   516    517     SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
   517    518     int iDb;              /* Index of database holding TABLE */
   518    519     Db *pDb;              /* The database containing table being inserted into */
   519    520     int appendFlag = 0;   /* True if the insert is likely to be an append */
          521  +  int iPk;              /* Cursor offset of PK index cursor */
          522  +  Index *pPk;           /* Primary key for table pTab */
          523  +  int iIntPKCol = -1;   /* Column of INTEGER PRIMARY KEY or -1 */
          524  +  int bImplicitPK;      /* True if table pTab has an implicit PK */
   520    525   
   521    526     /* Register allocations */
   522    527     int regFromSelect = 0;/* Base register for data coming from SELECT */
   523    528     int regEof = 0;       /* Register recording end of SELECT data */
   524    529     int *aRegIdx = 0;     /* One register allocated to each index */
   525         -
   526         -  int iPk;                        /* Cursor offset of PK index cursor */
   527         -  Index *pPk;                     /* Primary key for table pTab */
   528         -  int iIntPKCol = -1;             /* Column of INTEGER PRIMARY KEY or -1 */
   529         -  int bImplicitPK;                /* True if table pTab has an implicit PK */
   530         -  int regContent;                 /* First register in column value array */
   531         -  int regRowid;                   /* If bImplicitPK, register holding IPK */
   532         -
          530  +  int regContent;       /* First register in column value array */
          531  +  int regRowid;         /* If bImplicitPK, register holding IPK */
          532  +  int regAutoinc;       /* Register holding the AUTOINCREMENT counter */
   533    533   
   534    534   #ifndef SQLITE4_OMIT_TRIGGER
   535    535     int isView;                 /* True if attempting to insert into a view */
   536    536     Trigger *pTrigger;          /* List of triggers on pTab, if required */
   537    537     int tmask;                  /* Mask of trigger times */
   538    538   #endif
   539    539   
................................................................................
   625    625     */
   626    626     if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
   627    627       assert( !pTrigger );
   628    628       assert( pList==0 );
   629    629       goto insert_end;
   630    630     }
   631    631   #endif /* SQLITE4_OMIT_XFER_OPT */
          632  +
          633  +  /* If this is an AUTOINCREMENT table, look up the sequence number in the
          634  +  ** sqlite_sequence table and store it in memory cell regAutoinc.
          635  +  */
          636  +  regAutoinc = autoIncBegin(pParse, iDb, pTab);
   632    637   
   633    638     /* Figure out how many columns of data are supplied.  If the data
   634    639     ** is coming from a SELECT statement, then generate a co-routine that
   635    640     ** produces a single row of the SELECT on each invocation.  The
   636    641     ** co-routine is the common header to the 3rd and 4th templates.
   637    642     */
   638    643     if( pSelect ){
................................................................................
   856    861       regRowid++;
   857    862       pParse->nMem++;
   858    863     }
   859    864   
   860    865     endOfLoop = sqlite4VdbeMakeLabel(v);
   861    866   
   862    867     for(i=0; i<pTab->nCol; i++){
          868  +    int regDest = regContent+i;
   863    869       j = i;
   864    870       if( pColumn ){
   865    871         for(j=0; j<pColumn->nId; j++){
   866    872           if( pColumn->a[j].idx==i ) break;
   867    873         }
   868    874       }
   869    875   
   870    876       if( nColumn==0 || (pColumn && j>=pColumn->nId) ){
   871         -      sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regContent+i);
          877  +      sqlite4ExprCode(pParse, pTab->aCol[i].pDflt, regDest);
   872    878       }else if( useTempTable ){
   873         -      sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, regContent+i);
          879  +      sqlite4VdbeAddOp3(v, OP_Column, srcTab, j, regDest);
   874    880       }else if( pSelect ){
   875         -      sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+j, regContent+i);
          881  +      sqlite4VdbeAddOp2(v, OP_SCopy, regFromSelect+j, regDest);
   876    882       }else{
   877    883         assert( pSelect==0 ); /* Otherwise useTempTable is true */
   878         -      sqlite4ExprCodeAndCache(pParse, pList->a[j].pExpr, regContent+i);
   879         -    }
   880         -    if( i==iIntPKCol ){
   881         -      int a1;
   882         -      a1 = sqlite4VdbeAddOp1(v, OP_NotNull, regContent+i);
   883         -      sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur, regContent+i);
   884         -      sqlite4VdbeJumpHere(v, a1);
          884  +      sqlite4ExprCodeAndCache(pParse, pList->a[j].pExpr, regDest);
   885    885       }
   886    886     }
   887    887   
   888    888     if( !isView ){
   889    889       sqlite4VdbeAddOp2(v, OP_Affinity, regContent, pTab->nCol);
   890    890       sqlite4TableAffinityStr(v, pTab);
   891    891     }
................................................................................
   895    895       sqlite4VdbeAddOp2(v, OP_Integer, -1, regRowid);
   896    896       VdbeComment((v, "new.rowid value for BEFORE triggers"));
   897    897       sqlite4CodeRowTrigger(
   898    898           pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
   899    899           pTab, (regRowid - pTab->nCol - 1), onError, endOfLoop
   900    900       );
   901    901     }
          902  +
          903  +  if( iIntPKCol>=0 ){
          904  +    int regDest = regContent+iIntPKCol;
          905  +    int a1;
          906  +    a1 = sqlite4VdbeAddOp1(v, OP_NotNull, regDest);
          907  +    sqlite4VdbeAddOp3(v, OP_NewRowid, baseCur, regDest, regAutoinc);
          908  +    sqlite4VdbeJumpHere(v, a1);
          909  +    autoIncStep(pParse, regAutoinc, regDest);
          910  +  }
   902    911   
   903    912     if( bImplicitPK ){
   904    913       assert( !isView );
   905    914       sqlite4VdbeAddOp2(v, OP_NewRowid, baseCur+iPk, regRowid);
   906    915     }
   907    916   
   908    917     if( !isView ){

Changes to src/vdbe.c.

   460    460     sqlite4 *db = p->db;
   461    461     sqlite4DbFree(db, p->zErrMsg);
   462    462     p->zErrMsg = sqlite4DbStrDup(db, pVtab->zErrMsg);
   463    463     sqlite4_free(db->pEnv, pVtab->zErrMsg);
   464    464     pVtab->zErrMsg = 0;
   465    465   }
   466    466   
          467  +/*
          468  +** Return a pointer to a register in the root frame.
          469  +*/
          470  +static Mem *sqlite4RegisterInRootFrame(Vdbe *p, int i){
          471  +  if( p->pFrame ){
          472  +    VdbeFrame *pFrame;
          473  +    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
          474  +    return &pFrame->aMem[i];
          475  +  }else{
          476  +    return &p->aMem[i];
          477  +  }
          478  +}
   467    479   
   468    480   /*
   469    481   ** Execute as much of a VDBE program as we can then return.
   470    482   **
   471    483   ** sqlite4VdbeMakeReady() must be called before this routine in order to
   472    484   ** close the program with a final OP_Halt and to set up the callbacks
   473    485   ** and the error message pointer.
................................................................................
  3235   3247     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  3236   3248     assert( p->apCsr[pOp->p1]!=0 );
  3237   3249     pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
  3238   3250     break;
  3239   3251   }
  3240   3252   
  3241   3253   
  3242         -/* Opcode: NewRowid P1 P2 * * *
         3254  +/* Opcode: NewRowid P1 P2 P3 * *
  3243   3255   **
  3244   3256   ** Get a new integer primary key (a.k.a "rowid") for table P1.  The integer
  3245   3257   ** should not be currently in use as a primary key on that table.
         3258  +**
         3259  +** If P3 is not zero, then it is the number of a register in the top-level
         3260  +** frame that holds a lower bound for the new rowid.  In other words, the
         3261  +** new rowid must be no less than reg[P3]+1.
  3246   3262   */
  3247   3263   case OP_NewRowid: {           /* out2-prerelease */
  3248   3264     i64 v;                   /* The new rowid */
  3249   3265     VdbeCursor *pC;          /* Cursor of table to get the new rowid */
  3250   3266     const KVByteArray *aKey; /* Key of an existing row */
  3251   3267     KVSize nKey;             /* Size of the existing row key */
  3252   3268     int n;                   /* Number of bytes decoded */
................................................................................
  3290   3306       if( rc==SQLITE4_OK ){
  3291   3307         n = sqlite4VdbeDecodeIntKey(&aKey[n], nKey-n, &v);
  3292   3308         if( n==0 || v==LARGEST_INT64 ) rc = SQLITE4_FULL;
  3293   3309       }
  3294   3310     }else{
  3295   3311       break;
  3296   3312     }
         3313  +#ifndef SQLITE_OMIT_AUTOINCREMENT
         3314  +  if( pOp->p3 && rc==SQLITE4_OK ){
         3315  +    pIn3 = sqlite4RegisterInRootFrame(p, pOp->p3);
         3316  +    assert( memIsValid(pIn3) );
         3317  +    REGISTER_TRACE(pOp->p3, pIn3);
         3318  +    sqlite4VdbeMemIntegerify(pIn3);
         3319  +    assert( (pIn3->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
         3320  +    if( pIn3->u.i==MAX_ROWID ){
         3321  +      rc = SQLITE4_FULL;
         3322  +    }
         3323  +    if( v<pIn3->u.i ) v = pIn3->u.i;
         3324  +  }
         3325  +#endif
  3297   3326     pOut->flags = MEM_Int;
  3298   3327     pOut->u.i = v+1;
  3299   3328     break;
  3300   3329   }
  3301   3330   
  3302   3331   /* Opcode: NewIdxid P1 P2 * * *
  3303   3332   **
................................................................................
  4266   4295   **
  4267   4296   ** This instruction throws an error if the memory cell is not initially
  4268   4297   ** an integer.
  4269   4298   */
  4270   4299   case OP_MemMax: {        /* in2 */
  4271   4300     Mem *pIn1;
  4272   4301     VdbeFrame *pFrame;
  4273         -  if( p->pFrame ){
  4274         -    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
  4275         -    pIn1 = &pFrame->aMem[pOp->p1];
  4276         -  }else{
  4277         -    pIn1 = &aMem[pOp->p1];
  4278         -  }
         4302  +  pIn1 = sqlite4RegisterInRootFrame(p, pOp->p1);
  4279   4303     assert( memIsValid(pIn1) );
  4280   4304     sqlite4VdbeMemIntegerify(pIn1);
  4281   4305     pIn2 = &aMem[pOp->p2];
         4306  +  REGISTER_TRACE(pOp->p1, pIn1);
  4282   4307     sqlite4VdbeMemIntegerify(pIn2);
  4283   4308     if( pIn1->u.i<pIn2->u.i){
  4284   4309       pIn1->u.i = pIn2->u.i;
  4285   4310     }
         4311  +  REGISTER_TRACE(pOp->p1, pIn1);
  4286   4312     break;
  4287   4313   }
  4288   4314   #endif /* SQLITE4_OMIT_AUTOINCREMENT */
  4289   4315   
  4290   4316   /* Opcode: IfPos P1 P2 * * *
  4291   4317   **
  4292   4318   ** If the value of register P1 is 1 or greater, jump to P2.