]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Ensure that the KeyInfo.nXField value for ephemeral tables used to implement
authordrh <drh@noemail.net>
Mon, 19 Jan 2015 21:38:53 +0000 (21:38 +0000)
committerdrh <drh@noemail.net>
Mon, 19 Jan 2015 21:38:53 +0000 (21:38 +0000)
ORDER BY or GROUP BY clauses is set correctly, so that the
sqlite3VdbeFindCompare() routine can choose the correct comparison function.
Add assert() statements to the high-speed comparison functions to detect
cases where they are inappropriately chosen.
Fix for ticket [f97c4637102a3ae72b7911].

FossilOrigin-Name: 59e592f67fb88e2630c04655058fc63439af0913

manifest
manifest.uuid
src/select.c
src/vdbeaux.c
test/orderby8.test [new file with mode: 0644]

index 2d35ff8ff15bf4fb1753acdaaca34d426e5e50c2..f457526ed0007f0198d60da52930aa815da648db 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Version\s3.8.8
-D 2015-01-16T12:08:06.393
+C Ensure\sthat\sthe\sKeyInfo.nXField\svalue\sfor\sephemeral\stables\sused\sto\simplement\nORDER\sBY\sor\sGROUP\sBY\sclauses\sis\sset\scorrectly,\sso\sthat\sthe\nsqlite3VdbeFindCompare()\sroutine\scan\schoose\sthe\scorrect\scomparison\sfunction.\nAdd\sassert()\sstatements\sto\sthe\shigh-speed\scomparison\sfunctions\sto\sdetect\ncases\swhere\sthey\sare\sinappropriately\schosen.\nFix\sfor\sticket\s[f97c4637102a3ae72b7911].
+D 2015-01-19T21:38:53.373
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5407a688f4d77a05c18a8142be8ae5a2829dd610
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -229,7 +229,7 @@ F src/printf.c ea82bcb1b83273b4c67177c233c1f78c81fc42f9
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
 F src/resolve.c f6c46d3434439ab2084618d603e6d6dbeb0d6ada
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
-F src/select.c e4c38c75e36f28aed80a69a725d888751bfd53df
+F src/select.c bc02e8b084891af5a3b428faa9cf367aff887d1a
 F src/shell.c 5b8e786a7c8eec87fa3f2ea615b337d2d99e284c
 F src/sqlite.h.in 9dfc99d6533d36d6a549c4f3f01cacc8be956ada
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
@@ -296,7 +296,7 @@ F src/vdbe.c ddfc977981cd6324668aa6b114045eb1c677421a
 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
 F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78
 F src/vdbeapi.c 4bc511a46b9839392ae0e90844a71dc96d9dbd71
-F src/vdbeaux.c 07ef87c6d4b5abdf13ff33babb10205702fdab0a
+F src/vdbeaux.c f06d38c71d7f533348c09869d69fd1b647042a5b
 F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778
 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
 F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2
@@ -769,6 +769,7 @@ F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4
 F test/orderby5.test 8f08a54836d21fb7c70245360751aedd1c2286fb
 F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859
 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
+F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
 F test/oserror.test 14fec2796c2b6fe431c7823750e8a18a761176d7
 F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799
 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
@@ -1236,10 +1237,11 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 8f45217cbafef2297cdcec3fd69f4371dfb83922
-R 933466cd8ec4e35d692da3aefe1a6703
-T +bgcolor * #d0c0ff
-T +sym-release *
-T +sym-version-3.8.8 *
+P 7d68a42face3ab14ed88407d4331872f5b243fdf
+Q +f7201bb0cdc9e1425c68599b32434de2231dca36
+R e444e9c867dd5196e8f0c39e1d05468d
+T *branch * branch-3.8.8
+T *sym-branch-3.8.8 *
+T -sym-trunk *
 U drh
