From a4741840f617abeda899dc5491bea582f0733c2e Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 25 Apr 2010 20:58:37 +0000 Subject: [PATCH 1/6] Remove an unreachable branch from the function initialization logic. FossilOrigin-Name: 064d3ddd6199b7b049b1706974e4295f78fb5ab9 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/func.c | 16 +++++++--------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 2c22758bdf..a99faf14fc 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C When\scommands\ssuch\sas\sALTER\sTABLE\sand\sVACUUM\suse\sSQL\sinternally,\smake\ssure\nthey\suse\sonly\sthe\sbuilt-in\sfunctions\sand\snot\sapplication-defined\soverrides\nfor\sthose\sfunctions. -D 2010-04-24T14:02:59 +C Remove\san\sunreachable\sbranch\sfrom\sthe\sfunction\sinitialization\slogic. +D 2010-04-25T20:58:37 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -124,7 +124,7 @@ F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581 F src/expr.c 6baed2a0448d494233d9c0a610eea018ab386a32 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2116672a6bd610dc888e27df292ebc7999c9bb0 -F src/func.c b4af81088b1ad2ceea42d70a7aa048a48d18733f +F src/func.c 0c28599430856631216b6c0131c51c89bf516026 F src/global.c 5a9c1e3c93213ca574786ac1caa976ce8f709105 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 @@ -801,14 +801,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e79dac3c2f723ed7cc62fcef468f53952711f242 -R f7b3f2f2586b016425d2ff4d0aa6d5e4 +P 0291ed974d5bf1e344e2c38422530cc961b897da +R fd6e4addad7e1a8279cfaf819615b3fa U drh -Z 60e8a7849ac5e43c2a7c878285e8be5d +Z 7d20f9f474a13977b8eb713940e9f8af -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFL0voooxKgR168RlERAuygAJ9JZEPkPJWwA9gu3SJJpCJ6uLWSCACfXJK2 -t7ZFFTqEHyFHDlhkRqjBdIY= -=45i3 +iD8DBQFL1Kz/oxKgR168RlERAgG0AJoDjmhXedAET5V0L1Z5n0cXBHnSMwCff/bm +c8fjZiKrCLhVKjzQJ+FPaRw= +=pPi4 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index d37c175bb5..ccbbcfba66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0291ed974d5bf1e344e2c38422530cc961b897da \ No newline at end of file +064d3ddd6199b7b049b1706974e4295f78fb5ab9 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 7bd3d58fa4..8b1b2f71f6 100644 --- a/src/func.c +++ b/src/func.c @@ -1411,17 +1411,15 @@ static void groupConcatFinalize(sqlite3_context *context){ } /* -** This function registered all of the above C functions as SQL -** functions. This should be the only routine in this file with -** external linkage. +** This routine does per-connection function registration. Most +** of the built-in functions above are part of the global function set. +** This routine only deals with those that are not global. */ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ - if( !db->mallocFailed ){ - int rc = sqlite3_overload_function(db, "MATCH", 2); - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); - if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; - } + int rc = sqlite3_overload_function(db, "MATCH", 2); + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; } } From 562cedb185849f8985c0ba1ce1fb6be167aca4c9 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Apr 2010 15:44:07 +0000 Subject: [PATCH 2/6] Enhancements to the showdb.c utility program. Automatically detect the page size and adjust the display accordingly. Add the "dbheader" display option. FossilOrigin-Name: 23eb408b5d08b89b41aaf245a7be8e235f30af8a --- manifest | 18 ++--- manifest.uuid | 2 +- tool/showdb.c | 179 +++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 174 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index a99faf14fc..43c5db3d5b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Remove\san\sunreachable\sbranch\sfrom\sthe\sfunction\sinitialization\slogic. -D 2010-04-25T20:58:37 +C Enhancements\sto\sthe\sshowdb.c\sutility\sprogram.\s\sAutomatically\sdetect\sthe\npage\ssize\sand\sadjust\sthe\sdisplay\saccordingly.\s\sAdd\sthe\s"dbheader"\sdisplay\noption. +D 2010-04-26T15:44:07 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -790,7 +790,7 @@ F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/shell1.test ef08a3e738b9fee4fc228920956950bc35db0575 F tool/shell2.test 8f51f61c13b88618e71c17439fe0847c2421c5d1 F tool/shell3.test ff663e83100670a295d473515c12beb8103a78b6 -F tool/showdb.c 8ab8b3b53884312aafb7ef60982e255a6c31d238 +F tool/showdb.c f36a0d6250cd66da80c70c5f68db504b6004ffae F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b @@ -801,14 +801,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 0291ed974d5bf1e344e2c38422530cc961b897da -R fd6e4addad7e1a8279cfaf819615b3fa +P 064d3ddd6199b7b049b1706974e4295f78fb5ab9 +R 8b381715211fe751bde39cc29f2ff9cd U drh -Z 7d20f9f474a13977b8eb713940e9f8af +Z 764a1f25e347ea0d4e5e531b573f483f -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFL1Kz/oxKgR168RlERAgG0AJoDjmhXedAET5V0L1Z5n0cXBHnSMwCff/bm -c8fjZiKrCLhVKjzQJ+FPaRw= -=pPi4 +iD8DBQFL1bTKoxKgR168RlERAo5cAJ9Eb+lGq+Qu8+YZ7K+hoPtgssOPdwCfc3aA +gSmF+BvN/QcbZjim662ior8= +=k+Sx -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index ccbbcfba66..5f6a0740c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -064d3ddd6199b7b049b1706974e4295f78fb5ab9 \ No newline at end of file +23eb408b5d08b89b41aaf245a7be8e235f30af8a \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index 26e7ea2be2..d8f9d79d81 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -8,41 +8,174 @@ #include #include #include +#include -static int pagesize = 1024; -static int db = -1; -static int mxPage = 0; -static int perLine = 32; +static int pagesize = 1024; /* Size of a database page */ +static int db = -1; /* File descriptor for reading the DB */ +static int mxPage = 0; /* Last page number */ +static int perLine = 16; /* HEX elements to print per line */ +typedef long long int i64; /* Datatype for 64-bit integers */ + + +/* +** Convert the var-int format into i64. Return the number of bytes +** in the var-int. Write the var-int value into *pVal. +*/ +static int decodeVarint(const char *z, i64 *pVal){ + i64 v = 0; + int i = 0; + while( i<8 ){ + v = (v<<7) + (z[i]&0x7f); + if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; } + } + v = (v<<8) + (z[i]&0xff); + *pVal = v; + return 9; +} + +/* Report an out-of-memory error and die. +*/ static void out_of_memory(void){ fprintf(stderr,"Out of memory...\n"); exit(1); } -static print_page(int iPg){ +/* +** Read content from the file. +** +** Space to hold the content is obtained from malloc() and needs to be +** freed by the caller. +*/ +static unsigned char *getContent(int ofst, int nByte){ + unsigned char *aData; + aData = malloc(nByte); + if( aData==0 ) out_of_memory(); + lseek(db, ofst, SEEK_SET); + read(db, aData, nByte); + return aData; +} + +/* +** Print a range of bytes as hex and as ascii. +*/ +static unsigned char *print_byte_range( + int ofst, /* First byte in the range of bytes to print */ + int nByte, /* Number of bytes to print */ + int printOfst /* Add this amount to the index on the left column */ +){ unsigned char *aData; int i, j; - aData = malloc(pagesize); - if( aData==0 ) out_of_memory(); - lseek(db, (iPg-1)*(long long int)pagesize, SEEK_SET); - read(db, aData, pagesize); - fprintf(stdout, "Page %d:\n", iPg); - for(i=0; inByte ){ + fprintf(stdout, " "); + }else{ + fprintf(stdout,"%02x ", aData[i+j]); + } } for(j=0; jnByte ){ + fprintf(stdout, " "); + }else{ + fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.'); + } } fprintf(stdout,"\n"); } + return aData; +} + +/* +** Print an entire page of content as hex +*/ +static print_page(int iPg){ + int iStart; + unsigned char *aData; + iStart = (iPg-1)*pagesize; + fprintf(stdout, "Page %d: (offsets 0x%x..0x%x)\n", + iPg, iStart, iStart+pagesize-1); + aData = print_byte_range(iStart, pagesize, 0); free(aData); } +/* Print a line of decode output showing a 4-byte integer. +*/ +static print_decode_line( + unsigned char *aData, /* Content being decoded */ + int ofst, int nByte, /* Start and size of decode */ + const char *zMsg /* Message to append */ +){ + int i, j; + int val = aData[ofst]; + char zBuf[100]; + sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]); + i = strlen(zBuf); + for(j=1; j<4; j++){ + if( j>=nByte ){ + sprintf(&zBuf[i], " "); + }else{ + sprintf(&zBuf[i], " %02x", aData[ofst+j]); + val = val*256 + aData[ofst+j]; + } + i += strlen(&zBuf[i]); + } + sprintf(&zBuf[i], " %9d", val); + printf(" %s %s\n", zBuf, zMsg); +} + +/* +** Decode the database header. +*/ +static print_db_header(void){ + unsigned char *aData; + aData = print_byte_range(0, 100, 0); + printf("Decoded:\n"); + print_decode_line(aData, 16, 2, "Database page size"); + print_decode_line(aData, 18, 1, "File format write version"); + print_decode_line(aData, 19, 1, "File format read version"); + print_decode_line(aData, 20, 1, "Reserved space at end of page"); + print_decode_line(aData, 24, 4, "File change counter"); + print_decode_line(aData, 28, 4, "Size of database in pages"); + print_decode_line(aData, 32, 4, "Page number of first freelist page"); + print_decode_line(aData, 36, 4, "Number of freelist pages"); + print_decode_line(aData, 40, 4, "Schema cookie"); + print_decode_line(aData, 44, 4, "Schema format version"); + print_decode_line(aData, 48, 4, "Default page cache size"); + print_decode_line(aData, 52, 4, "Largest auto-vac root page"); + print_decode_line(aData, 56, 4, "Text encoding"); + print_decode_line(aData, 60, 4, "User version"); + print_decode_line(aData, 64, 4, "Incremental-vacuum mode"); + print_decode_line(aData, 68, 4, "meta[7]"); + print_decode_line(aData, 72, 4, "meta[8]"); + print_decode_line(aData, 76, 4, "meta[9]"); + print_decode_line(aData, 80, 4, "meta[10]"); + print_decode_line(aData, 84, 4, "meta[11]"); + print_decode_line(aData, 88, 4, "meta[12]"); + print_decode_line(aData, 92, 4, "meta[13]"); + print_decode_line(aData, 96, 4, "meta[14]"); +} + int main(int argc, char **argv){ struct stat sbuf; + unsigned char zPgSz[2]; if( argc<2 ){ fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]); exit(1); @@ -52,8 +185,16 @@ int main(int argc, char **argv){ fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); exit(1); } + zPgSz[0] = 0; + zPgSz[1] = 0; + lseek(db, 16, SEEK_SET); + read(db, zPgSz, 2); + pagesize = zPgSz[0]*256 + zPgSz[1]; + if( pagesize==0 ) pagesize = 1024; + printf("Pagesize: %d\n", pagesize); fstat(db, &sbuf); - mxPage = sbuf.st_size/pagesize + 1; + mxPage = sbuf.st_size/pagesize; + printf("Available pages: 1..%d\n", mxPage); if( argc==2 ){ int i; for(i=1; i<=mxPage; i++) print_page(i); @@ -62,6 +203,14 @@ int main(int argc, char **argv){ for(i=2; i Date: Mon, 26 Apr 2010 16:47:12 +0000 Subject: [PATCH 3/6] Further enhancements to the showdb utility: A page number followed by "b" causes a btree decoding to occur on the page. FossilOrigin-Name: 2ff824e58ce8b8f605c809ac960dcbfc51c30e30 --- manifest | 18 +++++----- manifest.uuid | 2 +- tool/showdb.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 103 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 43c5db3d5b..5120eee056 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Enhancements\sto\sthe\sshowdb.c\sutility\sprogram.\s\sAutomatically\sdetect\sthe\npage\ssize\sand\sadjust\sthe\sdisplay\saccordingly.\s\sAdd\sthe\s"dbheader"\sdisplay\noption. -D 2010-04-26T15:44:07 +C Further\senhancements\sto\sthe\sshowdb\sutility:\s\sA\spage\snumber\sfollowed\sby\s"b"\ncauses\sa\sbtree\sdecoding\sto\soccur\son\sthe\spage. +D 2010-04-26T16:47:13 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -790,7 +790,7 @@ F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/shell1.test ef08a3e738b9fee4fc228920956950bc35db0575 F tool/shell2.test 8f51f61c13b88618e71c17439fe0847c2421c5d1 F tool/shell3.test ff663e83100670a295d473515c12beb8103a78b6 -F tool/showdb.c f36a0d6250cd66da80c70c5f68db504b6004ffae +F tool/showdb.c 4ab96e7f501e5423d5b7ac34504afd3834dbf3ce F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b @@ -801,14 +801,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 064d3ddd6199b7b049b1706974e4295f78fb5ab9 -R 8b381715211fe751bde39cc29f2ff9cd +P 23eb408b5d08b89b41aaf245a7be8e235f30af8a +R 933a436d34fb2f67d252b6f2eef7208a U drh -Z 764a1f25e347ea0d4e5e531b573f483f +Z f61ced08bbb9a853a64647c8b442a2d5 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFL1bTKoxKgR168RlERAo5cAJ9Eb+lGq+Qu8+YZ7K+hoPtgssOPdwCfc3aA -gSmF+BvN/QcbZjim662ior8= -=k+Sx +iD8DBQFL1cOUoxKgR168RlERAvg3AJsFJVG93QKIMPjRrMQew07/kDOloACgjMdv +7XmPQv5MjnYy+cdiQdmjRsk= +=SfZz -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 5f6a0740c2..cf2caab397 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23eb408b5d08b89b41aaf245a7be8e235f30af8a \ No newline at end of file +2ff824e58ce8b8f605c809ac960dcbfc51c30e30 \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index d8f9d79d81..ac537682ef 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -23,10 +23,10 @@ typedef long long int i64; /* Datatype for 64-bit integers */ ** Convert the var-int format into i64. Return the number of bytes ** in the var-int. Write the var-int value into *pVal. */ -static int decodeVarint(const char *z, i64 *pVal){ +static int decodeVarint(const unsigned char *z, i64 *pVal){ i64 v = 0; - int i = 0; - while( i<8 ){ + int i; + for(i=0; i<8; i++){ v = (v<<7) + (z[i]&0x7f); if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; } } @@ -138,13 +138,13 @@ static print_decode_line( i += strlen(&zBuf[i]); } sprintf(&zBuf[i], " %9d", val); - printf(" %s %s\n", zBuf, zMsg); + printf("%s %s\n", zBuf, zMsg); } /* ** Decode the database header. */ -static print_db_header(void){ +static void print_db_header(void){ unsigned char *aData; aData = print_byte_range(0, 100, 0); printf("Decoded:\n"); @@ -173,6 +173,79 @@ static print_db_header(void){ print_decode_line(aData, 96, 4, "meta[14]"); } +/* +** Create a description for a single cell. +*/ +static int describeCell(unsigned char cType, unsigned char *a, char **pzDesc){ + int i; + int nDesc = 0; + int n = 0; + int leftChild; + i64 nPayload; + i64 rowid; + static char zDesc[100]; + i = 0; + if( cType<=5 ){ + leftChild = ((a[0]*256 + a[1])*256 + a[2])*256 + a[3]; + a += 4; + n += 4; + sprintf(zDesc, "left-child: %d ", leftChild); + nDesc = strlen(zDesc); + } + if( cType!=5 ){ + i = decodeVarint(a, &nPayload); + a += i; + n += i; + sprintf(&zDesc[nDesc], "sz: %lld ", nPayload); + nDesc += strlen(&zDesc[nDesc]); + } + if( cType==5 || cType==13 ){ + i = decodeVarint(a, &rowid); + a += i; + n += i; + sprintf(&zDesc[nDesc], "rowid: %lld ", rowid); + nDesc += strlen(&zDesc[nDesc]); + } + *pzDesc = zDesc; + return n; +} + +/* +** Decode a btree page +*/ +static void decode_btree_page(unsigned char *a, int pgno, int hdrSize){ + const char *zType = "unknown"; + int nCell; + int i; + int iCellPtr; + switch( a[0] ){ + case 2: zType = "index interior node"; break; + case 5: zType = "table interior node"; break; + case 10: zType = "index leaf"; break; + case 13: zType = "table leaf"; break; + } + printf("Decode of btree page %d:\n", pgno); + print_decode_line(a, 0, 1, zType); + print_decode_line(a, 1, 2, "Offset to first freeblock"); + print_decode_line(a, 3, 2, "Number of cells on this page"); + nCell = a[3]*256 + a[4]; + print_decode_line(a, 5, 2, "Offset to cell content area"); + print_decode_line(a, 7, 1, "Fragmented byte count"); + if( a[0]==2 || a[0]==5 ){ + print_decode_line(a, 8, 4, "Right child"); + iCellPtr = 12; + }else{ + iCellPtr = 8; + } + for(i=0; i Date: Mon, 26 Apr 2010 17:30:52 +0000 Subject: [PATCH 4/6] Identify the SQLite version meta-value entry in the db-header output of showdb. FossilOrigin-Name: 245d934b72cbc6e897193e7892195b6561995939 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- tool/showdb.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 5120eee056..53259d8b71 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Further\senhancements\sto\sthe\sshowdb\sutility:\s\sA\spage\snumber\sfollowed\sby\s"b"\ncauses\sa\sbtree\sdecoding\sto\soccur\son\sthe\spage. -D 2010-04-26T16:47:13 +C Identify\sthe\sSQLite\sversion\smeta-value\sentry\sin\sthe\sdb-header\soutput\sof\nshowdb. +D 2010-04-26T17:30:53 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -790,7 +790,7 @@ F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/shell1.test ef08a3e738b9fee4fc228920956950bc35db0575 F tool/shell2.test 8f51f61c13b88618e71c17439fe0847c2421c5d1 F tool/shell3.test ff663e83100670a295d473515c12beb8103a78b6 -F tool/showdb.c 4ab96e7f501e5423d5b7ac34504afd3834dbf3ce +F tool/showdb.c 12fbece85695e3a61bdb4f7607b61f264120c4b6 F tool/showjournal.c ec3b171be148656827c4949fbfb8ab4370822f87 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b @@ -801,14 +801,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 23eb408b5d08b89b41aaf245a7be8e235f30af8a -R 933a436d34fb2f67d252b6f2eef7208a +P 2ff824e58ce8b8f605c809ac960dcbfc51c30e30 +R 07d9a10059fff93d4de005270606b0db U drh -Z f61ced08bbb9a853a64647c8b442a2d5 +Z 92020570ca8608c3a29033eaaebd4aa8 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFL1cOUoxKgR168RlERAvg3AJsFJVG93QKIMPjRrMQew07/kDOloACgjMdv -7XmPQv5MjnYy+cdiQdmjRsk= -=SfZz +iD8DBQFL1c3QoxKgR168RlERAk7nAJ0RNPM+2ysEsEOLzmoRWkmlbmvLeACfXafV +1if1i0LIIQFX3bMAD0w2gxM= +=aVQ6 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index cf2caab397..04c48fb1f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ff824e58ce8b8f605c809ac960dcbfc51c30e30 \ No newline at end of file +245d934b72cbc6e897193e7892195b6561995939 \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index ac537682ef..08b1b85987 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -170,7 +170,7 @@ static void print_db_header(void){ print_decode_line(aData, 84, 4, "meta[11]"); print_decode_line(aData, 88, 4, "meta[12]"); print_decode_line(aData, 92, 4, "meta[13]"); - print_decode_line(aData, 96, 4, "meta[14]"); + print_decode_line(aData, 96, 4, "SQLite version number"); } /* From 93791ea0bac51d58675a54621e3fd7a1cce75d36 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Apr 2010 17:36:35 +0000 Subject: [PATCH 5/6] Change the default_cache_size pragma to always store a positive value. FossilOrigin-Name: 36fb2cae75b5dfe1fe818895f03c0b4f4190a722 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/pragma.c | 14 +++++--------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 53259d8b71..438c37caf5 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Identify\sthe\sSQLite\sversion\smeta-value\sentry\sin\sthe\sdb-header\soutput\sof\nshowdb. -D 2010-04-26T17:30:53 +C Change\sthe\sdefault_cache_size\spragma\sto\salways\sstore\sa\spositive\svalue. +D 2010-04-26T17:36:35 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -161,7 +161,7 @@ F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c 6dc1871ce8ead9187161c370a58cd06c84221f76 -F src/pragma.c e166ea41544f8e57a08db86dbe87212b7d378fe8 +F src/pragma.c 71ba42f5a6f1c91266ca065c2a55c168c7846d3a F src/prepare.c fd1398cb1da54385ba5bd68d93928f10d10a1d9c F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -801,14 +801,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2ff824e58ce8b8f605c809ac960dcbfc51c30e30 -R 07d9a10059fff93d4de005270606b0db +P 245d934b72cbc6e897193e7892195b6561995939 +R 1a721a7e3d8403e75d36dd22925eaa62 U drh -Z 92020570ca8608c3a29033eaaebd4aa8 +Z d3141c0d53e4f0054b2b5670e084ebf2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFL1c3QoxKgR168RlERAk7nAJ0RNPM+2ysEsEOLzmoRWkmlbmvLeACfXafV -1if1i0LIIQFX3bMAD0w2gxM= -=aVQ6 +iD8DBQFL1c8noxKgR168RlERAk2fAJwIn4ScLPQ6cD+9QSCdisImYXuM8QCfTXNt +XvbQVdO+MSVbonYnIw7jvtU= +=Dgm7 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 04c48fb1f8..736cbd9388 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -245d934b72cbc6e897193e7892195b6561995939 \ No newline at end of file +36fb2cae75b5dfe1fe818895f03c0b4f4190a722 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index f03078f246..037a290a90 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -329,11 +329,11 @@ void sqlite3Pragma( ** page cache size value and the persistent page cache size value ** stored in the database file. ** - ** The default cache size is stored in meta-value 2 of page 1 of the - ** database file. The cache size is actually the absolute value of - ** this memory location. The sign of meta-value 2 determines the - ** synchronous setting. A negative value means synchronous is off - ** and a positive value means synchronous is on. + ** Older versions of SQLite would set the default cache size to a + ** negative number to indicate synchronous=OFF. These days, synchronous + ** is always on by default regardless of the sign of the default cache + ** size. But continue to take the absolute value of the default cache + ** size of historical compatibility. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { @@ -362,10 +362,6 @@ void sqlite3Pragma( if( size<0 ) size = -size; sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp2(v, OP_Integer, size, 1); - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, BTREE_DEFAULT_CACHE_SIZE); - addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0); - sqlite3VdbeAddOp2(v, OP_Integer, -size, 1); - sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); From 8c6f666b26cd8244da3d7fb6da478b43105bc679 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Apr 2010 19:17:26 +0000 Subject: [PATCH 6/6] Optimization: Convert an ORDER BY clause into a no-op if the query also contains a GROUP BY clause that will force the same output order. FossilOrigin-Name: ca9d86baf70f210d331ce93102177c8005c494cb --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/expr.c | 39 ++++++++++++++++++++++++++------------- src/select.c | 12 ++++++++++++ src/sqliteInt.h | 4 +++- 5 files changed, 53 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 438c37caf5..f2bb25a6d4 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Change\sthe\sdefault_cache_size\spragma\sto\salways\sstore\sa\spositive\svalue. -D 2010-04-26T17:36:35 +C Optimization:\sConvert\san\sORDER\sBY\sclause\sinto\sa\sno-op\sif\sthe\squery\salso\ncontains\sa\sGROUP\sBY\sclause\sthat\swill\sforce\sthe\ssame\soutput\sorder. +D 2010-04-26T19:17:27 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -121,7 +121,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 51553a859994d01d8bf3500747f66a890c459774 F src/date.c 485a4409a384310e6d93fd1104a9d0a8658becd9 F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581 -F src/expr.c 6baed2a0448d494233d9c0a610eea018ab386a32 +F src/expr.c 286f62b24217ade1c14ba56de413ffdd607b6a41 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2116672a6bd610dc888e27df292ebc7999c9bb0 F src/func.c 0c28599430856631216b6c0131c51c89bf516026 @@ -167,11 +167,11 @@ F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c ac5f1a713cd1ae77f08b83cc69581e11bf5ae6f9 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 -F src/select.c b7c9a40bc1567bceff52ad4b73108734ee4bf268 +F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4 F src/sqlite.h.in dc98616304e3e776008655671d81e3ad3028ada7 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 -F src/sqliteInt.h 15339730eeeb571ed515d125e3446ae80ec3b4ef +F src/sqliteInt.h 4303fdad2e96c56f510cc8e31a647b1b8c5a5254 F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6 F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -801,14 +801,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 245d934b72cbc6e897193e7892195b6561995939 -R 1a721a7e3d8403e75d36dd22925eaa62 +P 36fb2cae75b5dfe1fe818895f03c0b4f4190a722 +R 39601da2973f0d22788b2e5833832c44 U drh -Z d3141c0d53e4f0054b2b5670e084ebf2 +Z 9d6faae1537324b0ce24766e774d3c1e -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFL1c8noxKgR168RlERAk2fAJwIn4ScLPQ6cD+9QSCdisImYXuM8QCfTXNt -XvbQVdO+MSVbonYnIw7jvtU= -=Dgm7 +iD8DBQFL1ebKoxKgR168RlERAixaAJ9MtsB9+gfG3m3Uh9CtO8GjRZH+fgCghDsR +Xx+FaS5+UH9uAeCG9zc761s= +=CIW0 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 736cbd9388..8feb63902d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36fb2cae75b5dfe1fe818895f03c0b4f4190a722 \ No newline at end of file +ca9d86baf70f210d331ce93102177c8005c494cb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 034088fafc..70526aea61 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3440,7 +3440,6 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** an incorrect 0 or 1 could lead to a malfunction. */ int sqlite3ExprCompare(Expr *pA, Expr *pB){ - int i; if( pA==0||pB==0 ){ return pB==pA ? 0 : 2; } @@ -3453,18 +3452,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ if( pA->op!=pB->op ) return 2; if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2; if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2; - - if( pA->x.pList && pB->x.pList ){ - if( pA->x.pList->nExpr!=pB->x.pList->nExpr ) return 2; - for(i=0; ix.pList->nExpr; i++){ - Expr *pExprA = pA->x.pList->a[i].pExpr; - Expr *pExprB = pB->x.pList->a[i].pExpr; - if( sqlite3ExprCompare(pExprA, pExprB) ) return 2; - } - }else if( pA->x.pList || pB->x.pList ){ - return 2; - } - + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2; if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ @@ -3481,6 +3469,31 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ return 0; } +/* +** Compare two ExprList objects. Return 0 if they are identical and +** non-zero if they differ in any way. +** +** This routine might return non-zero for equivalent ExprLists. The +** only consequence will be disabled optimizations. But this routine +** must never return 0 if the two ExprList objects are different, or +** a malfunction will result. +** +** Two NULL pointers are considered to be the same. But a NULL pointer +** always differs from a non-NULL pointer. +*/ +int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){ + int i; + if( pA==0 && pB==0 ) return 0; + if( pA==0 || pB==0 ) return 1; + if( pA->nExpr!=pB->nExpr ) return 1; + for(i=0; inExpr; i++){ + Expr *pExprA = pA->a[i].pExpr; + Expr *pExprB = pB->a[i].pExpr; + if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; + if( sqlite3ExprCompare(pExprA, pExprB) ) return 1; + } + return 0; +} /* ** Add a new element to the pAggInfo->aCol[] array. Return the index of diff --git a/src/select.c b/src/select.c index 47e409ffc8..9a016039a8 100644 --- a/src/select.c +++ b/src/select.c @@ -3718,6 +3718,18 @@ int sqlite3Select( isDistinct = 0; } + /* If there is both a GROUP BY and an ORDER BY clause and they are + ** identical, then disable the ORDER BY clause since the GROUP BY + ** will cause elements to come out in the correct order. This is + ** an optimization - the correct answer should result regardless. + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER + ** to disable this optimization for testing purposes. + */ + if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0 + && (db->flags & SQLITE_GroupByOrder)==0 ){ + pOrderBy = 0; + } + /* If there is an ORDER BY clause, then this sorting ** index might end up being unused if the data can be ** extracted in pre-sorted order. If that is the case, then the diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6e6ec72ac2..d4f8d23aa9 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -925,7 +925,8 @@ struct sqlite3 { #define SQLITE_IndexSort 0x04 /* Disable indexes for sorting */ #define SQLITE_IndexSearch 0x08 /* Disable indexes for searching */ #define SQLITE_IndexCover 0x10 /* Disable index covering table */ -#define SQLITE_OptMask 0x1f /* Mask of all disablable opts */ +#define SQLITE_GroupByOrder 0x20 /* Disable GROUPBY cover of ORDERBY */ +#define SQLITE_OptMask 0xff /* Mask of all disablable opts */ /* ** Possible values for the sqlite.magic field. @@ -2689,6 +2690,7 @@ void sqlite3Vacuum(Parse*); int sqlite3RunVacuum(char**, sqlite3*); char *sqlite3NameFromToken(sqlite3*, Token*); int sqlite3ExprCompare(Expr*, Expr*); +int sqlite3ExprListCompare(ExprList*, ExprList*); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); Vdbe *sqlite3GetVdbe(Parse*);