/ Check-in [a332908b]
Login

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

Overview
Comment:Make the root page of an ephemeral index be page 1 instead of page 2.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | subquery-codegen-refactor
Files: files | file ages | folders
SHA1: a332908b70afa4e77e60b30a3b96d8a8504363a2
User & Date: drh 2014-02-05 17:08:07
Context
2014-02-05
18:15
Use a new opcode, OP_OpenHash, to indicate that ephemeral tables can be unordered, rather than using the BTREE_UNORDERED bit in the P5 field. check-in: 2997e181 user: drh tags: subquery-codegen-refactor
17:08
Make the root page of an ephemeral index be page 1 instead of page 2. check-in: a332908b user: drh tags: subquery-codegen-refactor
11:05
In the Win32 VFS, the winSysInfo variable should be static. check-in: 4a4dd371 user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  1523   1523     return SQLITE_OK;
  1524   1524   }
  1525   1525   
  1526   1526   /*
  1527   1527   ** Set up a raw page so that it looks like a database page holding
  1528   1528   ** no entries.
  1529   1529   */
  1530         -static void zeroPage(MemPage *pPage, int flags){
         1530  +static void zeroPage(MemPage *pPage, u8 flags){
  1531   1531     unsigned char *data = pPage->aData;
  1532   1532     BtShared *pBt = pPage->pBt;
  1533   1533     u8 hdr = pPage->hdrOffset;
  1534   1534     u16 first;
  1535   1535   
  1536   1536     assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno );
  1537   1537     assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
................................................................................
  2581   2581   ** into a new empty database by initializing the first page of
  2582   2582   ** the database.
  2583   2583   */
  2584   2584   static int newDatabase(BtShared *pBt){
  2585   2585     MemPage *pP1;
  2586   2586     unsigned char *data;
  2587   2587     int rc;
         2588  +  u8 flags;
  2588   2589   
  2589   2590     assert( sqlite3_mutex_held(pBt->mutex) );
  2590   2591     if( pBt->nPage>0 ){
  2591   2592       return SQLITE_OK;
  2592   2593     }
  2593   2594     pP1 = pBt->pPage1;
  2594   2595     assert( pP1!=0 );
................................................................................
  2603   2604     data[19] = 1;
  2604   2605     assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
  2605   2606     data[20] = (u8)(pBt->pageSize - pBt->usableSize);
  2606   2607     data[21] = 64;
  2607   2608     data[22] = 32;
  2608   2609     data[23] = 32;
  2609   2610     memset(&data[24], 0, 100-24);
  2610         -  zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
         2611  +  flags = (pBt->openFlags&BTREE_SINGLE_INDEX) ? PTF_ZERODATA|PTF_LEAF
         2612  +                                              : PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF;
         2613  +  zeroPage(pP1, flags);
  2611   2614     pBt->btsFlags |= BTS_PAGESIZE_FIXED;
  2612   2615   #ifndef SQLITE_OMIT_AUTOVACUUM
  2613   2616     assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 );
  2614   2617     assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 );
  2615   2618     put4byte(&data[36 + 4*4], pBt->autoVacuum);
  2616   2619     put4byte(&data[36 + 7*4], pBt->incrVacuum);
  2617   2620   #endif
................................................................................
  6105   6108     int nOld;                    /* Number of pages in apOld[] */
  6106   6109     int i, j, k;                 /* Loop counters */
  6107   6110     int nxDiv;                   /* Next divider slot in pParent->aCell[] */
  6108   6111     int rc = SQLITE_OK;          /* The return code */
  6109   6112     u16 leafCorrection;          /* 4 if pPage is a leaf.  0 if not */
  6110   6113     int leafData;                /* True if pPage is a leaf of a LEAFDATA tree */
  6111   6114     int usableSpace;             /* Bytes in pPage beyond the header */
  6112         -  int pageFlags;               /* Value of pPage->aData[0] */
         6115  +  u8 pageFlags;                /* Value of pPage->aData[0] */
  6113   6116     int subtotal;                /* Subtotal of bytes in cells on one page */
  6114   6117     int iSpace1 = 0;             /* First unused byte of aSpace1[] */
  6115   6118     int iOvflSpace = 0;          /* First unused byte of aOvflSpace[] */
  6116   6119     int szScratch;               /* Size of scratch memory requested */
  6117   6120     MemPage *apOld[NB];          /* pPage and up to two siblings */
  6118   6121     MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
  6119   6122     MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
................................................................................
  7206   7209   **     BTREE_ZERODATA                  Used for SQL indices
  7207   7210   */
  7208   7211   static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
  7209   7212     BtShared *pBt = p->pBt;
  7210   7213     MemPage *pRoot;
  7211   7214     Pgno pgnoRoot;
  7212   7215     int rc;
  7213         -  int ptfFlags;          /* Page-type flage for the root page of new table */
         7216  +  u8 ptfFlags;          /* Page-type flage for the root page of new table */
  7214   7217   
  7215   7218     assert( sqlite3BtreeHoldsMutex(p) );
  7216   7219     assert( pBt->inTransaction==TRANS_WRITE );
  7217   7220     assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  7218   7221   
  7219   7222   #ifdef SQLITE_OMIT_AUTOVACUUM
  7220   7223     rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0);

