/ Check-in [793e206f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The sqlite3ExprCodeGetColumn() is not guaranteed to put the result in the register requested. Fix the skip-scan code generator for WITHOUT ROWID tables so that it always checks the register and copies the result if it lands in the wrong register. Fix for ticket [8fd39115d8f46ece70e7d4b3].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:793e206f9032d9205bdb3f447b136bed9a25fa22
User & Date: drh 2015-07-23 16:39:33
Context
2015-07-23
17:16
When SQLITE_OMIT_LOOKASIDE is set, do not allocate any lookaside memory since it will never be used. check-in: 0ffd499f user: drh tags: trunk
16:39
The sqlite3ExprCodeGetColumn() is not guaranteed to put the result in the register requested. Fix the skip-scan code generator for WITHOUT ROWID tables so that it always checks the register and copies the result if it lands in the wrong register. Fix for ticket [8fd39115d8f46ece70e7d4b3]. check-in: 793e206f user: drh tags: trunk
2015-07-21
19:22
Fix harmless compiler warning in MSVC 2015. check-in: 01c8b9cc user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/wherecode.c.

1292
1293
1294
1295
1296
1297
1298

1299



1300
1301
1302
1303
1304
1305
1306
              int nPk = pPk->nKeyCol;
              int iPk;

              /* Read the PK into an array of temp registers. */
              r = sqlite3GetTempRange(pParse, nPk);
              for(iPk=0; iPk<nPk; iPk++){
                int iCol = pPk->aiColumn[iPk];

                sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur, r+iPk, 0);



              }

              /* Check if the temp table already contains this key. If so,
              ** the row has already been included in the result set and
              ** can be ignored (by jumping past the Gosub below). Otherwise,
              ** insert the key into the temp table and proceed with processing
              ** the row.







>
|
>
>
>







1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
              int nPk = pPk->nKeyCol;
              int iPk;

              /* Read the PK into an array of temp registers. */
              r = sqlite3GetTempRange(pParse, nPk);
              for(iPk=0; iPk<nPk; iPk++){
                int iCol = pPk->aiColumn[iPk];
                int rx;
                rx = sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur,r+iPk,0);
                if( rx!=r+iPk ){
                  sqlite3VdbeAddOp2(v, OP_SCopy, rx, r+iPk);
                }
              }

              /* Check if the temp table already contains this key. If so,
              ** the row has already been included in the result set and
              ** can be ignored (by jumping past the Gosub below). Otherwise,
              ** insert the key into the temp table and proceed with processing
              ** the row.

Changes to test/skipscan1.test.

287
288
289
290
291
292
293
294






























295
  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {~/ANY/}
do_execsql_test skipscan1-7.3 {
  UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100 noskipscan';
  ANALYZE sqlite_master;
  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {~/ANY/}































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {~/ANY/}
do_execsql_test skipscan1-7.3 {
  UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100 noskipscan';
  ANALYZE sqlite_master;
  EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1;
} {~/ANY/}

# Ticket 8fd39115d8f46ece70e7d4b3c481d1bd86194746  2015-07-23
# Incorrect code generated for a skipscan within an OR optimization
# on a WITHOUT ROWID table.
#
do_execsql_test skipscan1-8.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x, y, PRIMARY KEY(x,y)) WITHOUT ROWID;
  INSERT INTO t1(x,y) VALUES(1,'AB');
  INSERT INTO t1(x,y) VALUES(2,'CD');
  ANALYZE;
  DROP TABLE IF EXISTS sqlite_stat4;
  DELETE FROM sqlite_stat1;
  INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES('t1','t1','1000000 100 1');
  ANALYZE sqlite_master;
  SELECT * FROM t1
   WHERE (y = 'AB' AND x <= 4)
      OR (y = 'EF' AND x = 5);
} {1 AB}
do_execsql_test skipscan1-8.1eqp {
  EXPLAIN QUERY PLAN
  SELECT * FROM t1
   WHERE (y = 'AB' AND x <= 4)
      OR (y = 'EF' AND x = 5);
} {/ANY/}
do_execsql_test skipscan1-8.2 {
  SELECT * FROM t1
   WHERE y = 'AB' OR (y = 'CD' AND x = 2)
  ORDER BY +x;
} {1 AB 2 CD}

finish_test