/ Check-in [b21d831b]
Login

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

Overview
Comment:Some inserts and queries working for multi-column primary keys and WITHOUT ROWID.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | omit-rowid
Files: files | file ages | folders
SHA1: b21d831b2aa55507dd9def2acb02cdbffddf10d1
User & Date: drh 2013-10-23 13:30:58
Context
2013-10-23
16:03
Get VACUUM and the xfer optimization working with WITHOUT ROWID. check-in: 579815ff user: drh tags: omit-rowid
13:30
Some inserts and queries working for multi-column primary keys and WITHOUT ROWID. check-in: b21d831b user: drh tags: omit-rowid
01:57
Some simple inserts and queries working on WITHOUT ROWID tables. check-in: 3f8016de user: drh tags: omit-rowid
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

  4023   4023   ** the caller is responsible for calling sqlite3DbFree(db, ) on the returned 
  4024   4024   ** pointer. If an error occurs (out of memory or missing collation 
  4025   4025   ** sequence), NULL is returned and the state of pParse updated to reflect
  4026   4026   ** the error.
  4027   4027   */
  4028   4028   KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
  4029   4029     int i;
  4030         -  int nCol = pIdx->nKeyCol;
         4030  +  int nCol = pIdx->nColumn;
         4031  +  int nKey = pIdx->nKeyCol;
  4031   4032     KeyInfo *pKey;
  4032   4033   
  4033         -  pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
         4034  +  pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
  4034   4035     if( pKey ){
  4035   4036       for(i=0; i<nCol; i++){
  4036   4037         char *zColl = pIdx->azColl[i];
  4037         -      assert( zColl );
         4038  +      if( zColl==0 ) zColl = "BINARY";
  4038   4039         pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
  4039   4040         pKey->aSortOrder[i] = pIdx->aSortOrder[i];
  4040   4041       }
  4041   4042     }
  4042   4043   
  4043   4044     if( pParse->nErr ){
  4044   4045       sqlite3DbFree(pParse->db, pKey);
  4045   4046       pKey = 0;
  4046   4047     }
  4047   4048     return pKey;
  4048   4049   }

