From: drh <> Date: Fri, 21 Feb 2025 17:03:22 +0000 (+0000) Subject: Detect when a UNIQUE or PRIMARY KEY on a WITHOUT ROWID table would need X-Git-Tag: major-release~253 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ce25007db8df01e3271486574d520d4dea4cf97a;p=thirdparty%2Fsqlite.git Detect when a UNIQUE or PRIMARY KEY on a WITHOUT ROWID table would need to use more than SQLITE_LIMIT_COLUMN columns and raise an error. Also include some unrelated compiler warning fixes. FossilOrigin-Name: d7729dbbf231d57cbcaaa5004d0a9c4957f112dd6520052995b232aa521c0ca3 --- diff --git a/manifest b/manifest index 89f3436486..bb9dfef35a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure:\sin\sseveral\splaces\swhere\ssupport\sfor\s-Wl,...\slinker\sflags\sare\schecked,\sensure\sthat\sthe\scheck\sinvokes\sthe\slinker\s(not\sjust\sthe\scompiler)\sto\savoid\sfalse\spositives.\sThis\sallows\sus\sto\sremove\sthe\sAIX-specific\shandling\sand\s--disable-rpath\sbits\sadded\sin\s[a15e0f680],\sas\swell\sas\smake\sseveral\ssimilar\schecks\smore\srobust. -D 2025-02-21T03:19:21.417 +C Detect\swhen\sa\sUNIQUE\sor\sPRIMARY\sKEY\son\sa\sWITHOUT\sROWID\stable\swould\sneed\nto\suse\smore\sthan\sSQLITE_LIMIT_COLUMN\scolumns\sand\sraise\san\serror.\nAlso\sinclude\ssome\sunrelated\scompiler\swarning\sfixes. +D 2025-02-21T17:03:22.433 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d @@ -715,7 +715,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 -F src/alter.c 1751e231d8385067fa0d0145f0d461a092db6bd3d7edbfc3172db625aceccd9a +F src/alter.c 04cad1defb7262937e586b0529f3a524ac825aa283341e326546cf08de35b209 F src/analyze.c 6d27b425a16817975e6a4f8501e531d13dd1bf4b53bff2329dbc1f301aeef82d F src/attach.c c36d9d82811e2274bd06bf3b34459e36d8ae8a7f32efa5cbf3f890eef08a9987 F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc @@ -725,14 +725,14 @@ F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 F src/btree.c 9316859aa5f14bde4a3719ffb1570219e51c5de433221e38b87ea19db868aedf F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 98aadb6dcb77b012cab2574d6a728fad56b337fc946839b9898c4b4c969e30b6 -F src/build.c 2fa35745a279e2a17eec6df67a3cd35d456c136a7f5c75e80bdd6c5658423b60 +F src/build.c c2bcfc7e5072a743a051699f06329ee206299729adf4323fed9be8aa2d64af73 F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/date.c 842c08ac143a56a627b05ac51d68624f2b7b03e3b4cba596205e735eed64ee57 F src/dbpage.c 2e677acb658a29965e55398bbc61161cb7819da538057c8032adac7ab8e4a8c0 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 6e0635f3e3761f368d10e77d26d29a1a521ab208f1be66e84c13354ffbcf5ad2 +F src/expr.c 6769d3f0ca9b1792e883e3ff21fdc5ca0033cece65571ebbf9d8b8fe2f47cd27 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 6c8b7bbdc5b588f3cfc79ed5effcfd3031758f5034c464fcd8891e8010b4d317 @@ -741,7 +741,7 @@ F src/hash.c 73934a7f7ab1cb110614a9388cb516893b0cf5b7b69e4fd1a0780ac4ce166be7 F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 05e04ef637cbc0dccb9a5c5d188a5a2608891e554c8ec17c7a71afe2cf896a06 +F src/insert.c a5f0366266be993ebf533808f22cb7a788624805b55bc45424ceed3f48c54a16 F src/json.c 5abb5cb782e74451a8882f6b7ee4d5e629246642262660bd1980a5e1b796258d F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 @@ -771,7 +771,7 @@ F src/os_win.c 2423a45e70c2cda01bfc84106f7e9f34feb1add42121ab2e35a67ba24589ac52 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 8d73e7a0ebbecd8bb4996ff285cc055cec56b7e3edb5a4609d0748e0fa39d28a F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 -F src/parse.y f84673f1454e2bcf517623d4346e67fb2d73e57826ea103681ad5848238f6029 +F src/parse.y 4e62b0b301673d404b8aff7c9d84ee8636e5ff59f45c90cdce4c8845a1289837 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 78d4935e510f7bed0fdd1a3f742c0e663b36a795f9dc7411161dc22bdae1245e @@ -781,14 +781,14 @@ F src/printf.c b9ac740dfaf68552f5da1266be28ae2824b53a6b73d93425f7c6b2ef62457cbb F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 626c24b258b111f75c22107aa5614ad89810df3026f5ca071116d3fe75925c75 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 57893cc8b099f231f7ed5b84faff14841f2aabb4776e32e17fae00aeae0a8993 +F src/select.c a076f7db3a0fcbd9f710d7746cfc07e0b3baadee45eb3136bedc29c598ef8f1c F src/shell.c.in bf997e43faaa1ef0ff78d4d7b9be6a9430cf1edda9a47a14e7fef646fcb459af F src/sqlite.h.in 8d4486fb28a90de818ac1e8c6206ea458e7de6bd8e0dfa3d554494f155be8c01 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h 020aff180111b7dfe5bbdf8e59e8595c195b956488e9ca955f876cb7482e6de5 -F src/sqliteLimit.h 1bbdbf72bd0411d003267ffebc59a262f061df5653027a75627d03f48ca30523 -F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b +F src/sqliteInt.h a5c850981cff99331b2ed48d519fb54a47f5f91c680e2cab64d91e259685de69 +F src/sqliteLimit.h b963c1e8c48791cc5cf733bb33e4741d0fbb7d0650cc2344cce5e4c17be4e8fd +F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 5c1e367e26711044730c93d4b81312170918a8d1fe811f45be740ab48f7de8c1 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 @@ -869,7 +869,7 @@ F src/where.c 09dc313e7223ca1217c39c7026b00f16ff449a8323511a762fcba7863a00f4cd F src/whereInt.h d20cddddb1d61b18d5cb1fcfa9b77fbeebbc4afe44d996e603452a23b3009ee1 F src/wherecode.c 5baa06f0daae7d38aca1d4814030b82ad4f127fe6bad18f0644776a474f6088b F src/whereexpr.c 2415c8eee5ff89a8b709d7d83d71c1ff986cd720d0520057e1d8a5371339012a -F src/window.c 2bf01f9941a64fbcead61a0e3cb5db3fca5094b30d2ff0d23274c2a81d2e2385 +F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9 @@ -2095,7 +2095,7 @@ F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f1982 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 F test/with6.test 281e4861b5e517f6c3c2f08517a520c1e2ee7c11966545d3901f258a4fe8ef76 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 -F test/without_rowid1.test a5210b8770dc4736bca4e74bc96588f43025ad03ad6a80f885afd36d9890e217 +F test/without_rowid1.test 7120af676485e68930d3e513d083f3644622893477901f55eec954387125d550 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test 39ab0dd773eaa62e59b17093f875327630f54c4145458f6d2b053d68d4b2f67b F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a @@ -2210,8 +2210,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a15e0f6802a5ba7bc5a7a70d6a162ea4548b49b132a5ac31263e64c388bbafcb -R 42c23a2d2b7be27c2c7a4de01b0af4e3 -U stephan -Z 369390f432e27c3785cf51965afea95c +P 4e81e2c707a954dcda6219dc94e2b96dd0c9907bd4beab28adad51d488b7d739 +R 92107357485b715229de5818697d5fcf +U drh +Z 4c75b5945df64c93f9907a88e623cba4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9eb88d3ff..6c0f837bd5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e81e2c707a954dcda6219dc94e2b96dd0c9907bd4beab28adad51d488b7d739 +d7729dbbf231d57cbcaaa5004d0a9c4957f112dd6520052995b232aa521c0ca3 diff --git a/src/alter.c b/src/alter.c index 5f706b513f..3c8a6c3a18 100644 --- a/src/alter.c +++ b/src/alter.c @@ -531,13 +531,13 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); - pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); + pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*(u32)nAlloc); pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); if( !pNew->aCol || !pNew->zName ){ assert( db->mallocFailed ); goto exit_begin_add_column; } - memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); + memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*(size_t)pNew->nCol); for(i=0; inCol; i++){ Column *pCol = &pNew->aCol[i]; pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); @@ -1144,7 +1144,13 @@ static int renameParseSql( if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ return SQLITE_CORRUPT_BKPT; } - db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + if( bTemp ){ + db->init.iDb = 1; + }else{ + int iDb = sqlite3FindDbName(db, zDb); + assert( iDb>=0 && iDb<=0xff ); + db->init.iDb = (u8)iDb; + } p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; @@ -1211,10 +1217,11 @@ static int renameEditSql( nQuot = sqlite3Strlen30(zQuot)-1; } - assert( nQuot>=nNew ); - zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); + assert( nQuot>=nNew && nSql>0 && nNew>0 ); + zOut = sqlite3DbMallocZero(db, (u64)(nSql + pRename->nList*nQuot + 1)); }else{ - zOut = (char*)sqlite3DbMallocZero(db, (nSql*2+1) * 3); + assert( nSql>0 ); + zOut = (char*)sqlite3DbMallocZero(db, (u64)(nSql*2+1) * 3); if( zOut ){ zBuf1 = &zOut[nSql*2+1]; zBuf2 = &zOut[nSql*4+2]; @@ -1226,16 +1233,17 @@ static int renameEditSql( ** with the new column name, or with single-quoted versions of themselves. ** All that remains is to construct and return the edited SQL string. */ if( zOut ){ - int nOut = nSql; - memcpy(zOut, zSql, nSql); + i64 nOut = nSql; + assert( nSql>0 ); + memcpy(zOut, zSql, (size_t)nSql); while( pRename->pList ){ int iOff; /* Offset of token to replace in zOut */ - u32 nReplace; + i64 nReplace; const char *zReplace; RenameToken *pBest = renameColumnTokenNext(pRename); if( zNew ){ - if( bQuote==0 && sqlite3IsIdChar(*pBest->t.z) ){ + if( bQuote==0 && sqlite3IsIdChar(*(u8*)pBest->t.z) ){ nReplace = nNew; zReplace = zNew; }else{ @@ -1547,7 +1555,7 @@ static void renameColumnFunc( if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; - pSelect->selFlags &= ~SF_View; + pSelect->selFlags &= ~(u32)SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); @@ -1765,7 +1773,7 @@ static void renameTableFunc( sNC.pParse = &sParse; assert( pSelect->selFlags & SF_View ); - pSelect->selFlags &= ~SF_View; + pSelect->selFlags &= ~(u32)SF_View; sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); if( sParse.nErr ){ rc = sParse.rc; @@ -1938,7 +1946,7 @@ static void renameQuotefixFunc( if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; - pSelect->selFlags &= ~SF_View; + pSelect->selFlags &= ~(u32)SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); diff --git a/src/build.c b/src/build.c index 986201bfb4..18bf27b833 100644 --- a/src/build.c +++ b/src/build.c @@ -1067,10 +1067,16 @@ Index *sqlite3PrimaryKeyIndex(Table *pTab){ ** find the (first) offset of that column in index pIdx. Or return -1 ** if column iCol is not used in index pIdx. */ -i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ +i16 sqlite3TableColumnToIndex(Index *pIdx, int iCol){ int i; + i16 iCol16; + assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN ); + assert( pIdx->nColumn<=SQLITE_MAX_COLUMN ); + iCol16 = iCol; for(i=0; inColumn; i++){ - if( iCol==pIdx->aiColumn[i] ) return i; + if( iCol16==pIdx->aiColumn[i] ){ + return i; + } } return -1; } @@ -2167,10 +2173,16 @@ static char *createTableStmt(sqlite3 *db, Table *p){ ** Resize an Index object to hold N columns total. Return SQLITE_OK ** on success and SQLITE_NOMEM on an OOM error. */ -static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ +static int resizeIndexObject(Parse *pParse, Index *pIdx, int N){ char *zExtra; int nByte; + sqlite3 *db; if( pIdx->nColumn>=N ) return SQLITE_OK; + db = pParse->db; + if( N>db->aLimit[SQLITE_LIMIT_COLUMN] ){ + sqlite3ErrorMsg(pParse, "too many columns on %s", pIdx->zName); + return SQLITE_ERROR; + } assert( pIdx->isResized==0 ); nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N; zExtra = sqlite3DbMallocZero(db, nByte); @@ -2440,7 +2452,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ pIdx->nColumn = pIdx->nKeyCol; continue; } - if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return; + if( resizeIndexObject(pParse, pIdx, pIdx->nKeyCol+n) ) return; for(i=0, j=pIdx->nKeyCol; inKeyCol, pPk, i) ){ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); @@ -2464,7 +2476,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( !hasColumn(pPk->aiColumn, nPk, i) && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++; } - if( resizeIndexObject(db, pPk, nPk+nExtra) ) return; + if( resizeIndexObject(pParse, pPk, nPk+nExtra) ) return; for(i=0, j=nPk; inCol; i++){ if( !hasColumn(pPk->aiColumn, j, i) && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 diff --git a/src/expr.c b/src/expr.c index 0f86e126de..f6b5729b4b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1963,7 +1963,7 @@ Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){ pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->iLimit = 0; pNew->iOffset = 0; - pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; + pNew->selFlags = p->selFlags & ~(u32)SF_UsesEphemeral; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; diff --git a/src/insert.c b/src/insert.c index c1ca1897ed..7dc9bfd8b1 100644 --- a/src/insert.c +++ b/src/insert.c @@ -693,7 +693,7 @@ Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ f = (f & pLeft->selFlags); } pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); - pLeft->selFlags &= ~SF_MultiValue; + pLeft->selFlags &= ~(u32)SF_MultiValue; if( pSelect ){ pSelect->op = TK_ALL; pSelect->pPrior = pLeft; diff --git a/src/parse.y b/src/parse.y index 76c9a8e4ed..65a15f8c49 100644 --- a/src/parse.y +++ b/src/parse.y @@ -617,8 +617,8 @@ selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). { if( pRhs ){ pRhs->op = (u8)Y; pRhs->pPrior = pLhs; - if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; - pRhs->selFlags &= ~SF_MultiValue; + if( ALWAYS(pLhs) ) pLhs->selFlags &= ~(u32)SF_MultiValue; + pRhs->selFlags &= ~(u32)SF_MultiValue; if( Y!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); diff --git a/src/select.c b/src/select.c index e47a9b6be2..e7db195333 100644 --- a/src/select.c +++ b/src/select.c @@ -5646,7 +5646,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ #ifndef SQLITE_OMIT_WINDOWFUNC p->pWinDefn = 0; #endif - p->selFlags &= ~SF_Compound; + p->selFlags &= ~(u32)SF_Compound; assert( (p->selFlags & SF_Converted)==0 ); p->selFlags |= SF_Converted; assert( pNew->pPrior!=0 ); @@ -7252,7 +7252,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pSub->pPrior = 0; pSub->pNext = 0; pSub->selFlags |= SF_Aggregate; - pSub->selFlags &= ~SF_Compound; + pSub->selFlags &= ~(u32)SF_Compound; pSub->nSelectRow = 0; sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; @@ -7267,7 +7267,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pSub = pPrior; } p->pEList->a[0].pExpr = pExpr; - p->selFlags &= ~SF_Aggregate; + p->selFlags &= ~(u32)SF_Aggregate; #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x200 ){ @@ -7474,7 +7474,7 @@ int sqlite3Select( testcase( pParse->earlyCleanup ); p->pOrderBy = 0; } - p->selFlags &= ~SF_Distinct; + p->selFlags &= ~(u32)SF_Distinct; p->selFlags |= SF_NoopOrderBy; } sqlite3SelectPrep(pParse, p, 0); @@ -7513,7 +7513,7 @@ int sqlite3Select( ** and leaving this flag set can cause errors if a compound sub-query ** in p->pSrc is flattened into this query and this function called ** again as part of compound SELECT processing. */ - p->selFlags &= ~SF_UFSrcCheck; + p->selFlags &= ~(u32)SF_UFSrcCheck; } if( pDest->eDest==SRT_Output ){ @@ -8002,7 +8002,7 @@ int sqlite3Select( && p->pWin==0 #endif ){ - p->selFlags &= ~SF_Distinct; + p->selFlags &= ~(u32)SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); if( pGroupBy ){ for(i=0; inExpr; i++){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6ebd8eb4fe..d4b9983091 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3097,10 +3097,10 @@ struct Expr { /* Macros can be used to test, set, or clear bits in the ** Expr.flags field. */ -#define ExprHasProperty(E,P) (((E)->flags&(P))!=0) -#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) -#define ExprSetProperty(E,P) (E)->flags|=(P) -#define ExprClearProperty(E,P) (E)->flags&=~(P) +#define ExprHasProperty(E,P) (((E)->flags&(u32)(P))!=0) +#define ExprHasAllProperty(E,P) (((E)->flags&(u32)(P))==(u32)(P)) +#define ExprSetProperty(E,P) (E)->flags|=(u32)(P) +#define ExprClearProperty(E,P) (E)->flags&=~(u32)(P) #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) #define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) @@ -4908,7 +4908,7 @@ void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); void sqlite3OpenSchemaTable(Parse *, int); Index *sqlite3PrimaryKeyIndex(Table*); -i16 sqlite3TableColumnToIndex(Index*, i16); +i16 sqlite3TableColumnToIndex(Index*, int); #ifdef SQLITE_OMIT_GENERATED_COLUMNS # define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ # define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index 620b0f8e5a..0d15b31822 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -36,14 +36,16 @@ ** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. ** * Terms in the VALUES clause of an INSERT statement ** -** The hard upper limit here is 32676. Most database people will +** The hard upper limit here is 32767. Most database people will ** tell you that in a well-normalized database, you usually should ** not have more than a dozen or so columns in any table. And if ** that is the case, there is no point in having more than a few ** dozen values in any of the other situations described above. */ -#ifndef SQLITE_MAX_COLUMN +#if !defined(SQLITE_MAX_COLUMN) # define SQLITE_MAX_COLUMN 2000 +#elif SQLITE_MAX_COLUMN>32767 +# error SQLITE_MAX_COLUMN may not exceed 32767 #endif /* diff --git a/src/status.c b/src/status.c index a462c94293..b0a47c7f85 100644 --- a/src/status.c +++ b/src/status.c @@ -192,8 +192,9 @@ int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ nInit += countLookasideSlots(db->lookaside.pSmallInit); nFree += countLookasideSlots(db->lookaside.pSmallFree); #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ - if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit; - return db->lookaside.nSlot - (nInit+nFree); + assert( db->lookaside.nSlot >= nInit+nFree ); + if( pHighwater ) *pHighwater = (int)(db->lookaside.nSlot - nInit); + return (int)(db->lookaside.nSlot - (nInit+nFree)); } /* @@ -246,7 +247,7 @@ int sqlite3_db_status( assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); *pCurrent = 0; - *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; + *pHighwater = (int)db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT]; if( resetFlag ){ db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; } diff --git a/src/window.c b/src/window.c index 8373e36413..948b0728af 100644 --- a/src/window.c +++ b/src/window.c @@ -995,7 +995,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ p->pWhere = 0; p->pGroupBy = 0; p->pHaving = 0; - p->selFlags &= ~SF_Aggregate; + p->selFlags &= ~(u32)SF_Aggregate; p->selFlags |= SF_WinRewrite; /* Create the ORDER BY clause for the sub-select. This is the concatenation diff --git a/test/without_rowid1.test b/test/without_rowid1.test index 3c33f733a1..0095fab0c0 100644 --- a/test/without_rowid1.test +++ b/test/without_rowid1.test @@ -487,4 +487,24 @@ ifcapable altertable { SELECT name FROM sqlite_sequence ORDER BY +name; } {a c0 c2} } + +# Ensure that the number of columns in an index on a WITHOUT ROWID +# table does not exceed SQLITE_LIMIT_COLUMN. +# +reset_db +sqlite3_limit db SQLITE_LIMIT_COLUMN 8 +do_catchsql_test 16.1 { + CREATE TABLE t1( + c1,c2,c3,c4,c5,c6,c7,c8, + PRIMARY KEY(c1,c2,c1 COLLATE NOCASE) + ) WITHOUT ROWID; +} {1 {too many columns on sqlite_autoindex_t1_1}} +do_catchsql_test 16.2 { + CREATE TABLE t1( + c1,c2,c3,c4,c5,c6,c7,c8, + PRIMARY KEY(c1,c2), + UNIQUE(c3,c4,c5,c6,c7,c8,c3 COLLATE nocase) + ) WITHOUT ROWID; +} {1 {too many columns on sqlite_autoindex_t1_2}} + finish_test