SQLite

Check-in [a7530f8971]
Login

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

Overview
Comment:Fix a problem causing "PRAGMA quick_check" to return spurious corruption errors for a WITHOUT ROWID for which all columns are either virtual or part of the primary key, and for which the order of the columns in the primary key definition is different from the order in the table.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a7530f897127f35a212db6557edbcbbb286cc0e094754c1c1b74ce8dbf724470
User & Date: dan 2023-01-28 17:37:37.660
Context
2023-01-28
21:01
Show more details about the SrcItem.fg field in tree-trace output. (check-in: 3d05dddd0b user: drh tags: trunk)
17:37
Fix a problem causing "PRAGMA quick_check" to return spurious corruption errors for a WITHOUT ROWID for which all columns are either virtual or part of the primary key, and for which the order of the columns in the primary key definition is different from the order in the table. (check-in: a7530f8971 user: dan tags: trunk)
16:37
Update sqllimits1.test to account for the fact that if an odd value is specified as the length in bytes of a utf-16 string, it is truncated to the largest smaller even number. (check-in: 74508470c4 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pragma.c.
1781
1782
1783
1784
1785
1786
1787


1788
1789
1790

1791






1792
1793
1794
1795
1796
1797
1798
1799
1800
        loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);

        /* Fetch the right-most column from the table.  This will cause
        ** the entire record header to be parsed and sanity checked.  It
        ** will also prepopulate the cursor column cache that is used
        ** by the OP_IsType code, so it is a required step.
        */


        mxCol = pTab->nCol-1;
        while( mxCol>=0
            && ((pTab->aCol[mxCol].colFlags & COLFLAG_VIRTUAL)!=0

                || pTab->iPKey==mxCol) ) mxCol--;






        if( mxCol>=0 ){
          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, mxCol, 3);
          sqlite3VdbeTypeofColumn(v, 3);
        }

        if( !isQuick ){
          if( pPk ){
            /* Verify WITHOUT ROWID keys are in ascending order */
            int a1;







>
>
|
|
|
>
|
>
>
>
>
>
>

|







1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
        loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);

        /* Fetch the right-most column from the table.  This will cause
        ** the entire record header to be parsed and sanity checked.  It
        ** will also prepopulate the cursor column cache that is used
        ** by the OP_IsType code, so it is a required step.
        */
        assert( !IsVirtual(pTab) );
        if( HasRowid(pTab) ){
          mxCol = -1;
          for(j=0; j<pTab->nCol; j++){
            if( (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)==0 ) mxCol++;
          }
          if( mxCol==pTab->iPKey ) mxCol--;
        }else{
          /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID
          ** PK index column-count, so there is no need to account for them 
          ** in this case. */
          mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1;
        }
        if( mxCol>=0 ){
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, mxCol, 3);
          sqlite3VdbeTypeofColumn(v, 3);
        }

        if( !isQuick ){
          if( pPk ){
            /* Verify WITHOUT ROWID keys are in ascending order */
            int a1;
Added test/quickcheck.test.




































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 2023 January 28
#
# 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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix quickcheck

do_execsql_test 1.0 {
  CREATE TABLE t1(
    a INTEGER NOT NULL, b INTEGER NOT NULL, c AS (a+1),
    PRIMARY KEY(b, a)
  ) WITHOUT ROWID;

  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
}

do_execsql_test 1.1 {
  PRAGMA quick_check
} {
  ok
}

finish_test