Changes to src/expr.c.

  1724   1724         ** if either column has NUMERIC or INTEGER affinity. If neither
  1725   1725         ** 'x' nor the SELECT... statement are columns, then numeric affinity
  1726   1726         ** is used.
  1727   1727         */
  1728   1728         pExpr->iTable = pParse->nTab++;
  1729   1729         addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
  1730   1730         if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
  1731         -      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);
         1731  +      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1);
  1732   1732   
  1733   1733         if( ExprHasProperty(pExpr, EP_xIsSelect) ){
  1734   1734           /* Case 1:     expr IN (SELECT ...)
  1735   1735           **
  1736   1736           ** Generate code to write the results of the select into the temporary
  1737   1737           ** table allocated and opened above.
  1738   1738           */

Changes to src/insert.c.

    65     65       ** The column affinity string will eventually be deleted by
    66     66       ** sqliteDeleteIndex() when the Index structure itself is cleaned
    67     67       ** up.
    68     68       */
    69     69       int n;
    70     70       Table *pTab = pIdx->pTable;
    71     71       sqlite3 *db = sqlite3VdbeDb(v);
    72         -    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nKeyCol+2);
           72  +    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
    73     73       if( !pIdx->zColAff ){
    74     74         db->mallocFailed = 1;
    75     75         return 0;
    76     76       }
    77         -    for(n=0; n<pIdx->nKeyCol; n++){
    78         -      pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
           77  +    for(n=0; n<pIdx->nColumn; n++){
           78  +      i16 x = pIdx->aiColumn[n];
           79  +      pIdx->zColAff[n] = x<0 ? SQLITE_AFF_INTEGER : pTab->aCol[x].affinity;
    79     80       }
    80         -    pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;
    81     81       pIdx->zColAff[n] = 0;
    82     82     }
    83     83    
    84     84     return pIdx->zColAff;
    85     85   }
    86     86   
    87     87   /*

Changes to src/select.c.

   799    799     */
   800    800     if( pOrderBy==0 && p->iLimit ){
   801    801       sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
   802    802     }
   803    803   }
   804    804   
   805    805   /*
   806         -** Allocate a KeyInfo object sufficient for an index of N columns.
          806  +** Allocate a KeyInfo object sufficient for an index of N key columns and
          807  +** X extra columns.
   807    808   **
   808    809   ** Actually, always allocate one extra column for the rowid at the end
   809    810   ** of the index.  So the KeyInfo returned will have space sufficient for
   810    811   ** N+1 columns.
   811    812   */
   812         -KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
          813  +KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
   813    814     KeyInfo *p = sqlite3DbMallocZero(db, 
   814         -                   sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
          815  +                   sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1));
   815    816     if( p ){
   816         -    p->aSortOrder = (u8*)&p->aColl[N+1];
          817  +    p->aSortOrder = (u8*)&p->aColl[N+X];
   817    818       p->nField = (u16)N;
          819  +    p->nXField = (u16)X;
   818    820       p->enc = ENC(db);
   819    821       p->db = db;
   820    822     }
   821    823     return p;
   822    824   }
   823    825   
   824    826   /*
................................................................................
   840    842     int nExpr;
   841    843     KeyInfo *pInfo;
   842    844     struct ExprList_item *pItem;
   843    845     sqlite3 *db = pParse->db;
   844    846     int i;
   845    847   
   846    848     nExpr = pList->nExpr;
   847         -  pInfo = sqlite3KeyInfoAlloc(db, nExpr);
          849  +  pInfo = sqlite3KeyInfoAlloc(db, nExpr, 1);
   848    850     if( pInfo ){
   849    851       for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
   850    852         CollSeq *pColl;
   851    853         pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
   852    854         if( !pColl ) pColl = db->pDfltColl;
   853    855         pInfo->aColl[i] = pColl;
   854    856         pInfo->aSortOrder[i] = pItem->sortOrder;
................................................................................
  1984   1986       KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
  1985   1987       Select *pLoop;                /* For looping through SELECT statements */
  1986   1988       CollSeq **apColl;             /* For looping through pKeyInfo->aColl[] */
  1987   1989       int nCol;                     /* Number of columns in result set */
  1988   1990   
  1989   1991       assert( p->pRightmost==p );
  1990   1992       nCol = p->pEList->nExpr;
  1991         -    pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
         1993  +    pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
  1992   1994       if( !pKeyInfo ){
  1993   1995         rc = SQLITE_NOMEM;
  1994   1996         goto multi_select_end;
  1995   1997       }
  1996   1998       for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
  1997   1999         *apColl = multiSelectCollSeq(pParse, p, i);
  1998   2000         if( 0==*apColl ){
................................................................................
  2363   2365     aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
  2364   2366     if( aPermute ){
  2365   2367       struct ExprList_item *pItem;
  2366   2368       for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
  2367   2369         assert( pItem->iOrderByCol>0  && pItem->iOrderByCol<=p->pEList->nExpr );
  2368   2370         aPermute[i] = pItem->iOrderByCol - 1;
  2369   2371       }
  2370         -    pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
         2372  +    pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1);
  2371   2373       if( pKeyMerge ){
  2372   2374         for(i=0; i<nOrderBy; i++){
  2373   2375           CollSeq *pColl;
  2374   2376           Expr *pTerm = pOrderBy->a[i].pExpr;
  2375   2377           if( pTerm->flags & EP_Collate ){
  2376   2378             pColl = sqlite3ExprCollSeq(pParse, pTerm);
  2377   2379           }else{
................................................................................
  2401   2403       regPrev = 0;
  2402   2404     }else{
  2403   2405       int nExpr = p->pEList->nExpr;
  2404   2406       assert( nOrderBy>=nExpr || db->mallocFailed );
  2405   2407       regPrev = pParse->nMem+1;
  2406   2408       pParse->nMem += nExpr+1;
  2407   2409       sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
  2408         -    pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
         2410  +    pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1);
  2409   2411       if( pKeyDup ){
  2410   2412         for(i=0; i<nExpr; i++){
  2411   2413           pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
  2412   2414           pKeyDup->aSortOrder[i] = 0;
  2413   2415         }
  2414   2416       }
  2415   2417     }
................................................................................
  4650   4652           }
  4651   4653           if( pBest ){
  4652   4654             iRoot = pBest->tnum;
  4653   4655             pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
  4654   4656           }
  4655   4657   
  4656   4658           /* Open a read-only cursor, execute the OP_Count, close the cursor. */
  4657         -        sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb);
         4659  +        sqlite3VdbeAddOp4(v, OP_OpenRead, iCsr, iRoot, iDb, 
         4660  +              SQLITE_INT_TO_PTR(1), P4_INT32);
  4658   4661           if( pKeyInfo ){
  4659   4662             sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
  4660   4663           }
  4661   4664           sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
  4662   4665           sqlite3VdbeAddOp1(v, OP_Close, iCsr);
  4663   4666           explainSimpleCount(pParse, pTab, pBest);
  4664   4667         }else

