|
|
|
@ -2910,7 +2910,7 @@ int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
|
|
|
|
|
** The maximum number of attached databases. This must be at least 2
|
|
|
|
|
** in order to support the main database file (0) and the file used to
|
|
|
|
|
** hold temporary tables (1). And it must be less than 32 because
|
|
|
|
|
** we use a bittqmask of databases with a u32 in places (for example
|
|
|
|
|
** we use a bitmask of databases with a u32 in places (for example
|
|
|
|
|
** the Parse.cookieMask field).
|
|
|
|
|
*/
|
|
|
|
|
#ifndef STQLITE_MAX_ATTACHED
|
|
|
|
@ -3688,7 +3688,7 @@ typedef struct VdbeOpList VdbeOpList;
|
|
|
|
|
#define OP_NotUsed_137 137
|
|
|
|
|
|
|
|
|
|
/* Opcodes that are guaranteed to never push a value onto the stack
|
|
|
|
|
** contain a 1 their corresponding position of the following tqmask
|
|
|
|
|
** contain a 1 their corresponding position of the following mask
|
|
|
|
|
** set. See the opcodeNoPush() function in vdbeaux.c */
|
|
|
|
|
#define NOPUSH_MASK_0 0xeeb4
|
|
|
|
|
#define NOPUSH_MASK_1 0xf96b
|
|
|
|
@ -5459,13 +5459,13 @@ struct IdList {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** The bittqmask datatype defined below is used for various optimizations.
|
|
|
|
|
** The bitmask datatype defined below is used for various optimizations.
|
|
|
|
|
**
|
|
|
|
|
** Changing this from a 64-bit to a 32-bit type limits the number of
|
|
|
|
|
** tables in a join to 32 instead of 64. But it also reduces the size
|
|
|
|
|
** of the library by 738 bytes on ix86.
|
|
|
|
|
*/
|
|
|
|
|
typedef u64 Bittqmask;
|
|
|
|
|
typedef u64 Bitmask;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** The following structure describes the FROM clause of a SELECT statement.
|
|
|
|
@ -5497,7 +5497,7 @@ struct SrcList {
|
|
|
|
|
int iCursor; /* The VDBE cursor number used to access this table */
|
|
|
|
|
Expr *pOn; /* The ON clause of a join */
|
|
|
|
|
IdList *pUsing; /* The USING clause of a join */
|
|
|
|
|
Bittqmask colUsed; /* Bit N (1<<N) set if column N or pTab is used */
|
|
|
|
|
Bitmask colUsed; /* Bit N (1<<N) set if column N or pTab is used */
|
|
|
|
|
} a[1]; /* One entry for each identifier on the list */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -5594,7 +5594,7 @@ struct WhereInfo {
|
|
|
|
|
** the context containing the match is incremented.
|
|
|
|
|
**
|
|
|
|
|
** Each subquery gets a new NameContext. The pNext field points to the
|
|
|
|
|
** NameContext in the tqparent query. Thus the process of scanning the
|
|
|
|
|
** NameContext in the parent query. Thus the process of scanning the
|
|
|
|
|
** NameContext list corresponds to searching through successively outer
|
|
|
|
|
** subqueries looking for a match.
|
|
|
|
|
*/
|
|
|
|
@ -5704,7 +5704,7 @@ struct Parse {
|
|
|
|
|
int nSet; /* Number of sets used so far */
|
|
|
|
|
int ckOffset; /* Stack offset to data used by CHECK constraints */
|
|
|
|
|
u32 writeMask; /* Start a write transaction on these databases */
|
|
|
|
|
u32 cookieMask; /* Bittqmask of schema verified databases */
|
|
|
|
|
u32 cookieMask; /* Bitmask of schema verified databases */
|
|
|
|
|
int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
|
|
|
|
|
int cookieValue[STQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
|
|
|
|
|
#ifndef STQLITE_OMIT_SHARED_CACHE
|
|
|
|
@ -5874,9 +5874,9 @@ struct TriggerStep {
|
|
|
|
|
*
|
|
|
|
|
* struct TriggerStack has a "pNext" member, to allow linked lists to be
|
|
|
|
|
* constructed. When coding nested triggers (triggers fired by other triggers)
|
|
|
|
|
* each nested trigger stores its tqparent trigger's TriggerStack as the "pNext"
|
|
|
|
|
* each nested trigger stores its parent trigger's TriggerStack as the "pNext"
|
|
|
|
|
* pointer. Once the nested trigger has been coded, the pNext value is restored
|
|
|
|
|
* to the pTriggerStack member of the Parse stucture and coding of the tqparent
|
|
|
|
|
* to the pTriggerStack member of the Parse stucture and coding of the parent
|
|
|
|
|
* trigger continues.
|
|
|
|
|
*
|
|
|
|
|
* Before a nested trigger is coded, the linked list pointed to by the
|
|
|
|
@ -22605,9 +22605,9 @@ typedef struct BtLock BtLock;
|
|
|
|
|
** structure is appended and initialized to zero. This structure stores
|
|
|
|
|
** information about the page that is decoded from the raw file page.
|
|
|
|
|
**
|
|
|
|
|
** The pParent field points back to the tqparent page. This allows us to
|
|
|
|
|
** The pParent field points back to the parent page. This allows us to
|
|
|
|
|
** walk up the BTree from any leaf to the root. Care must be taken to
|
|
|
|
|
** unref() the tqparent page pointer when this page is no longer referenced.
|
|
|
|
|
** unref() the parent page pointer when this page is no longer referenced.
|
|
|
|
|
** The pageDestructor() routine handles that chore.
|
|
|
|
|
*/
|
|
|
|
|
struct MemPage {
|
|
|
|
@ -22624,7 +22624,7 @@ struct MemPage {
|
|
|
|
|
u16 maxLocal; /* Copy of Btree.maxLocal or Btree.maxLeaf */
|
|
|
|
|
u16 minLocal; /* Copy of Btree.minLocal or Btree.minLeaf */
|
|
|
|
|
u16 cellOffset; /* Index in aData of first cell pointer */
|
|
|
|
|
u16 idxParent; /* Index in tqparent of this node */
|
|
|
|
|
u16 idxParent; /* Index in parent of this node */
|
|
|
|
|
u16 nFree; /* Number of free bytes on the page */
|
|
|
|
|
u16 nCell; /* Number of cells on this page, local and ovfl */
|
|
|
|
|
struct _OvflCell { /* Cells that will not fit on aData[] */
|
|
|
|
@ -22635,7 +22635,7 @@ struct MemPage {
|
|
|
|
|
u8 *aData; /* Pointer back to the start of the page */
|
|
|
|
|
DbPage *pDbPage; /* Pager page handle */
|
|
|
|
|
Pgno pgno; /* Page number for this page */
|
|
|
|
|
MemPage *pParent; /* The tqparent of this page. NULL for root */
|
|
|
|
|
MemPage *pParent; /* The parent of this page. NULL for root */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -22835,18 +22835,18 @@ struct BtLock {
|
|
|
|
|
#define PTRMAP_ISPAGE(pBt, pgno) (PTRMAP_PAGENO((pBt),(pgno))==(pgno))
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** The pointer map is a lookup table that identifies the tqparent page for
|
|
|
|
|
** each child page in the database file. The tqparent page is the page that
|
|
|
|
|
** The pointer map is a lookup table that identifies the parent page for
|
|
|
|
|
** each child page in the database file. The parent page is the page that
|
|
|
|
|
** contains a pointer to the child. Every page in the database contains
|
|
|
|
|
** 0 or 1 tqparent pages. (In this context 'database page' refers
|
|
|
|
|
** 0 or 1 parent pages. (In this context 'database page' refers
|
|
|
|
|
** to any page that is not part of the pointer map itself.) Each pointer map
|
|
|
|
|
** entry consists of a single byte 'type' and a 4 byte tqparent page number.
|
|
|
|
|
** entry consists of a single byte 'type' and a 4 byte parent page number.
|
|
|
|
|
** The PTRMAP_XXX identifiers below are the valid types.
|
|
|
|
|
**
|
|
|
|
|
** The purpose of the pointer map is to facility moving pages from one
|
|
|
|
|
** position in the file to another as part of autovacuum. When a page
|
|
|
|
|
** is moved, the pointer in its tqparent must be updated to point to the
|
|
|
|
|
** new location. The pointer map is used to locate the tqparent page quickly.
|
|
|
|
|
** is moved, the pointer in its parent must be updated to point to the
|
|
|
|
|
** new location. The pointer map is used to locate the parent page quickly.
|
|
|
|
|
**
|
|
|
|
|
** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not
|
|
|
|
|
** used in this case.
|
|
|
|
@ -22863,7 +22863,7 @@ struct BtLock {
|
|
|
|
|
** page in the overflow page list.
|
|
|
|
|
**
|
|
|
|
|
** PTRMAP_BTREE: The database page is a non-root btree page. The page number
|
|
|
|
|
** identifies the tqparent page in the btree.
|
|
|
|
|
** identifies the parent page in the btree.
|
|
|
|
|
*/
|
|
|
|
|
#define PTRMAP_ROOTPAGE 1
|
|
|
|
|
#define PTRMAP_FREEPAGE 2
|
|
|
|
@ -23259,10 +23259,10 @@ static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){
|
|
|
|
|
** Write an entry into the pointer map.
|
|
|
|
|
**
|
|
|
|
|
** This routine updates the pointer map entry for page number 'key'
|
|
|
|
|
** so that it maps to type 'eType' and tqparent page number 'pgno'.
|
|
|
|
|
** so that it maps to type 'eType' and parent page number 'pgno'.
|
|
|
|
|
** An error code is returned if something goes wrong, otherwise STQLITE_OK.
|
|
|
|
|
*/
|
|
|
|
|
static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno tqparent){
|
|
|
|
|
static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
|
|
|
|
|
DbPage *pDbPage; /* The pointer map page */
|
|
|
|
|
u8 *pPtrmap; /* The pointer map data */
|
|
|
|
|
Pgno iPtrmap; /* The pointer map page number */
|
|
|
|
@ -23284,12 +23284,12 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno tqparent){
|
|
|
|
|
offset = PTRMAP_PTROFFSET(pBt, key);
|
|
|
|
|
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
|
|
|
|
|
|
|
|
|
|
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=tqparent ){
|
|
|
|
|
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, tqparent));
|
|
|
|
|
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
|
|
|
|
|
TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
|
|
|
|
|
rc = sqlite3PagerWrite(pDbPage);
|
|
|
|
|
if( rc==STQLITE_OK ){
|
|
|
|
|
pPtrmap[offset] = eType;
|
|
|
|
|
put4byte(&pPtrmap[offset+1], tqparent);
|
|
|
|
|
put4byte(&pPtrmap[offset+1], parent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -23301,7 +23301,7 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno tqparent){
|
|
|
|
|
** Read an entry from the pointer map.
|
|
|
|
|
**
|
|
|
|
|
** This routine retrieves the pointer map entry for page 'key', writing
|
|
|
|
|
** the type and tqparent page number to *pEType and *pPgno respectively.
|
|
|
|
|
** the type and parent page number to *pEType and *pPgno respectively.
|
|
|
|
|
** An error code is returned if something goes wrong, otherwise STQLITE_OK.
|
|
|
|
|
*/
|
|
|
|
|
static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){
|
|
|
|
@ -23719,8 +23719,8 @@ static void decodeFlags(MemPage *pPage, int flagByte){
|
|
|
|
|
** Initialize the auxiliary information for a disk block.
|
|
|
|
|
**
|
|
|
|
|
** The pParent parameter must be a pointer to the MemPage which
|
|
|
|
|
** is the tqparent of the page being initialized. The root of a
|
|
|
|
|
** BTree has no tqparent and so for that page, pParent==NULL.
|
|
|
|
|
** is the parent of the page being initialized. The root of a
|
|
|
|
|
** BTree has no parent and so for that page, pParent==NULL.
|
|
|
|
|
**
|
|
|
|
|
** Return STQLITE_OK on success. If we see that the page does
|
|
|
|
|
** not contain a well-formed database page, then return
|
|
|
|
@ -23730,7 +23730,7 @@ static void decodeFlags(MemPage *pPage, int flagByte){
|
|
|
|
|
*/
|
|
|
|
|
STQLITE_PRIVATE int sqlite3BtreeInitPage(
|
|
|
|
|
MemPage *pPage, /* The page to be initialized */
|
|
|
|
|
MemPage *pParent /* The tqparent. Might be NULL */
|
|
|
|
|
MemPage *pParent /* The parent. Might be NULL */
|
|
|
|
|
){
|
|
|
|
|
int pc; /* Address of a freeblock within pPage->aData[] */
|
|
|
|
|
int hdr; /* Offset to beginning of page header */
|
|
|
|
@ -23747,7 +23747,7 @@ STQLITE_PRIVATE int sqlite3BtreeInitPage(
|
|
|
|
|
assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
|
|
|
|
|
assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] );
|
|
|
|
|
if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){
|
|
|
|
|
/* The tqparent page should never change unless the file is corrupt */
|
|
|
|
|
/* The parent page should never change unless the file is corrupt */
|
|
|
|
|
return STQLITE_CORRUPT_BKPT;
|
|
|
|
|
}
|
|
|
|
|
if( pPage->isInit ) return STQLITE_OK;
|
|
|
|
@ -25917,7 +25917,7 @@ STQLITE_PRIVATE int sqlite3BtreeIsRootPage(MemPage *pPage){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Move the cursor up to the tqparent page.
|
|
|
|
|
** Move the cursor up to the parent page.
|
|
|
|
|
**
|
|
|
|
|
** pCur->idx is set to the cell index that contains the pointer
|
|
|
|
|
** to the page we are coming from. If we are coming from the
|
|
|
|
@ -26892,7 +26892,7 @@ static int reparentPage(BtShared *pBt, Pgno pgno, MemPage *pNewParent, int idx){
|
|
|
|
|
** to pPage.
|
|
|
|
|
**
|
|
|
|
|
** In other words, for every child of pPage, invoke reparentPage()
|
|
|
|
|
** to make sure that each child knows that pPage is its tqparent.
|
|
|
|
|
** to make sure that each child knows that pPage is its parent.
|
|
|
|
|
**
|
|
|
|
|
** This routine gets called after you memcpy() one page into
|
|
|
|
|
** another.
|
|
|
|
@ -27122,7 +27122,7 @@ static int balance(MemPage*, int);
|
|
|
|
|
** fill up. On average.
|
|
|
|
|
**
|
|
|
|
|
** pPage is the leaf page which is the right-most page in the tree.
|
|
|
|
|
** pParent is its tqparent. pPage must have a single overflow entry
|
|
|
|
|
** pParent is its parent. pPage must have a single overflow entry
|
|
|
|
|
** which is also the right-most entry on the page.
|
|
|
|
|
*/
|
|
|
|
|
static int balance_quick(MemPage *pPage, MemPage *pParent){
|
|
|
|
@ -27150,7 +27150,7 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
|
|
|
|
|
assemblePage(pNew, 1, &pCell, &szCell);
|
|
|
|
|
pPage->nOverflow = 0;
|
|
|
|
|
|
|
|
|
|
/* Set the tqparent of the newly allocated page to pParent. */
|
|
|
|
|
/* Set the parent of the newly allocated page to pParent. */
|
|
|
|
|
pNew->pParent = pParent;
|
|
|
|
|
sqlite3PagerRef(pParent->pDbPage);
|
|
|
|
|
|
|
|
|
@ -27190,7 +27190,7 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Release the reference to the new page and balance the tqparent page,
|
|
|
|
|
/* Release the reference to the new page and balance the parent page,
|
|
|
|
|
** in case the divider cell inserted caused it to become overfull.
|
|
|
|
|
*/
|
|
|
|
|
releasePage(pNew);
|
|
|
|
@ -27203,7 +27203,7 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
|
|
|
|
|
** of pPage so that all pages have about the same amount of free space.
|
|
|
|
|
** Usually NN siblings on either side of pPage is used in the balancing,
|
|
|
|
|
** though more siblings might come from one side if pPage is the first
|
|
|
|
|
** or last child of its tqparent. If pPage has fewer than 2*NN siblings
|
|
|
|
|
** or last child of its parent. If pPage has fewer than 2*NN siblings
|
|
|
|
|
** (something which can only happen if pPage is the root page or a
|
|
|
|
|
** child of root) then all available siblings participate in the balancing.
|
|
|
|
|
**
|
|
|
|
@ -27219,16 +27219,16 @@ static int balance_quick(MemPage *pPage, MemPage *pParent){
|
|
|
|
|
** if the page is overfull. Part of the job of this routine is to
|
|
|
|
|
** make sure all Cells for pPage once again fit in pPage->aData[].
|
|
|
|
|
**
|
|
|
|
|
** In the course of balancing the siblings of pPage, the tqparent of pPage
|
|
|
|
|
** In the course of balancing the siblings of pPage, the parent of pPage
|
|
|
|
|
** might become overfull or underfull. If that happens, then this routine
|
|
|
|
|
** is called recursively on the tqparent.
|
|
|
|
|
** is called recursively on the parent.
|
|
|
|
|
**
|
|
|
|
|
** If this routine fails for any reason, it might leave the database
|
|
|
|
|
** in a corrupted state. So if this routine fails, the database should
|
|
|
|
|
** be rolled back.
|
|
|
|
|
*/
|
|
|
|
|
static int balance_nonroot(MemPage *pPage){
|
|
|
|
|
MemPage *pParent; /* The tqparent of pPage */
|
|
|
|
|
MemPage *pParent; /* The parent of pPage */
|
|
|
|
|
BtShared *pBt; /* The whole database */
|
|
|
|
|
int nCell = 0; /* Number of cells in apCell[] */
|
|
|
|
|
int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
|
|
|
|
@ -27262,7 +27262,7 @@ static int balance_nonroot(MemPage *pPage){
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Find the tqparent page.
|
|
|
|
|
** Find the parent page.
|
|
|
|
|
*/
|
|
|
|
|
assert( pPage->isInit );
|
|
|
|
|
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
|
|
|
|
@ -27300,7 +27300,7 @@ static int balance_nonroot(MemPage *pPage){
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Find the cell in the tqparent page whose left child points back
|
|
|
|
|
** Find the cell in the parent page whose left child points back
|
|
|
|
|
** to pPage. The "idx" variable is the index of that cell. If pPage
|
|
|
|
|
** is the rightmost child of pParent then set idx to pParent->nCell
|
|
|
|
|
*/
|
|
|
|
@ -27675,7 +27675,7 @@ static int balance_nonroot(MemPage *pPage){
|
|
|
|
|
j = cntNew[i];
|
|
|
|
|
|
|
|
|
|
/* If the sibling page assembled above was not the right-most sibling,
|
|
|
|
|
** insert a divider cell into the tqparent page.
|
|
|
|
|
** insert a divider cell into the parent page.
|
|
|
|
|
*/
|
|
|
|
|
if( i<nNew-1 && j<nCell ){
|
|
|
|
|
u8 *pCell;
|
|
|
|
@ -27758,7 +27758,7 @@ static int balance_nonroot(MemPage *pPage){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Retqparent tqchildren of all cells.
|
|
|
|
|
** Reparent tqchildren of all cells.
|
|
|
|
|
*/
|
|
|
|
|
for(i=0; i<nNew; i++){
|
|
|
|
|
rc = reparentChildPages(apNew[i]);
|
|
|
|
@ -27768,9 +27768,9 @@ static int balance_nonroot(MemPage *pPage){
|
|
|
|
|
if( rc!=STQLITE_OK ) goto balance_cleanup;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Balance the tqparent page. Note that the current page (pPage) might
|
|
|
|
|
** Balance the parent page. Note that the current page (pPage) might
|
|
|
|
|
** have been added to the freelist so it might no longer be initialized.
|
|
|
|
|
** But the tqparent page will always be initialized.
|
|
|
|
|
** But the parent page will always be initialized.
|
|
|
|
|
*/
|
|
|
|
|
assert( pParent->isInit );
|
|
|
|
|
rc = balance(pParent, 0);
|
|
|
|
@ -27848,7 +27848,7 @@ static int balance_shallower(MemPage *pPage){
|
|
|
|
|
szCell[i] = cellSizePtr(pChild, apCell[i]);
|
|
|
|
|
}
|
|
|
|
|
assemblePage(pPage, pChild->nCell, apCell, szCell);
|
|
|
|
|
/* Copy the right-pointer of the child to the tqparent. */
|
|
|
|
|
/* Copy the right-pointer of the child to the parent. */
|
|
|
|
|
put4byte(&pPage->aData[pPage->hdrOffset+8],
|
|
|
|
|
get4byte(&pChild->aData[pChild->hdrOffset+8]));
|
|
|
|
|
freePage(pChild);
|
|
|
|
@ -27905,10 +27905,10 @@ static int balance_deeper(MemPage *pPage){
|
|
|
|
|
Pgno pgnoChild; /* Page number of the new child page */
|
|
|
|
|
BtShared *pBt; /* The BTree */
|
|
|
|
|
int usableSize; /* Total usable size of a page */
|
|
|
|
|
u8 *data; /* Content of the tqparent page */
|
|
|
|
|
u8 *data; /* Content of the parent page */
|
|
|
|
|
u8 *cdata; /* Content of the child page */
|
|
|
|
|
int hdr; /* Offset to page header in tqparent */
|
|
|
|
|
int brk; /* Offset to content of first cell in tqparent */
|
|
|
|
|
int hdr; /* Offset to page header in parent */
|
|
|
|
|
int brk; /* Offset to content of first cell in parent */
|
|
|
|
|
|
|
|
|
|
assert( pPage->pParent==0 );
|
|
|
|
|
assert( pPage->nOverflow>0 );
|
|
|
|
@ -28705,7 +28705,7 @@ static void checkPtrmap(
|
|
|
|
|
IntegrityCk *pCheck, /* Integrity check context */
|
|
|
|
|
Pgno iChild, /* Child page number */
|
|
|
|
|
u8 eType, /* Expected pointer map type */
|
|
|
|
|
Pgno iParent, /* Expected pointer map tqparent page number */
|
|
|
|
|
Pgno iParent, /* Expected pointer map parent page number */
|
|
|
|
|
char *zContext /* Context description (used for error msg) */
|
|
|
|
|
){
|
|
|
|
|
int rc;
|
|
|
|
@ -30617,7 +30617,7 @@ STQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
|
|
|
|
|
*/
|
|
|
|
|
static int opcodeNoPush(u8 op){
|
|
|
|
|
/* The 10 NOPUSH_MASK_n constants are defined in the automatically
|
|
|
|
|
** generated header file opcodes.h. Each is a 16-bit bittqmask, one
|
|
|
|
|
** generated header file opcodes.h. Each is a 16-bit bitmask, one
|
|
|
|
|
** bit corresponding to each opcode implemented by the virtual
|
|
|
|
|
** machine in vdbe.c. The bit is true if the word "no-push" appears
|
|
|
|
|
** in a comment on the same line as the "case OP_XXX:" in
|
|
|
|
@ -32015,15 +32015,15 @@ STQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Call the destructor for each auxdata entry in pVdbeFunc for which
|
|
|
|
|
** the corresponding bit in tqmask is clear. Auxdata entries beyond 31
|
|
|
|
|
** the corresponding bit in mask is clear. Auxdata entries beyond 31
|
|
|
|
|
** are always destroyed. To destroy all auxdata entries, call this
|
|
|
|
|
** routine with tqmask==0.
|
|
|
|
|
** routine with mask==0.
|
|
|
|
|
*/
|
|
|
|
|
STQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int tqmask){
|
|
|
|
|
STQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0; i<pVdbeFunc->nAux; i++){
|
|
|
|
|
struct AuxData *pAux = &pVdbeFunc->apAux[i];
|
|
|
|
|
if( (i>31 || !(tqmask&(1<<i))) && pAux->pAux ){
|
|
|
|
|
if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
|
|
|
|
|
if( pAux->xDelete ){
|
|
|
|
|
pAux->xDelete(pAux->pAux);
|
|
|
|
|
}
|
|
|
|
@ -34760,7 +34760,7 @@ case OP_CollSeq: { /* no-push */
|
|
|
|
|
** defines the function) with P2 arguments taken from the stack. Pop all
|
|
|
|
|
** arguments from the stack and push back the result.
|
|
|
|
|
**
|
|
|
|
|
** P1 is a 32-bit bittqmask indicating whether or not each argument to the
|
|
|
|
|
** P1 is a 32-bit bitmask indicating whether or not each argument to the
|
|
|
|
|
** function was determined to be constant at compile time. If the first
|
|
|
|
|
** argument was constant then bit 0 of P1 is set. This is used to determine
|
|
|
|
|
** whether meta data associated with a user function argument using the
|
|
|
|
@ -35104,7 +35104,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, no-push */
|
|
|
|
|
** whereas it would normally be NULL. Similarly, NULL==123 is false when
|
|
|
|
|
** 0x200 is set but is NULL when the 0x200 bit of P1 is clear.
|
|
|
|
|
**
|
|
|
|
|
** The least significant byte of P1 (tqmask 0xff) must be an affinity character -
|
|
|
|
|
** The least significant byte of P1 (mask 0xff) must be an affinity character -
|
|
|
|
|
** STQLITE_AFF_TEXT, STQLITE_AFF_INTEGER, and so forth. An attempt is made
|
|
|
|
|
** to coerce both values
|
|
|
|
|
** according to the affinity before the comparison is made. If the byte is
|
|
|
|
@ -36268,8 +36268,8 @@ case OP_OpenWrite: { /* no-push */
|
|
|
|
|
case STQLITE_OK: {
|
|
|
|
|
int flags = sqlite3BtreeFlags(pCur->pCursor);
|
|
|
|
|
/* Sanity checking. Only the lower four bits of the flags byte should
|
|
|
|
|
** be used. Bit 3 (tqmask 0x08) is unpreditable. The lower 3 bits
|
|
|
|
|
** (tqmask 0x07) should be either 5 (intkey+leafdata for tables) or
|
|
|
|
|
** be used. Bit 3 (mask 0x08) is unpreditable. The lower 3 bits
|
|
|
|
|
** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
|
|
|
|
|
** 2 (zerodata for indices). If these conditions are not met it can
|
|
|
|
|
** only mean that we are dealing with a corrupt database file
|
|
|
|
|
*/
|
|
|
|
@ -40260,18 +40260,18 @@ static int lookupName(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If a column from a table in pSrcList is referenced, then record
|
|
|
|
|
** this fact in the pSrcList.a[].colUsed bittqmask. Column 0 causes
|
|
|
|
|
** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
|
|
|
|
|
** bit 0 to be set. Column 1 sets bit 1. And so forth. If the
|
|
|
|
|
** column number is greater than the number of bits in the bittqmask
|
|
|
|
|
** then set the high-order bit of the bittqmask.
|
|
|
|
|
** column number is greater than the number of bits in the bitmask
|
|
|
|
|
** then set the high-order bit of the bitmask.
|
|
|
|
|
*/
|
|
|
|
|
if( pExpr->iColumn>=0 && pMatch!=0 ){
|
|
|
|
|
int n = pExpr->iColumn;
|
|
|
|
|
if( n>=sizeof(Bittqmask)*8 ){
|
|
|
|
|
n = sizeof(Bittqmask)*8-1;
|
|
|
|
|
if( n>=sizeof(Bitmask)*8 ){
|
|
|
|
|
n = sizeof(Bitmask)*8-1;
|
|
|
|
|
}
|
|
|
|
|
assert( pMatch->iCursor==pExpr->iTable );
|
|
|
|
|
pMatch->colUsed |= ((Bittqmask)1)<<n;
|
|
|
|
|
pMatch->colUsed |= ((Bitmask)1)<<n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lookupname_end:
|
|
|
|
@ -43561,19 +43561,19 @@ STQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
|
|
|
|
|
if( v ){
|
|
|
|
|
sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
|
|
|
|
|
|
|
|
|
|
/* The cookie tqmask contains one bit for each database file open.
|
|
|
|
|
/* The cookie mask contains one bit for each database file open.
|
|
|
|
|
** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are
|
|
|
|
|
** set for each database that is used. Generate code to start a
|
|
|
|
|
** transaction on each used database and to verify the schema cookie
|
|
|
|
|
** on each used database.
|
|
|
|
|
*/
|
|
|
|
|
if( pParse->cookieGoto>0 ){
|
|
|
|
|
u32 tqmask;
|
|
|
|
|
u32 mask;
|
|
|
|
|
int iDb;
|
|
|
|
|
sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
|
|
|
|
|
for(iDb=0, tqmask=1; iDb<db->nDb; tqmask<<=1, iDb++){
|
|
|
|
|
if( (tqmask & pParse->cookieMask)==0 ) continue;
|
|
|
|
|
sqlite3VdbeAddOp(v, OP_Transaction, iDb, (tqmask & pParse->writeMask)!=0);
|
|
|
|
|
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
|
|
|
|
|
if( (mask & pParse->cookieMask)==0 ) continue;
|
|
|
|
|
sqlite3VdbeAddOp(v, OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
|
|
|
|
|
sqlite3VdbeAddOp(v, OP_VerifyCookie, iDb, pParse->cookieValue[iDb]);
|
|
|
|
|
}
|
|
|
|
|
#ifndef STQLITE_OMIT_VIRTUALTABLE
|
|
|
|
@ -46558,7 +46558,7 @@ STQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
|
|
|
|
|
STQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
|
|
|
|
sqlite3 *db;
|
|
|
|
|
Vdbe *v;
|
|
|
|
|
int tqmask;
|
|
|
|
|
int mask;
|
|
|
|
|
|
|
|
|
|
v = sqlite3GetVdbe(pParse);
|
|
|
|
|
if( v==0 ) return; /* This only happens if there was a prior error */
|
|
|
|
@ -46570,9 +46570,9 @@ STQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
|
|
|
|
|
assert( iDb<db->nDb );
|
|
|
|
|
assert( db->aDb[iDb].pBt!=0 || iDb==1 );
|
|
|
|
|
assert( iDb<STQLITE_MAX_ATTACHED+2 );
|
|
|
|
|
tqmask = 1<<iDb;
|
|
|
|
|
if( (pParse->cookieMask & tqmask)==0 ){
|
|
|
|
|
pParse->cookieMask |= tqmask;
|
|
|
|
|
mask = 1<<iDb;
|
|
|
|
|
if( (pParse->cookieMask & mask)==0 ){
|
|
|
|
|
pParse->cookieMask |= mask;
|
|
|
|
|
pParse->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
|
|
|
|
|
if( !OMIT_TEMPDB && iDb==1 ){
|
|
|
|
|
sqlite3OpenTempDatabase(pParse);
|
|
|
|
@ -47922,20 +47922,20 @@ static void minmaxFunc(
|
|
|
|
|
sqlite3_value **argv
|
|
|
|
|
){
|
|
|
|
|
int i;
|
|
|
|
|
int tqmask; /* 0 for min() or 0xffffffff for max() */
|
|
|
|
|
int mask; /* 0 for min() or 0xffffffff for max() */
|
|
|
|
|
int iBest;
|
|
|
|
|
CollSeq *pColl;
|
|
|
|
|
|
|
|
|
|
if( argc==0 ) return;
|
|
|
|
|
tqmask = sqlite3_user_data(context)==0 ? 0 : -1;
|
|
|
|
|
mask = sqlite3_user_data(context)==0 ? 0 : -1;
|
|
|
|
|
pColl = sqlite3GetFuncCollSeq(context);
|
|
|
|
|
assert( pColl );
|
|
|
|
|
assert( tqmask==-1 || tqmask==0 );
|
|
|
|
|
assert( mask==-1 || mask==0 );
|
|
|
|
|
iBest = 0;
|
|
|
|
|
if( sqlite3_value_type(argv[0])==STQLITE_NULL ) return;
|
|
|
|
|
for(i=1; i<argc; i++){
|
|
|
|
|
if( sqlite3_value_type(argv[i])==STQLITE_NULL ) return;
|
|
|
|
|
if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^tqmask)>=0 ){
|
|
|
|
|
if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
|
|
|
|
|
iBest = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -52019,7 +52019,7 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, int value){
|
|
|
|
|
static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
|
|
|
|
static const struct sPragmaType {
|
|
|
|
|
const char *zName; /* Name of the pragma */
|
|
|
|
|
int tqmask; /* Mask for the db->flags value */
|
|
|
|
|
int mask; /* Mask for the db->flags value */
|
|
|
|
|
} aPragma[] = {
|
|
|
|
|
{ "full_column_names", STQLITE_FullColNames },
|
|
|
|
|
{ "short_column_names", STQLITE_ShortColNames },
|
|
|
|
@ -52052,12 +52052,12 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
|
|
|
|
|
v = sqlite3GetVdbe(pParse);
|
|
|
|
|
if( v ){
|
|
|
|
|
if( zRight==0 ){
|
|
|
|
|
returnSingleInt(pParse, p->zName, (db->flags & p->tqmask)!=0 );
|
|
|
|
|
returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
|
|
|
|
|
}else{
|
|
|
|
|
if( getBoolean(zRight) ){
|
|
|
|
|
db->flags |= p->tqmask;
|
|
|
|
|
db->flags |= p->mask;
|
|
|
|
|
}else{
|
|
|
|
|
db->flags &= ~p->tqmask;
|
|
|
|
|
db->flags &= ~p->mask;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -55920,7 +55920,7 @@ static void substSelect(Select *p, int iTable, ExprList *pEList){
|
|
|
|
|
** the subquery before this routine runs.
|
|
|
|
|
*/
|
|
|
|
|
static int flattenSubquery(
|
|
|
|
|
Select *p, /* The tqparent or outer SELECT statement */
|
|
|
|
|
Select *p, /* The parent or outer SELECT statement */
|
|
|
|
|
int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
|
|
|
|
|
int isAgg, /* True if outer SELECT uses aggregate functions */
|
|
|
|
|
int subqueryIsAgg /* True if the subquery uses aggregate functions */
|
|
|
|
@ -56322,7 +56322,7 @@ static int processOrderGroupBy(
|
|
|
|
|
** This routine resolves any names used in the result set of the
|
|
|
|
|
** supplied SELECT statement. If the SELECT statement being resolved
|
|
|
|
|
** is a sub-select, then pOuterNC is a pointer to the NameContext
|
|
|
|
|
** of the tqparent SELECT.
|
|
|
|
|
** of the parent SELECT.
|
|
|
|
|
*/
|
|
|
|
|
STQLITE_PRIVATE int sqlite3SelectResolve(
|
|
|
|
|
Parse *pParse, /* The parser context */
|
|
|
|
@ -56580,8 +56580,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
|
|
|
|
|
**
|
|
|
|
|
** The pParent, parentTab, and *pParentAgg fields are filled in if this
|
|
|
|
|
** SELECT is a subquery. This routine may try to combine this SELECT
|
|
|
|
|
** with its tqparent to form a single flat query. In so doing, it might
|
|
|
|
|
** change the tqparent query from a non-aggregate to an aggregate query.
|
|
|
|
|
** with its parent to form a single flat query. In so doing, it might
|
|
|
|
|
** change the parent query from a non-aggregate to an aggregate query.
|
|
|
|
|
** For that reason, the pParentAgg flag is passed as a pointer, so it
|
|
|
|
|
** can be changed.
|
|
|
|
|
**
|
|
|
|
@ -56715,7 +56715,7 @@ STQLITE_PRIVATE int sqlite3Select(
|
|
|
|
|
}
|
|
|
|
|
#if STQLITE_MAX_EXPR_DEPTH>0
|
|
|
|
|
/* Increment Parse.nHeight by the height of the largest expression
|
|
|
|
|
** tree refered to by this, the tqparent select. The child select
|
|
|
|
|
** tree refered to by this, the parent select. The child select
|
|
|
|
|
** may contain expression trees of at most
|
|
|
|
|
** (STQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
|
|
|
|
|
** more conservative than necessary, but much easier than enforcing
|
|
|
|
@ -56750,7 +56750,7 @@ STQLITE_PRIVATE int sqlite3Select(
|
|
|
|
|
goto select_end;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check to see if this is a subquery that can be "flattened" into its tqparent.
|
|
|
|
|
/* Check to see if this is a subquery that can be "flattened" into its parent.
|
|
|
|
|
** If flattening is a possiblity, do so and return immediately.
|
|
|
|
|
*/
|
|
|
|
|
#ifndef STQLITE_OMIT_VIEW
|
|
|
|
@ -58043,16 +58043,16 @@ STQLITE_PRIVATE int sqlite3TriggersExist(
|
|
|
|
|
ExprList *pChanges /* Columns that change in an UPDATE statement */
|
|
|
|
|
){
|
|
|
|
|
Trigger *pTrigger;
|
|
|
|
|
int tqmask = 0;
|
|
|
|
|
int mask = 0;
|
|
|
|
|
|
|
|
|
|
pTrigger = IsVirtual(pTab) ? 0 : pTab->pTrigger;
|
|
|
|
|
while( pTrigger ){
|
|
|
|
|
if( pTrigger->op==op && checkColumnOverLap(pTrigger->pColumns, pChanges) ){
|
|
|
|
|
tqmask |= pTrigger->tr_tm;
|
|
|
|
|
mask |= pTrigger->tr_tm;
|
|
|
|
|
}
|
|
|
|
|
pTrigger = pTrigger->pNext;
|
|
|
|
|
}
|
|
|
|
|
return tqmask;
|
|
|
|
|
return mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -59959,9 +59959,9 @@ STQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** The number of bits in a Bittqmask. "BMS" means "BitMask Size".
|
|
|
|
|
** The number of bits in a Bitmask. "BMS" means "BitMask Size".
|
|
|
|
|
*/
|
|
|
|
|
#define BMS (sizeof(Bittqmask)*8)
|
|
|
|
|
#define BMS (sizeof(Bitmask)*8)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Trace output macros
|
|
|
|
@ -59995,20 +59995,20 @@ typedef struct ExprMaskSet ExprMaskSet;
|
|
|
|
|
** where X is a column name and <op> is one of certain operators,
|
|
|
|
|
** then WhereTerm.leftCursor and WhereTerm.leftColumn record the
|
|
|
|
|
** cursor number and column number for X. WhereTerm.operator records
|
|
|
|
|
** the <op> using a bittqmask encoding defined by WO_xxx below. The
|
|
|
|
|
** use of a bittqmask encoding for the operator allows us to search
|
|
|
|
|
** the <op> using a bitmask encoding defined by WO_xxx below. The
|
|
|
|
|
** use of a bitmask encoding for the operator allows us to search
|
|
|
|
|
** quickly for terms that match any of several different operators.
|
|
|
|
|
**
|
|
|
|
|
** prereqRight and prereqAll record sets of cursor numbers,
|
|
|
|
|
** but they do so indirectly. A single ExprMaskSet structure translates
|
|
|
|
|
** cursor number into bits and the translated bit is stored in the prereq
|
|
|
|
|
** fields. The translation is used in order to maximize the number of
|
|
|
|
|
** bits that will fit in a Bittqmask. The VDBE cursor numbers might be
|
|
|
|
|
** bits that will fit in a Bitmask. The VDBE cursor numbers might be
|
|
|
|
|
** spread out over the non-negative integers. For example, the cursor
|
|
|
|
|
** numbers might be 3, 8, 9, 10, 20, 23, 41, and 45. The ExprMaskSet
|
|
|
|
|
** translates these sparse cursor numbers into consecutive integers
|
|
|
|
|
** beginning with 0 in order to make the best possible use of the available
|
|
|
|
|
** bits in the Bittqmask. So, in the example above, the cursor numbers
|
|
|
|
|
** bits in the Bitmask. So, in the example above, the cursor numbers
|
|
|
|
|
** would be mapped into integers 0 through 7.
|
|
|
|
|
*/
|
|
|
|
|
typedef struct WhereTerm WhereTerm;
|
|
|
|
@ -60021,8 +60021,8 @@ struct WhereTerm {
|
|
|
|
|
u8 flags; /* Bit flags. See below */
|
|
|
|
|
u8 nChild; /* Number of tqchildren that must disable us */
|
|
|
|
|
WhereClause *pWC; /* The clause this term is part of */
|
|
|
|
|
Bittqmask prereqRight; /* Bittqmask of tables used by pRight */
|
|
|
|
|
Bittqmask prereqAll; /* Bittqmask of tables referenced by p */
|
|
|
|
|
Bitmask prereqRight; /* Bitmask of tables used by pRight */
|
|
|
|
|
Bitmask prereqAll; /* Bitmask of tables referenced by p */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -60059,8 +60059,8 @@ struct WhereClause {
|
|
|
|
|
** from the sparse cursor numbers into consecutive integers beginning
|
|
|
|
|
** with 0.
|
|
|
|
|
**
|
|
|
|
|
** If ExprMaskSet.ix[A]==B it means that The A-th bit of a Bittqmask
|
|
|
|
|
** corresponds VDBE cursor number B. The A-th bit of a bittqmask is 1<<A.
|
|
|
|
|
** If ExprMaskSet.ix[A]==B it means that The A-th bit of a Bitmask
|
|
|
|
|
** corresponds VDBE cursor number B. The A-th bit of a bitmask is 1<<A.
|
|
|
|
|
**
|
|
|
|
|
** For example, if the WHERE clause expression used these VDBE
|
|
|
|
|
** cursors: 4, 5, 8, 29, 57, 73. Then the ExprMaskSet structure
|
|
|
|
@ -60075,7 +60075,7 @@ struct WhereClause {
|
|
|
|
|
*/
|
|
|
|
|
struct ExprMaskSet {
|
|
|
|
|
int n; /* Number of assigned cursor values */
|
|
|
|
|
int ix[sizeof(Bittqmask)*8]; /* Cursor assigned to each bit */
|
|
|
|
|
int ix[sizeof(Bitmask)*8]; /* Cursor assigned to each bit */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -60096,7 +60096,7 @@ struct ExprMaskSet {
|
|
|
|
|
/*
|
|
|
|
|
** Value for flags returned by bestIndex().
|
|
|
|
|
**
|
|
|
|
|
** The least significant byte is reserved as a tqmask for WO_ values above.
|
|
|
|
|
** The least significant byte is reserved as a mask for WO_ values above.
|
|
|
|
|
** The WhereLevel.flags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
|
|
|
|
|
** But if the table is the right table of a left join, WhereLevel.flags
|
|
|
|
|
** is set to WO_IN|WO_EQ. The WhereLevel.flags field can then be used as
|
|
|
|
@ -60216,26 +60216,26 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Initialize an expression tqmask set
|
|
|
|
|
** Initialize an expression mask set
|
|
|
|
|
*/
|
|
|
|
|
#define initMaskSet(P) memset(P, 0, sizeof(*P))
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Return the bittqmask for the given cursor number. Return 0 if
|
|
|
|
|
** Return the bitmask for the given cursor number. Return 0 if
|
|
|
|
|
** iCursor is not in the set.
|
|
|
|
|
*/
|
|
|
|
|
static Bittqmask getMask(ExprMaskSet *pMaskSet, int iCursor){
|
|
|
|
|
static Bitmask getMask(ExprMaskSet *pMaskSet, int iCursor){
|
|
|
|
|
int i;
|
|
|
|
|
for(i=0; i<pMaskSet->n; i++){
|
|
|
|
|
if( pMaskSet->ix[i]==iCursor ){
|
|
|
|
|
return ((Bittqmask)1)<<i;
|
|
|
|
|
return ((Bitmask)1)<<i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Create a new tqmask for cursor iCursor.
|
|
|
|
|
** Create a new mask for cursor iCursor.
|
|
|
|
|
**
|
|
|
|
|
** There is one cursor per table in the FROM clause. The number of
|
|
|
|
|
** tables in the FROM clause is limited by a test early in the
|
|
|
|
@ -60249,7 +60249,7 @@ static void createMask(ExprMaskSet *pMaskSet, int iCursor){
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** This routine walks (recursively) an expression tree and generates
|
|
|
|
|
** a bittqmask indicating which tables are used in that expression
|
|
|
|
|
** a bitmask indicating which tables are used in that expression
|
|
|
|
|
** tree.
|
|
|
|
|
**
|
|
|
|
|
** In order for this routine to work, the calling function must have
|
|
|
|
@ -60258,46 +60258,46 @@ static void createMask(ExprMaskSet *pMaskSet, int iCursor){
|
|
|
|
|
** The sqlite3ExprResolveNames() routines looks for column names and
|
|
|
|
|
** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
|
|
|
|
|
** the VDBE cursor number of the table. This routine just has to
|
|
|
|
|
** translate the cursor numbers into bittqmask values and OR all
|
|
|
|
|
** translate the cursor numbers into bitmask values and OR all
|
|
|
|
|
** the bitmasks together.
|
|
|
|
|
*/
|
|
|
|
|
static Bittqmask exprListTableUsage(ExprMaskSet*, ExprList*);
|
|
|
|
|
static Bittqmask exprSelectTableUsage(ExprMaskSet*, Select*);
|
|
|
|
|
static Bittqmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
|
|
|
|
|
Bittqmask tqmask = 0;
|
|
|
|
|
static Bitmask exprListTableUsage(ExprMaskSet*, ExprList*);
|
|
|
|
|
static Bitmask exprSelectTableUsage(ExprMaskSet*, Select*);
|
|
|
|
|
static Bitmask exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
|
|
|
|
|
Bitmask mask = 0;
|
|
|
|
|
if( p==0 ) return 0;
|
|
|
|
|
if( p->op==TK_COLUMN ){
|
|
|
|
|
tqmask = getMask(pMaskSet, p->iTable);
|
|
|
|
|
return tqmask;
|
|
|
|
|
mask = getMask(pMaskSet, p->iTable);
|
|
|
|
|
return mask;
|
|
|
|
|
}
|
|
|
|
|
tqmask = exprTableUsage(pMaskSet, p->pRight);
|
|
|
|
|
tqmask |= exprTableUsage(pMaskSet, p->pLeft);
|
|
|
|
|
tqmask |= exprListTableUsage(pMaskSet, p->pList);
|
|
|
|
|
tqmask |= exprSelectTableUsage(pMaskSet, p->pSelect);
|
|
|
|
|
return tqmask;
|
|
|
|
|
mask = exprTableUsage(pMaskSet, p->pRight);
|
|
|
|
|
mask |= exprTableUsage(pMaskSet, p->pLeft);
|
|
|
|
|
mask |= exprListTableUsage(pMaskSet, p->pList);
|
|
|
|
|
mask |= exprSelectTableUsage(pMaskSet, p->pSelect);
|
|
|
|
|
return mask;
|
|
|
|
|
}
|
|
|
|
|
static Bittqmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){
|
|
|
|
|
static Bitmask exprListTableUsage(ExprMaskSet *pMaskSet, ExprList *pList){
|
|
|
|
|
int i;
|
|
|
|
|
Bittqmask tqmask = 0;
|
|
|
|
|
Bitmask mask = 0;
|
|
|
|
|
if( pList ){
|
|
|
|
|
for(i=0; i<pList->nExpr; i++){
|
|
|
|
|
tqmask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
|
|
|
|
|
mask |= exprTableUsage(pMaskSet, pList->a[i].pExpr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return tqmask;
|
|
|
|
|
return mask;
|
|
|
|
|
}
|
|
|
|
|
static Bittqmask exprSelectTableUsage(ExprMaskSet *pMaskSet, Select *pS){
|
|
|
|
|
Bittqmask tqmask;
|
|
|
|
|
static Bitmask exprSelectTableUsage(ExprMaskSet *pMaskSet, Select *pS){
|
|
|
|
|
Bitmask mask;
|
|
|
|
|
if( pS==0 ){
|
|
|
|
|
tqmask = 0;
|
|
|
|
|
mask = 0;
|
|
|
|
|
}else{
|
|
|
|
|
tqmask = exprListTableUsage(pMaskSet, pS->pEList);
|
|
|
|
|
tqmask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
|
|
|
|
|
tqmask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
|
|
|
|
|
tqmask |= exprTableUsage(pMaskSet, pS->pWhere);
|
|
|
|
|
tqmask |= exprTableUsage(pMaskSet, pS->pHaving);
|
|
|
|
|
mask = exprListTableUsage(pMaskSet, pS->pEList);
|
|
|
|
|
mask |= exprListTableUsage(pMaskSet, pS->pGroupBy);
|
|
|
|
|
mask |= exprListTableUsage(pMaskSet, pS->pOrderBy);
|
|
|
|
|
mask |= exprTableUsage(pMaskSet, pS->pWhere);
|
|
|
|
|
mask |= exprTableUsage(pMaskSet, pS->pHaving);
|
|
|
|
|
}
|
|
|
|
|
return tqmask;
|
|
|
|
|
return mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -60337,7 +60337,7 @@ static void exprCommute(Expr *pExpr){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** Translate from TK_xx operator to WO_xx bittqmask.
|
|
|
|
|
** Translate from TK_xx operator to WO_xx bitmask.
|
|
|
|
|
*/
|
|
|
|
|
static int operatorMask(int op){
|
|
|
|
|
int c;
|
|
|
|
@ -60369,7 +60369,7 @@ static WhereTerm *findTerm(
|
|
|
|
|
WhereClause *pWC, /* The WHERE clause to be searched */
|
|
|
|
|
int iCur, /* Cursor number of LHS */
|
|
|
|
|
int iColumn, /* Column number of LHS */
|
|
|
|
|
Bittqmask notReady, /* RHS must not overlap with this tqmask */
|
|
|
|
|
Bitmask notReady, /* RHS must not overlap with this mask */
|
|
|
|
|
u16 op, /* Mask of WO_xx values describing operator */
|
|
|
|
|
Index *pIdx /* Must be compatible with this index, if not NULL */
|
|
|
|
|
){
|
|
|
|
@ -60636,8 +60636,8 @@ static void exprAnalyze(
|
|
|
|
|
WhereTerm *pTerm = &pWC->a[idxTerm];
|
|
|
|
|
ExprMaskSet *pMaskSet = pWC->pMaskSet;
|
|
|
|
|
Expr *pExpr = pTerm->pExpr;
|
|
|
|
|
Bittqmask prereqLeft;
|
|
|
|
|
Bittqmask prereqAll;
|
|
|
|
|
Bitmask prereqLeft;
|
|
|
|
|
Bitmask prereqAll;
|
|
|
|
|
int nPattern;
|
|
|
|
|
int isComplete;
|
|
|
|
|
int op;
|
|
|
|
@ -60849,7 +60849,7 @@ or_not_possible:
|
|
|
|
|
int idxNew;
|
|
|
|
|
Expr *pRight, *pLeft;
|
|
|
|
|
WhereTerm *pNewTerm;
|
|
|
|
|
Bittqmask prereqColumn, prereqExpr;
|
|
|
|
|
Bitmask prereqColumn, prereqExpr;
|
|
|
|
|
|
|
|
|
|
pRight = pExpr->pList->a[0].pExpr;
|
|
|
|
|
pLeft = pExpr->pList->a[1].pExpr;
|
|
|
|
@ -60884,7 +60884,7 @@ static int referencesOtherTables(
|
|
|
|
|
int iFirst, /* Be searching with the iFirst-th expression */
|
|
|
|
|
int iBase /* Ignore references to this table */
|
|
|
|
|
){
|
|
|
|
|
Bittqmask allowed = ~getMask(pMaskSet, iBase);
|
|
|
|
|
Bitmask allowed = ~getMask(pMaskSet, iBase);
|
|
|
|
|
while( iFirst<pList->nExpr ){
|
|
|
|
|
if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){
|
|
|
|
|
return 1;
|
|
|
|
@ -61133,7 +61133,7 @@ static double bestVirtualIndex(
|
|
|
|
|
Parse *pParse, /* The parsing context */
|
|
|
|
|
WhereClause *pWC, /* The WHERE clause */
|
|
|
|
|
struct SrcList_item *pSrc, /* The FROM clause term to search */
|
|
|
|
|
Bittqmask notReady, /* Mask of cursors that are not available */
|
|
|
|
|
Bitmask notReady, /* Mask of cursors that are not available */
|
|
|
|
|
ExprList *pOrderBy, /* The order by clause */
|
|
|
|
|
int orderByUsable, /* True if we can potential sort */
|
|
|
|
|
sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */
|
|
|
|
@ -61337,7 +61337,7 @@ static double bestIndex(
|
|
|
|
|
Parse *pParse, /* The parsing context */
|
|
|
|
|
WhereClause *pWC, /* The WHERE clause */
|
|
|
|
|
struct SrcList_item *pSrc, /* The FROM clause term to search */
|
|
|
|
|
Bittqmask notReady, /* Mask of cursors that are not available */
|
|
|
|
|
Bitmask notReady, /* Mask of cursors that are not available */
|
|
|
|
|
ExprList *pOrderBy, /* The order by clause */
|
|
|
|
|
Index **ppIndex, /* Make *ppIndex point to the best index */
|
|
|
|
|
int *pFlags, /* Put flags describing this choice in *pFlags */
|
|
|
|
@ -61532,13 +61532,13 @@ static double bestIndex(
|
|
|
|
|
** ever reading the table. If that is the case, then halve the
|
|
|
|
|
** cost of this index.
|
|
|
|
|
*/
|
|
|
|
|
if( flags && pSrc->colUsed < (((Bittqmask)1)<<(BMS-1)) ){
|
|
|
|
|
Bittqmask m = pSrc->colUsed;
|
|
|
|
|
if( flags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){
|
|
|
|
|
Bitmask m = pSrc->colUsed;
|
|
|
|
|
int j;
|
|
|
|
|
for(j=0; j<pProbe->nColumn; j++){
|
|
|
|
|
int x = pProbe->aiColumn[j];
|
|
|
|
|
if( x<BMS-1 ){
|
|
|
|
|
m &= ~(((Bittqmask)1)<<x);
|
|
|
|
|
m &= ~(((Bitmask)1)<<x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( m==0 ){
|
|
|
|
@ -61705,7 +61705,7 @@ static void codeAllEqualityTerms(
|
|
|
|
|
Parse *pParse, /* Parsing context */
|
|
|
|
|
WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
|
|
|
|
|
WhereClause *pWC, /* The WHERE clause */
|
|
|
|
|
Bittqmask notReady /* Which parts of FROM have not yet been coded */
|
|
|
|
|
Bitmask notReady /* Which parts of FROM have not yet been coded */
|
|
|
|
|
){
|
|
|
|
|
int nEq = pLevel->nEq; /* The number of == or IN constraints to code */
|
|
|
|
|
int termsInMem = 0; /* If true, store value in mem[] cells */
|
|
|
|
@ -61887,9 +61887,9 @@ STQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
|
|
|
|
|
WhereInfo *pWInfo; /* Will become the return value of this function */
|
|
|
|
|
Vdbe *v = pParse->pVdbe; /* The virtual database engine */
|
|
|
|
|
int brk, cont = 0; /* Addresses used during code generation */
|
|
|
|
|
Bittqmask notReady; /* Cursors that are not yet positioned */
|
|
|
|
|
Bitmask notReady; /* Cursors that are not yet positioned */
|
|
|
|
|
WhereTerm *pTerm; /* A single term in the WHERE clause */
|
|
|
|
|
ExprMaskSet maskSet; /* The expression tqmask set */
|
|
|
|
|
ExprMaskSet maskSet; /* The expression mask set */
|
|
|
|
|
WhereClause wc; /* The WHERE clause is divided into these terms */
|
|
|
|
|
struct SrcList_item *pTabItem; /* A single entry from pTabList */
|
|
|
|
|
WhereLevel *pLevel; /* A single level in the pWInfo list */
|
|
|
|
@ -61897,7 +61897,7 @@ STQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
|
|
|
|
|
int andFlags; /* AND-ed combination of all wc.a[].flags */
|
|
|
|
|
|
|
|
|
|
/* The number of tables in the FROM clause is limited by the number of
|
|
|
|
|
** bits in a Bittqmask
|
|
|
|
|
** bits in a Bitmask
|
|
|
|
|
*/
|
|
|
|
|
if( pTabList->nSrc>BMS ){
|
|
|
|
|
sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS);
|
|
|
|
@ -61958,7 +61958,7 @@ STQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
|
|
|
|
|
** This loop also figures out the nesting order of tables in the FROM
|
|
|
|
|
** clause.
|
|
|
|
|
*/
|
|
|
|
|
notReady = ~(Bittqmask)0;
|
|
|
|
|
notReady = ~(Bitmask)0;
|
|
|
|
|
pTabItem = pTabList->a;
|
|
|
|
|
pLevel = pWInfo->a;
|
|
|
|
|
andFlags = ~0;
|
|
|
|
@ -61974,7 +61974,7 @@ STQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
|
|
|
|
|
int bestNEq = 0; /* nEq associated with pBest */
|
|
|
|
|
double lowestCost; /* Cost of the pBest */
|
|
|
|
|
int bestJ = 0; /* The value of j */
|
|
|
|
|
Bittqmask m; /* Bittqmask value for j or bestJ */
|
|
|
|
|
Bitmask m; /* Bitmask value for j or bestJ */
|
|
|
|
|
int once = 0; /* True when first table is seen */
|
|
|
|
|
sqlite3_index_info *pIndex; /* Current virtual index */
|
|
|
|
|
|
|
|
|
@ -62106,8 +62106,8 @@ STQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
|
|
|
|
|
#endif
|
|
|
|
|
if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){
|
|
|
|
|
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead);
|
|
|
|
|
if( pTab->nCol<(sizeof(Bittqmask)*8) ){
|
|
|
|
|
Bittqmask b = pTabItem->colUsed;
|
|
|
|
|
if( pTab->nCol<(sizeof(Bitmask)*8) ){
|
|
|
|
|
Bitmask b = pTabItem->colUsed;
|
|
|
|
|
int n = 0;
|
|
|
|
|
for(; b; b=b>>1, n++){}
|
|
|
|
|
sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-1, n);
|
|
|
|
@ -62138,7 +62138,7 @@ STQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
|
|
|
|
|
** loop below generates code for a single nested loop of the VM
|
|
|
|
|
** program.
|
|
|
|
|
*/
|
|
|
|
|
notReady = ~(Bittqmask)0;
|
|
|
|
|
notReady = ~(Bitmask)0;
|
|
|
|
|
for(i=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
|
|
|
|
|
int j;
|
|
|
|
|
int iCur = pTabItem->iCursor; /* The VDBE cursor for the table */
|
|
|
|
@ -62803,7 +62803,7 @@ typedef union {
|
|
|
|
|
struct TrigEvent yy370;
|
|
|
|
|
SrcList* yy373;
|
|
|
|
|
Expr * yy386;
|
|
|
|
|
struct {int value; int tqmask;} yy405;
|
|
|
|
|
struct {int value; int mask;} yy405;
|
|
|
|
|
Token yy410;
|
|
|
|
|
IdList* yy432;
|
|
|
|
|
int yy495;
|
|
|
|
@ -64787,19 +64787,19 @@ static void yy_reduce(
|
|
|
|
|
{ yygotominor.yy46 = OE_Restrict * 0x010101; }
|
|
|
|
|
break;
|
|
|
|
|
case 66:
|
|
|
|
|
{ yygotominor.yy46 = (yymsp[-1].minor.yy46 & yymsp[0].minor.yy405.tqmask) | yymsp[0].minor.yy405.value; }
|
|
|
|
|
{ yygotominor.yy46 = (yymsp[-1].minor.yy46 & yymsp[0].minor.yy405.mask) | yymsp[0].minor.yy405.value; }
|
|
|
|
|
break;
|
|
|
|
|
case 67:
|
|
|
|
|
{ yygotominor.yy405.value = 0; yygotominor.yy405.tqmask = 0x000000; }
|
|
|
|
|
{ yygotominor.yy405.value = 0; yygotominor.yy405.mask = 0x000000; }
|
|
|
|
|
break;
|
|
|
|
|
case 68:
|
|
|
|
|
{ yygotominor.yy405.value = yymsp[0].minor.yy46; yygotominor.yy405.tqmask = 0x0000ff; }
|
|
|
|
|
{ yygotominor.yy405.value = yymsp[0].minor.yy46; yygotominor.yy405.mask = 0x0000ff; }
|
|
|
|
|
break;
|
|
|
|
|
case 69:
|
|
|
|
|
{ yygotominor.yy405.value = yymsp[0].minor.yy46<<8; yygotominor.yy405.tqmask = 0x00ff00; }
|
|
|
|
|
{ yygotominor.yy405.value = yymsp[0].minor.yy46<<8; yygotominor.yy405.mask = 0x00ff00; }
|
|
|
|
|
break;
|
|
|
|
|
case 70:
|
|
|
|
|
{ yygotominor.yy405.value = yymsp[0].minor.yy46<<16; yygotominor.yy405.tqmask = 0xff0000; }
|
|
|
|
|
{ yygotominor.yy405.value = yymsp[0].minor.yy46<<16; yygotominor.yy405.mask = 0xff0000; }
|
|
|
|
|
break;
|
|
|
|
|
case 71:
|
|
|
|
|
{ yygotominor.yy46 = OE_SetNull; }
|
|
|
|
|