Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -1525,11 +1525,11 @@ /* ** Set up a raw page so that it looks like a database page holding ** no entries. */ -static void zeroPage(MemPage *pPage, int flags){ +static void zeroPage(MemPage *pPage, u8 flags){ unsigned char *data = pPage->aData; BtShared *pBt = pPage->pBt; u8 hdr = pPage->hdrOffset; u16 first; @@ -2583,10 +2583,11 @@ */ static int newDatabase(BtShared *pBt){ MemPage *pP1; unsigned char *data; int rc; + u8 flags; assert( sqlite3_mutex_held(pBt->mutex) ); if( pBt->nPage>0 ){ return SQLITE_OK; } @@ -2605,11 +2606,13 @@ data[20] = (u8)(pBt->pageSize - pBt->usableSize); data[21] = 64; data[22] = 32; data[23] = 32; memset(&data[24], 0, 100-24); - zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); + flags = (pBt->openFlags&BTREE_SINGLE_INDEX) ? PTF_ZERODATA|PTF_LEAF + : PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF; + zeroPage(pP1, flags); pBt->btsFlags |= BTS_PAGESIZE_FIXED; #ifndef SQLITE_OMIT_AUTOVACUUM assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); put4byte(&data[36 + 4*4], pBt->autoVacuum); @@ -6107,11 +6110,11 @@ int nxDiv; /* Next divider slot in pParent->aCell[] */ int rc = SQLITE_OK; /* The return code */ u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ int usableSpace; /* Bytes in pPage beyond the header */ - int pageFlags; /* Value of pPage->aData[0] */ + u8 pageFlags; /* Value of pPage->aData[0] */ int subtotal; /* Subtotal of bytes in cells on one page */ int iSpace1 = 0; /* First unused byte of aSpace1[] */ int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ int szScratch; /* Size of scratch memory requested */ MemPage *apOld[NB]; /* pPage and up to two siblings */ @@ -7208,11 +7211,11 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ BtShared *pBt = p->pBt; MemPage *pRoot; Pgno pgnoRoot; int rc; - int ptfFlags; /* Page-type flage for the root page of new table */ + u8 ptfFlags; /* Page-type flage for the root page of new table */ assert( sqlite3BtreeHoldsMutex(p) ); assert( pBt->inTransaction==TRANS_WRITE ); assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); Index: src/btree.h ================================================================== --- src/btree.h +++ src/btree.h @@ -54,14 +54,15 @@ ** following values. ** ** NOTE: These values must match the corresponding PAGER_ values in ** pager.h. */ -#define BTREE_OMIT_JOURNAL 1 /* Do not create or use a rollback journal */ -#define BTREE_MEMORY 2 /* This is an in-memory DB */ -#define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ -#define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ +#define BTREE_OMIT_JOURNAL 0x01 /* Do not create or use a rollback journal */ +#define BTREE_MEMORY 0x02 /* This is an in-memory DB */ +#define BTREE_SINGLE 0x04 /* The file contains at most 1 b-tree */ +#define BTREE_UNORDERED 0x08 /* Use of a hash implementation is OK */ +#define BTREE_SINGLE_INDEX 0x10 /* File contains one index btree */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); int sqlite3BtreeSetPagerFlags(Btree*,unsigned); Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -3322,11 +3322,11 @@ ** indices in joins. */ case OP_OpenAutoindex: case OP_OpenEphemeral: { VdbeCursor *pCx; - KeyInfo *pKeyInfo; + int btreeFlags; static const int vfsFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | @@ -3335,38 +3335,25 @@ assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, - BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); + btreeFlags = BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5; + if( pOp->p4.pKeyInfo ) btreeFlags |= BTREE_SINGLE_INDEX; + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, btreeFlags, vfsFlags); if( rc==SQLITE_OK ){ rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); } - if( rc==SQLITE_OK ){ - /* If a transient index is required, create it by calling - ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before - ** opening it. If a transient table is required, just use the - ** automatically created table with root-page 1 (an BLOB_INTKEY table). - */ - if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ - int pgno; - assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); - if( rc==SQLITE_OK ){ - assert( pgno==MASTER_ROOT+1 ); - assert( pKeyInfo->db==db ); - assert( pKeyInfo->enc==ENC(db) ); - pCx->pKeyInfo = pKeyInfo; - rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor); - } - pCx->isTable = 0; - }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor); - pCx->isTable = 1; - } - } + assert( pOp->p4.pKeyInfo==0 || pOp->p4type==P4_KEYINFO ); + assert( pOp->p4.pKeyInfo==0 || pOp->p4.pKeyInfo->db==db ); + assert( pOp->p4.pKeyInfo==0 || pOp->p4.pKeyInfo->enc==ENC(db) ); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, pOp->p4.pKeyInfo, + pCx->pCursor); + } + pCx->pKeyInfo = pOp->p4.pKeyInfo; + pCx->isTable = pCx->pKeyInfo==0; pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); break; } /* Opcode: SorterOpen P1 * * P4 *