-C Add\sSQLITE_DQS\sto\sthe\scompileoptions_used\slist,\sper\srequest\sin\s[forum\spost\s8b1060122b|forum:8b1060122b].\sForce\sDQS=0\sin\ssqlite3-wasm.c.
-D 2022-10-21T17:48:49.786
+C Begin\stransitioning\sthe\sfixed-length\s(64-bit)\sbitmap\sused\sto\skeep\strack\sof\nthe\ssubset\sof\scolumns\sof\sa\stable\sthat\sare\sused\sby\sa\squery\sinto\sa\smore\sgeneral\nstructure\sthat\scan\swork\swith\swide\stables.\s\sExperimental.
+D 2022-10-21T20:12:24.563
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
-F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d
+F src/bitvec.c 4915778f09f486e38f5fc43451c67e9b0933cacf23524fef61d7740f1d898588
F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca
F src/btree.c 74fc5f6a0577df703d6f98d0c51ee0d8d91d22dbc0ba86e42e056517e2b45576
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
-F src/build.c 13bcc04821ad260ef00d87e0704424e0ae4e6cd66c7e384b4cedb379a6cb738b
+F src/build.c df4dbc89b03927c493fb85b8d2500cea58105ee1714ad9725427de4333a6b5b9
F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
F src/dbpage.c 5808e91bc27fa3981b028000f8fadfdc10ce9e59a34ce7dc4e035a69be3906ec
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e
-F src/expr.c 847f87d9df3ede2b2b0a8db088af0b9c1923b21009f8ea1b9b7b28cb0a383170
+F src/expr.c 304bce440edc89567bed99756771331a8316b6c36c36edee7b0226666eeaef3a
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 722f20779f5342a787922deded3628d8c74b5249cab04098cf17ee2f2aaff002
F src/func.c fe2a795ad647ce42054873ac91c43beb7b5d204892903a67f6e7e314379b9d4a
F src/prepare.c 1b02be0441eda4579471fea097f678effcbb77ef0c39ab3f703c837822bcd674
F src/printf.c e99ee9741e79ae3873458146f59644276657340385ade4e76a5f5d1c25793764
F src/random.c 546d6feb15ec69c1aafe9bb351a277cbb498fd5410e646add673acb805714960
-F src/resolve.c efea4e5fbecfd6d0a9071b0be0d952620991673391b6ffaaf4c277b0bb674633
+F src/resolve.c 857836c954ad8affa5a71c0cfaf011742346b0e8fc74c2fc3437e32ff102a9d1
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 3f7238ebb3252f4768a8fb46ad95b62700d27baddcab8a21548129f4f9305d52
+F src/select.c 22905c05a1ef7c33f67c2ece75306d228590b4fcd2d00cf7fb1fba026e76d8e7
F src/shell.c.in 6a9e15cb9fc3cd13d3647d4d9714c0d4d4a65e7f49228c2aafca910ed08d5774
F src/sqlite.h.in d9c8a6243fc0a1c270d69db33758e34b810af3462f9bc5b4af113b347e07c69d
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 5336beea1868d99d2f62e628dbea55e97267dbff8193291ab175e960c5df9141
-F src/sqliteInt.h ce8bf543210ab4a8a797e6abaf45e15f4cff24570b1043560aa747b3dc1a7935
+F src/sqliteInt.h 449848d59da7b4862bee9a73ff0f8453beebc6689395e3aeaca33d994aa24a89
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
-F src/treeview.c 07787f67cd297a6d09d04b8d70c06769c60c9c1d9080378f93929c16f8fd3298
+F src/treeview.c bb143b907d5ee2f98f8a866eac20a2dd73e41bcfcc34a2360cde0df9720cb817
F src/trigger.c 4163ada044af89d51caba1cb713a73165347b2ec05fe84a283737c134d61fcd5
-F src/update.c 5b0302c47cf31b533d5dff04c497ca1d8b9d89c39727e633fbe7b882fd5ac5aa
+F src/update.c 932e88c143737695b0afec7be019e960a69d23ad049d2587be85c4ea39c6eb33
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
F src/util.c 0be191521ff6d2805995f4910f0b6231b42843678b2efdc1abecaf39929a673f
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
-F src/where.c bccea9a1066c9843ad7bf05f9054b390fe9b5d0fb721ff8af2d11fb93779836a
+F src/where.c d5037ce38cf934151d57440a0e9713efba6c766f6207837169670e105b404782
F src/whereInt.h e5f5cf1bc32b7d01a6337027478ef6ed90c8c403de4b977198345c8238f0e1b0
F src/wherecode.c 13b6373af69d484d9b05b9a732d393ce3b7b320cc93275c6528127678650f8cb
-F src/whereexpr.c a1bd9d8faddc946d19ae8b6b3468874794bf54acd13fe46e1680fb428e8d3ea7
+F src/whereexpr.c 793ed333739cc8f9320e9c3cb5b6e95f1b92d773d8cf3fbd739aae125da30002
F src/window.c 928e215840e2f2d9a2746e018c9643ef42c66c4ab6630ef0df7fa388fa145e86
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9cf1142b0cdb13347e3f551c862cb4714cadfe5ad637f049cf0a4b8bb6125b32
-R f0d8c3eadf9b3a16756631ad00044092
-U stephan
-Z 4b9ac72991a7e1ed1b8b1873a504bb5c
+P fcd9e0dbe3226f3f7ccc15b11fc3aa3b8058571bef274c25a33e9753e22f7551
+R 90ea3d24eab5cb65c030271a81eb056f
+T *branch * column-set
+T *sym-column-set *
+T -sym-trunk *
+U drh
+Z 9f1ca2bdbb2f4127a8ebcf444d4383b0
# Remove this line to create a well-formed Fossil manifest.
-fcd9e0dbe3226f3f7ccc15b11fc3aa3b8058571bef274c25a33e9753e22f7551
\ No newline at end of file
+5dd78588203b38e5782a31944c8f14141f348d4ccc9d378cf81c57b07162b650
\ No newline at end of file
** May you share freely, never taking more than you give.
**
*************************************************************************
-** This file implements an object that represents a fixed-length
-** bitmap. Bits are numbered starting with 1.
+** This file implements two objects: Bitvec and ColumnSet
**
-** A bitmap is used to record which pages of a database file have been
+** ## BITVEC
+**
+** The Bitvec object represents a fixed-length bitmap. Bits are
+** numbered starting with 1.
+**
+** A Bitvec bitmap is used to record which pages of a database file have been
** journalled during a transaction, or which pages have the "dont-write"
** property. Usually only a few pages are meet either condition.
** So the bitmap is usually sparse and has low cardinality.
** the bitmap becomes dense with high cardinality. The algorithm needs
** to handle both cases well.
**
-** The size of the bitmap is fixed when the object is created.
+** The size of a Bitvec bitmap is fixed when the object is created.
**
** All bits are clear when the bitmap is created. Individual bits
** may be set or cleared one at a time.
** Bitvec object is the number of pages in the database file at the
** start of a transaction, and is thus usually less than a few thousand,
** but can be as large as 2 billion for a really big database.
+**
+** ## COLUMNSET
+**
+** The ColumnSet object represents a subset of the columns of a table that
+** are used by an SQL statement or an index. This information is used to
+** during query planning, and especially to help determine if an index will
+** be a covering index.
*/
#include "sqliteInt.h"
return rc;
}
#endif /* SQLITE_UNTESTABLE */
+
+
+/*
+** The pExpr argument is guaranteed to be a non-NULL Expr node of
+** type TK_COLUMN. Mark this column as used in pCSet.
+*/
+void sqlite3CSetAddExpr(ColumnSet *pCSet, const Expr *pExpr){
+ int n;
+ Table *pExTab;
+
+ assert( pExpr!=0 );
+ n = pExpr->iColumn;
+ assert( ExprUseYTab(pExpr) );
+ pExTab = pExpr->y.pTab;
+ assert( pExTab!=0 );
+ if( (pExTab->tabFlags & TF_HasGenerated)!=0
+ && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
+ ){
+ testcase( pExTab->nCol==BMS-1 );
+ testcase( pExTab->nCol==BMS );
+ pCSet->m |= (pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1);
+ }else{
+ testcase( n==BMS-1 );
+ testcase( n==BMS );
+ if( n>=BMS ) n = BMS-1;
+ pCSet->m |= ((Bitmask)1)<<n;
+ }
+}
+
+/*
+** Convert a ColumnSet into a finite-length bitmask.
+*/
+Bitmask sqlite3CSetToMask(const ColumnSet *pCSet){
+ return pCSet->m;
+}
if( x<BMS-1 ) m |= MASKBIT(x);
}
}
- pIdx->colNotIdxed = ~m;
- assert( (pIdx->colNotIdxed>>63)==1 );
+ pIdx->colNotIdxed.m = ~m;
+ assert( (pIdx->colNotIdxed.m>>63)==1 );
}
/*
}else{
pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
}
- pNewItem->colUsed = pOldItem->colUsed;
+ pNewItem->colUsed.m = pOldItem->colUsed.m;
}
return pNew;
}
}
}
-/*
-** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN.
-** return the appropriate colUsed mask.
-*/
-Bitmask sqlite3ExprColUsed(Expr *pExpr){
- int n;
- Table *pExTab;
-
- n = pExpr->iColumn;
- assert( ExprUseYTab(pExpr) );
- pExTab = pExpr->y.pTab;
- assert( pExTab!=0 );
- if( (pExTab->tabFlags & TF_HasGenerated)!=0
- && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
- ){
- testcase( pExTab->nCol==BMS-1 );
- testcase( pExTab->nCol==BMS );
- return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
- }else{
- testcase( n==BMS-1 );
- testcase( n==BMS );
- if( n>=BMS ) n = BMS-1;
- return ((Bitmask)1)<<n;
- }
-}
-
/*
** Create a new expression term for the column specified by pMatch and
** iColumn. Append this new expression term to the FULL JOIN Match set
}
/* If a column from a table in pSrcList is referenced, then record
- ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
- ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is
- ** set if the 63rd or any subsequent column is used.
+ ** this fact in pSrcList.a[].colUsed.
**
** The colUsed mask is an optimization used to help determine if an
** index is a covering index. The correct answer is still obtained
** of the table.
*/
if( pExpr->iColumn>=0 && pMatch!=0 ){
- pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
+ sqlite3CSetAddExpr(&pMatch->colUsed, pExpr);
}
pExpr->op = eNewExprOp;
){
testcase( pTab->nCol==63 );
testcase( pTab->nCol==64 );
- pItem->colUsed = pTab->nCol>=64 ? ALLBITS : MASKBIT(pTab->nCol)-1;
+ pItem->colUsed.m = pTab->nCol>=64 ? ALLBITS : MASKBIT(pTab->nCol)-1;
}else{
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
- pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
+ pItem->colUsed.m |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
}
}
}
pItem = pWalker->u.pSrcItem;
if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue;
if( pExpr->iColumn<0 ) return WRC_Continue;
- pItem->colUsed |= sqlite3ExprColUsed(pExpr);
+ sqlite3CSetAddExpr(&pItem->colUsed, pExpr);
return WRC_Continue;
}
static void recomputeColumnsUsed(
w.xExprCallback = recomputeColumnsUsedExpr;
w.xSelectCallback = sqlite3SelectWalkNoop;
w.u.pSrcItem = pSrcItem;
- pSrcItem->colUsed = 0;
+ pSrcItem->colUsed.m = 0;
sqlite3WalkSelect(&w, pSelect);
}
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
** assume the column name is non-NULL and segfault. The use of an empty
** string for the fake column name seems safer.
*/
- if( pItem->colUsed==0 && pItem->zName!=0 ){
+ if( pItem->colUsed.m==0 && pItem->zName!=0 ){
sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
}
typedef struct Bitvec Bitvec;
typedef struct CollSeq CollSeq;
typedef struct Column Column;
+typedef struct ColumnSet ColumnSet;
typedef struct Cte Cte;
typedef struct CteUse CteUse;
typedef struct Db Db;
u8 eqSeen; /* True if an equality comparison has been seen */
};
+/*
+** A ColumnSet object is used to indicate a subset of the columns in
+** a table that are used in an SQL statement or used by an Index.
+*/
+struct ColumnSet {
+ Bitmask m;
+};
+
/*
** Each SQL index is represented in memory by an
tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */
tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */
#endif
- Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */
+ ColumnSet colNotIdxed; /* 0 for unindexed columns in pTab */
};
/*
Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */
IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */
} u3;
- Bitmask colUsed; /* Bit N (1<<N) set if column N of pTab is used */
union {
char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" clause */
ExprList *pFuncArg; /* Arguments to table-valued-function */
Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */
} u2;
+ ColumnSet colUsed; /* Bit N (1<<N) set if column N of pTab is used */
};
/*
const char*,
const char*
);
-Bitmask sqlite3ExprColUsed(Expr*);
+void sqlite3CSetAddExpr(ColumnSet*,const Expr*);
+Bitmask sqlite3CSetToMask(const ColumnSet*);
u8 sqlite3StrIHash(const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
if( pItem->pTab ){
sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
- pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
+ pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab,
+ sqlite3CSetToMask(&pItem->colUsed));
}
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
** case, set all bits of the colUsed mask (to ensure that the virtual
** table implementation makes all columns available).
*/
- pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0;
+ pTabList->a[0].colUsed.m = IsVirtual(pTab) ? ALLBITS : 0;
hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
** original table changes and the index and table cannot both be used
** if they go out of sync.
*/
- extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
+ extraCols = pSrc->colUsed.m & (~idxCols | MASKBIT(BMS-1));
mxBitCol = MIN(BMS-1,pTable->nCol);
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; i<mxBitCol; i++){
if( extraCols & MASKBIT(i) ) nKeyCol++;
}
- if( pSrc->colUsed & MASKBIT(BMS-1) ){
+ if( pSrc->colUsed.m & MASKBIT(BMS-1) ){
nKeyCol += pTable->nCol - BMS + 1;
}
n++;
}
}
- if( pSrc->colUsed & MASKBIT(BMS-1) ){
+ if( pSrc->colUsed.m & MASKBIT(BMS-1) ){
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = sqlite3StrBINARY;
pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
m = 0;
}else{
- m = pSrc->colUsed & pProbe->colNotIdxed;
+ m = pSrc->colUsed.m & pProbe->colNotIdxed.m;
pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
}
pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
pIdxInfo->estimatedRows = 25;
pIdxInfo->idxFlags = 0;
- pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
+ pIdxInfo->colUsed = sqlite3CSetToMask(&pSrc->colUsed);
pHidden->mHandleIn = 0;
/* Invoke the virtual table xBestIndex() method */
}
if( j!=pIdx->nKeyCol ) continue;
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
- if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){
+ if( pIdx->isCovering || (pItem->colUsed.m & pIdx->colNotIdxed.m)==0 ){
pLoop->wsFlags |= WHERE_IDX_ONLY;
}
pLoop->nLTerm = j;
/* If we know that only a prefix of the record will be used,
** it is advantageous to reduce the "column count" field in
** the P4 operand of the OP_OpenRead/Write opcode. */
- Bitmask b = pTabItem->colUsed;
+ Bitmask b = pTabItem->colUsed.m;
int n = 0;
for(; b; b=b>>1, n++){}
sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32);
}
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0,
- (const u8*)&pTabItem->colUsed, P4_INT64);
+ (const u8*)&pTabItem->colUsed.m, P4_INT64);
#endif
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
jj = pIx->aiColumn[ii];
if( jj<0 ) continue;
if( jj>63 ) jj = 63;
- if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue;
+ if( (pTabItem->colUsed.m & MASKBIT(jj))==0 ) continue;
colUsed |= ((u64)1)<<(ii<63 ? ii : 63);
}
sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0,
pColRef->iColumn = k++;
assert( ExprUseYTab(pColRef) );
pColRef->y.pTab = pTab;
- pItem->colUsed |= sqlite3ExprColUsed(pColRef);
+ sqlite3CSetAddExpr(&pItem->colUsed, pColRef);
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);