-Z bb546801ed90d1803572e32e58b772a4
+Z c6d384008cf12ca28742ca7fe4d481ac
index b043ddc19648a3f27dda01e1b9ef4a87d2557048..d437c568f0122a94ccc51b9890ce6e44344300be 100644 (file)
@@ -1 +1 @@
-7d68a42face3ab14ed88407d4331872f5b243fdf
\ No newline at end of file
+59e592f67fb88e2630c04655058fc63439af0913
\ No newline at end of file
index 78b1caea8de3ce75d1ab82640ef5d49327de0ec8..403732646736262f0f70af2e3278ed7cc7871a08 100644 (file)
@@ -1054,7 +1054,7 @@ static KeyInfo *keyInfoFromExprList(
   int i;
 
   nExpr = pList->nExpr;
-  pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra-iStart, 1);
+  pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1);
   if( pInfo ){
     assert( sqlite3KeyInfoIsWriteable(pInfo) );
     for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
@@ -4924,7 +4924,7 @@ int sqlite3Select(
   */
   if( sSort.pOrderBy ){
     KeyInfo *pKeyInfo;
-    pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0);
+    pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
     sSort.iECursor = pParse->nTab++;
     sSort.addrSortIndex =
       sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
@@ -5098,7 +5098,7 @@ int sqlite3Select(
       ** will be converted into a Noop.  
       */
       sAggInfo.sortingIdx = pParse->nTab++;
-      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, 0);
+      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
       addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, 
           sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
           0, (char*)pKeyInfo, P4_KEYINFO);
index 03c229c994a0bd08f621411933a234f4bc956bb4..e07aacbcac361fb134cc9a672c4f584d508f6d74 100644 (file)
@@ -3349,6 +3349,41 @@ debugCompareEnd:
 }
 #endif
 
+#if SQLITE_DEBUG
+/*
+** Count the number of fields (a.k.a. columns) in the record given by
+** pKey,nKey.  The verify that this count is less than or equal to the
+** limit given by pKeyInfo->nField + pKeyInfo->nXField.
+**
+** If this constraint is not satisfied, it means that the high-speed
+** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
+** not work correctly.  If this assert() ever fires, it probably means
+** that the KeyInfo.nField or KeyInfo.nXField values were computed
+** incorrectly.
+*/
+static void vdbeAssertFieldCountWithinLimits(
+  int nKey, const void *pKey,   /* The record to verify */ 
+  const KeyInfo *pKeyInfo       /* Compare size with this KeyInfo */
+){
+  int nField = 0;
+  u32 szHdr;
+  u32 idx;
+  u32 notUsed;
+  const unsigned char *aKey = (const unsigned char*)pKey;
+
+  if( CORRUPT_DB ) return;
+  idx = getVarint32(aKey, szHdr);
+  assert( szHdr<=nKey );
+  while( idx<szHdr ){
+    idx += getVarint32(aKey+idx, notUsed);
+    nField++;
+  }
+  assert( nField <= pKeyInfo->nField+pKeyInfo->nXField );
+}
+#else
+# define vdbeAssertFieldCountWithinLimits(A,B,C)
+#endif
+
 /*
 ** Both *pMem1 and *pMem2 contain string values. Compare the two values
 ** using the collation sequence pColl. As usual, return a negative , zero
@@ -3760,6 +3795,7 @@ static int vdbeRecordCompareInt(
   i64 v = pPKey2->aMem[0].u.i;
   i64 lhs;
 
+  vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
   assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB );
   switch( serial_type ){
     case 1: { /* 1-byte signed integer */
@@ -3847,6 +3883,7 @@ static int vdbeRecordCompareString(
   int serial_type;
   int res;
 
+  vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
   getVarint32(&aKey1[1], serial_type);
   if( serial_type<12 ){
     res = pPKey2->r1;      /* (pKey1/nKey1) is a number or a null */
diff --git a/test/orderby8.test b/test/orderby8.test
new file mode 100644 (file)
index 0000000..53da971
--- /dev/null
@@ -0,0 +1,41 @@
+# 2015-01-19
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    May you find forgiveness for yourself and forgive others.
+#    May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library.  The
+# focus of this file is testing ORDER BY and LIMIT on tables with
+# many columns.
+#
+# These tests verify that ticket [f97c4637102a3ae72b7911167e1d4da12ce60722]
+# from 2015-01-19 has been fixed.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix orderby8
+
+do_test 1.0 {
+  db eval {
+    CREATE TABLE t1(x);
+    INSERT INTO t1(x) VALUES(1),(5),(9),(7),(3),(2),(4),(6),(8);
+  }
+  set ::result_set "x"
+} {x}
+for {set i 1} {$i<200} {incr i} {
+  append ::result_set ", x+$i"
+  do_test 1.$i {
+    set res {}
+    db eval "SELECT $::result_set FROM t1 ORDER BY x LIMIT -1" {
+      lappend res $x
+    }
+    set res
+  } {1 2 3 4 5 6 7 8 9}
+}
+
+finish_test