Changes to src/btree.h.

    52     52   
    53     53   /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
    54     54   ** following values.
    55     55   **
    56     56   ** NOTE:  These values must match the corresponding PAGER_ values in
    57     57   ** pager.h.
    58     58   */
    59         -#define BTREE_OMIT_JOURNAL  1  /* Do not create or use a rollback journal */
    60         -#define BTREE_MEMORY        2  /* This is an in-memory DB */
    61         -#define BTREE_SINGLE        4  /* The file contains at most 1 b-tree */
    62         -#define BTREE_UNORDERED     8  /* Use of a hash implementation is OK */
           59  +#define BTREE_OMIT_JOURNAL  0x01  /* Do not create or use a rollback journal */
           60  +#define BTREE_MEMORY        0x02  /* This is an in-memory DB */
           61  +#define BTREE_SINGLE        0x04  /* The file contains at most 1 b-tree */
           62  +#define BTREE_UNORDERED     0x08  /* Use of a hash implementation is OK */
           63  +#define BTREE_SINGLE_INDEX  0x10  /* File contains one index btree */
    63     64   
    64     65   int sqlite3BtreeClose(Btree*);
    65     66   int sqlite3BtreeSetCacheSize(Btree*,int);
    66     67   int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
    67     68   int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
    68     69   int sqlite3BtreeSyncDisabled(Btree*);
    69     70   int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);

Changes to src/vdbe.c.

  3320   3320   ** different name to distinguish its use.  Tables created using
  3321   3321   ** by this opcode will be used for automatically created transient
  3322   3322   ** indices in joins.
  3323   3323   */
  3324   3324   case OP_OpenAutoindex: 
  3325   3325   case OP_OpenEphemeral: {
  3326   3326     VdbeCursor *pCx;
  3327         -  KeyInfo *pKeyInfo;
         3327  +  int btreeFlags;
  3328   3328   
  3329   3329     static const int vfsFlags = 
  3330   3330         SQLITE_OPEN_READWRITE |
  3331   3331         SQLITE_OPEN_CREATE |
  3332   3332         SQLITE_OPEN_EXCLUSIVE |
  3333   3333         SQLITE_OPEN_DELETEONCLOSE |
  3334   3334         SQLITE_OPEN_TRANSIENT_DB;
  3335   3335     assert( pOp->p1>=0 );
  3336   3336     assert( pOp->p2>=0 );
  3337   3337     pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  3338   3338     if( pCx==0 ) goto no_mem;
  3339   3339     pCx->nullRow = 1;
  3340         -  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, 
  3341         -                        BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
         3340  +  btreeFlags = BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5;
         3341  +  if( pOp->p4.pKeyInfo ) btreeFlags |= BTREE_SINGLE_INDEX;
         3342  +  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt, btreeFlags, vfsFlags);
  3342   3343     if( rc==SQLITE_OK ){
  3343   3344       rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
  3344   3345     }
         3346  +  assert( pOp->p4.pKeyInfo==0 || pOp->p4type==P4_KEYINFO );
         3347  +  assert( pOp->p4.pKeyInfo==0 || pOp->p4.pKeyInfo->db==db );
         3348  +  assert( pOp->p4.pKeyInfo==0 || pOp->p4.pKeyInfo->enc==ENC(db) );
  3345   3349     if( rc==SQLITE_OK ){
  3346         -    /* If a transient index is required, create it by calling
  3347         -    ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
  3348         -    ** opening it. If a transient table is required, just use the
  3349         -    ** automatically created table with root-page 1 (an BLOB_INTKEY table).
  3350         -    */
  3351         -    if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
  3352         -      int pgno;
  3353         -      assert( pOp->p4type==P4_KEYINFO );
  3354         -      rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5); 
  3355         -      if( rc==SQLITE_OK ){
  3356         -        assert( pgno==MASTER_ROOT+1 );
  3357         -        assert( pKeyInfo->db==db );
  3358         -        assert( pKeyInfo->enc==ENC(db) );
  3359         -        pCx->pKeyInfo = pKeyInfo;
  3360         -        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor);
  3361         -      }
  3362         -      pCx->isTable = 0;
  3363         -    }else{
  3364         -      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
  3365         -      pCx->isTable = 1;
  3366         -    }
         3350  +    rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, pOp->p4.pKeyInfo,
         3351  +                            pCx->pCursor);
  3367   3352     }
         3353  +  pCx->pKeyInfo = pOp->p4.pKeyInfo;
         3354  +  pCx->isTable = pCx->pKeyInfo==0;
  3368   3355     pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
  3369   3356     break;
  3370   3357   }
  3371   3358   
  3372   3359   /* Opcode: SorterOpen P1 * * P4 *
  3373   3360   **
  3374   3361   ** This opcode works like OP_OpenEphemeral except that it opens