Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When doing the optimization that attempts to avoid sorting on a GROUP BY, do not assume that the values in an index on an expression are non-NULL. Bug discovered by Wang Ke's fuzzer and reported at forum post 74330094d8. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
7178dc3a32c3a4a33e437fd5026f6f72 |
User & Date: | drh 2021-04-26 14:32:48 |
Context
2021-04-26
| ||
15:28 | More aggressive detection of OOM errors in resolveAlias(). dbsqlfuzz 7f96832c2ef7ee472022ed805b064e55e41094b2 (check-in: e99faf4f user: drh tags: trunk) | |
14:32 | When doing the optimization that attempts to avoid sorting on a GROUP BY, do not assume that the values in an index on an expression are non-NULL. Bug discovered by Wang Ke's fuzzer and reported at forum post 74330094d8. (check-in: 7178dc3a user: drh tags: trunk) | |
14:09 | Do not initialize eponymous virtual tables when parsing the schema. This can happen if the db is corrupt. (check-in: cb8c41aa user: dan tags: trunk) | |
Changes
Changes to src/where.c.
︙ | ︙ | |||
3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 | return 0; }else{ nKeyCol = pIndex->nKeyCol; nColumn = pIndex->nColumn; assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); isOrderDistinct = IsUniqueIndex(pIndex) && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; } /* Loop through all columns of the index and deal with the ones ** that are not constrained by == or IN. */ | > > > > | 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 | return 0; }else{ nKeyCol = pIndex->nKeyCol; nColumn = pIndex->nColumn; assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); /* All relevant terms of the index must also be non-NULL in order ** for isOrderDistinct to be true. So the isOrderDistint value ** computed here might be a false positive. Corrections will be ** made at tag-20210426-1 below */ isOrderDistinct = IsUniqueIndex(pIndex) && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; } /* Loop through all columns of the index and deal with the ones ** that are not constrained by == or IN. */ |
︙ | ︙ | |||
3942 3943 3944 3945 3946 3947 3948 | if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; }else{ iColumn = XN_ROWID; revIdx = 0; } /* An unconstrained column that might be NULL means that this | | | | | | | | | > > > > | 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 | if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; }else{ iColumn = XN_ROWID; revIdx = 0; } /* An unconstrained column that might be NULL means that this ** WhereLoop is not well-ordered. tag-20210426-1 */ if( isOrderDistinct ){ if( iColumn>=0 && j>=pLoop->u.btree.nEq && pIndex->pTable->aCol[iColumn].notNull==0 ){ isOrderDistinct = 0; } if( iColumn==XN_EXPR ){ isOrderDistinct = 0; } } /* Find the ORDER BY term that corresponds to the j-th column ** of the index and mark that ORDER BY term off */ isMatch = 0; for(i=0; bOnce && i<nOrderBy; i++){ if( MASKBIT(i) & obSat ) continue; |
︙ | ︙ |
Changes to test/select5.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # 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 aggregate functions and the # GROUP BY and HAVING clauses of SELECT statements. # | < | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 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 aggregate functions and the # GROUP BY and HAVING clauses of SELECT statements. # set testdir [file dirname $argv0] source $testdir/tester.tcl # Build some test data # execsql { |
︙ | ︙ | |||
247 248 249 250 251 252 253 | } {two 3 one 6} do_test select5-8.8 { execsql { SELECT a, count(*) FROM t8a, t8b GROUP BY a ORDER BY 2; } } {two 3 one 9} | | | > > > > > > | | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | } {two 3 one 6} do_test select5-8.8 { execsql { SELECT a, count(*) FROM t8a, t8b GROUP BY a ORDER BY 2; } } {two 3 one 9} # 2021-04-26 forum https://sqlite.org/forum/forumpost/74330094d8 reset_db do_execsql_test select5-9.1 { CREATE TABLE t1(a INT, b INT); INSERT INTO t1(a,b) VALUES(1,null),(null,null),(1,null); CREATE UNIQUE INDEX t1b ON t1(abs(b)); SELECT quote(a), quote(b), '|' FROM t1 GROUP BY a, abs(b); } {NULL NULL | 1 NULL |} finish_test |