Changes to src/sqliteInt.h.

  1514   1514   ** Note that aSortOrder[] and aColl[] have nField+1 slots.  There
  1515   1515   ** are nField slots for the columns of an index then one extra slot
  1516   1516   ** for the rowid at the end.
  1517   1517   */
  1518   1518   struct KeyInfo {
  1519   1519     sqlite3 *db;        /* The database connection */
  1520   1520     u8 enc;             /* Text encoding - one of the SQLITE_UTF* values */
  1521         -  u16 nField;         /* Maximum index for aColl[] and aSortOrder[] */
         1521  +  u16 nField;         /* Number of key columns in the index */
         1522  +  u16 nXField;         /* Number of columns beyond the key columns */
  1522   1523     u8 *aSortOrder;     /* Sort order for each column. */
  1523   1524     CollSeq *aColl[1];  /* Collating sequence for each term of the key */
  1524   1525   };
  1525   1526   
  1526   1527   /*
  1527   1528   ** An instance of the following structure holds information about a
  1528   1529   ** single index record that has already been parsed out into individual
................................................................................
  3135   3136   void sqlite3DefaultRowEst(Index*);
  3136   3137   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  3137   3138   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
  3138   3139   void sqlite3MinimumFileFormat(Parse*, int, int);
  3139   3140   void sqlite3SchemaClear(void *);
  3140   3141   Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
  3141   3142   int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
  3142         -KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
         3143  +KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
  3143   3144   KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
  3144   3145   int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
  3145   3146     void (*)(sqlite3_context*,int,sqlite3_value **),
  3146   3147     void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
  3147   3148     FuncDestructor *pDestructor
  3148   3149   );
  3149   3150   int sqlite3ApiExit(sqlite3 *db, int);

Changes to src/vdbe.c.

  3214   3214         rc = SQLITE_CORRUPT_BKPT;
  3215   3215         goto abort_due_to_error;
  3216   3216       }
  3217   3217     }
  3218   3218     if( pOp->p4type==P4_KEYINFO ){
  3219   3219       pKeyInfo = pOp->p4.pKeyInfo;
  3220   3220       pKeyInfo->enc = ENC(p->db);
  3221         -    nField = pKeyInfo->nField+1;
         3221  +    nField = pKeyInfo->nField+pKeyInfo->nXField;
  3222   3222     }else if( pOp->p4type==P4_INT32 ){
  3223   3223       nField = pOp->p4.i;
  3224   3224     }
  3225   3225     assert( pOp->p1>=0 );
  3226   3226     pCur = allocateCursor(p, pOp->p1, nField, iDb, 1);
  3227   3227     if( pCur==0 ) goto no_mem;
  3228   3228     pCur->nullRow = 1;

Changes to src/vdbeaux.c.

   748    748     }else if( zP4==0 ){
   749    749       pOp->p4.p = 0;
   750    750       pOp->p4type = P4_NOTUSED;
   751    751     }else if( n==P4_KEYINFO ){
   752    752       KeyInfo *pOrig, *pNew;
   753    753   
   754    754       pOrig = (KeyInfo*)zP4;
   755         -    pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
          755  +    pNew = sqlite3KeyInfoAlloc(db, pOrig->nField, pOrig->nXField);
          756  +    pOp->p4.pKeyInfo = pNew;
   756    757       if( pNew ){
   757         -      memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
   758         -      memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);
          758  +      int n = pOrig->nField+pOrig->nXField;
          759  +      memcpy(pNew->aColl, pOrig->aColl, n*sizeof(pNew->aColl[0]));
          760  +      memcpy(pNew->aSortOrder, pOrig->aSortOrder, n);
   759    761         pOp->p4type = P4_KEYINFO;
   760    762       }else{
   761    763         p->db->mallocFailed = 1;
   762    764         pOp->p4type = P4_NOTUSED;
   763    765       }
   764    766     }else if( n==P4_KEYINFO_HANDOFF ){
   765    767       pOp->p4.p = (void*)zP4;

Changes to test/alter.test.

   859    859       catchsql "ALTER TABLE $tbl ADD COLUMN xyz"
   860    860     } [list 1 "table $tbl may not be altered"]
   861    861   }
   862    862   
   863    863   #------------------------------------------------------------------------
   864    864   # Verify that ALTER TABLE works on tables with the WITHOUT rowid option.
   865    865   #
   866         -if 0 {
   867    866   do_execsql_test alter-16.1 {
   868    867     CREATE TABLE t16a(a TEXT, b REAL, c INT, PRIMARY KEY(a,b)) WITHOUT rowid;
   869    868     INSERT INTO t16a VALUES('abc',1.25,99);
   870    869     ALTER TABLE t16a ADD COLUMN d TEXT DEFAULT 'xyzzy';
   871    870     INSERT INTO t16a VALUES('cba',5.5,98,'fizzle');
   872    871     SELECT * FROM t16a ORDER BY a;
   873    872   } {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
   874    873   do_execsql_test alter-16.2 {
   875    874     ALTER TABLE t16a RENAME TO t16a_rn;
   876    875     SELECT * FROM t16a_rn ORDER BY a;
   877    876   } {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
   878         -}
   879    877   
   880    878   finish_test