SQLite

Check-in [76b26acaba]
Login

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

Overview
Comment:Bring the apple-osx branch up-to-date with the 3.30.0 release.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA3-256: 76b26acaba3a4169b358079fdd95526505902ee003d2505fdea111120d48169b
User & Date: drh 2019-10-04 15:41:17.879
Context
2019-11-15
02:52
Merge the version 3.30.1 changes into the apple-osx branch. (check-in: 2c8af35206 user: drh tags: apple-osx)
2019-10-04
15:41
Bring the apple-osx branch up-to-date with the 3.30.0 release. (check-in: 76b26acaba user: drh tags: apple-osx)
15:03
Version 3.30.0 (check-in: c20a353364 user: drh tags: trunk, release, version-3.30.0)
2019-09-30
16:13
Merge the 3.30.0 beta 1 changes from trunk. (check-in: 9ce4c79171 user: drh tags: apple-osx)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts3/fts3_write.c.
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
*/
static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
  memset(p, 0, sizeof(NodeReader));
  p->aNode = aNode;
  p->nNode = nNode;

  /* Figure out if this is a leaf or an internal node. */
  if( p->aNode[0] ){
    /* An internal node. */
    p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
  }else{
    p->iOff = 1;
  }

  return nodeReaderNext(p);
}

/*
** This function is called while writing an FTS segment each time a leaf o
** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed
** to be greater than the largest key on the node just written, but smaller
** than or equal to the first key that will be written to the next leaf







|






|







3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
*/
static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){
  memset(p, 0, sizeof(NodeReader));
  p->aNode = aNode;
  p->nNode = nNode;

  /* Figure out if this is a leaf or an internal node. */
  if( aNode && aNode[0] ){
    /* An internal node. */
    p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild);
  }else{
    p->iOff = 1;
  }

  return aNode ? nodeReaderNext(p) : SQLITE_OK;
}

/*
** This function is called while writing an FTS segment each time a leaf o
** node is finished and written to disk. The key (zTerm/nTerm) is guaranteed
** to be greater than the largest key on the node just written, but smaller
** than or equal to the first key that will be written to the next leaf
4292
4293
4294
4295
4296
4297
4298

4299
4300
4301
4302
4303
4304
4305
4306
4307
        memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
      }

      for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
        NodeReader reader;
        pNode = &pWriter->aNodeWriter[i];


        rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);
        if( reader.aNode ){
          while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
          blobGrowBuffer(&pNode->key, reader.term.n, &rc);
          if( rc==SQLITE_OK ){
            memcpy(pNode->key.a, reader.term.a, reader.term.n);
            pNode->key.n = reader.term.n;
            if( i>0 ){
              char *aBlock = 0;







>
|
<







4292
4293
4294
4295
4296
4297
4298
4299
4300

4301
4302
4303
4304
4305
4306
4307
        memset(&pNode->block.a[nRoot], 0, FTS3_NODE_PADDING);
      }

      for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){
        NodeReader reader;
        pNode = &pWriter->aNodeWriter[i];

        if( pNode->block.a){
          rc = nodeReaderInit(&reader, pNode->block.a, pNode->block.n);

          while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader);
          blobGrowBuffer(&pNode->key, reader.term.n, &rc);
          if( rc==SQLITE_OK ){
            memcpy(pNode->key.a, reader.term.a, reader.term.n);
            pNode->key.n = reader.term.n;
            if( i>0 ){
              char *aBlock = 0;
Changes to src/loadext.c.
459
460
461
462
463
464
465

466



467
468
469
470
471
472
473
#else
  0,
#endif
  /* Version 3.28.0 and later */
  sqlite3_stmt_isexplain,
  sqlite3_value_frombind,
  /* Version 3.30.0 and later */

  sqlite3_drop_modules,



};

/*
** Attempt to load an SQLite extension library contained in the file
** zFile.  The entry point is zProc.  zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used.  Use
** of the default name is recommended.







>

>
>
>







459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
#else
  0,
#endif
  /* Version 3.28.0 and later */
  sqlite3_stmt_isexplain,
  sqlite3_value_frombind,
  /* Version 3.30.0 and later */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3_drop_modules,
#else
  0,
#endif
};

/*
** Attempt to load an SQLite extension library contained in the file
** zFile.  The entry point is zProc.  zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used.  Use
** of the default name is recommended.
Changes to src/mutex.h.
63
64
65
66
67
68
69

70
#define sqlite3_mutex_notheld(X)  ((void)(X),1)
#define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
#define sqlite3MutexInit()        SQLITE_OK
#define sqlite3MutexEnd()
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X)            X

#endif /* defined(SQLITE_MUTEX_OMIT) */







>

63
64
65
66
67
68
69
70
71
#define sqlite3_mutex_notheld(X)  ((void)(X),1)
#define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
#define sqlite3MutexInit()        SQLITE_OK
#define sqlite3MutexEnd()
#define MUTEX_LOGIC(X)
#else
#define MUTEX_LOGIC(X)            X
int sqlite3_mutex_held(sqlite3_mutex*);
#endif /* defined(SQLITE_MUTEX_OMIT) */
Changes to src/shell.c.in.
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
    }else{
      if( mType==0 ) mType = SQLITE_TRACE_STMT;
      sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
    }
  }else
#endif /* !defined(SQLITE_OMIT_TRACE) */

#ifdef SQLITE_DEBUG
  if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
    int ii;
    int lenOpt;
    char *zOpt;
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
      rc = 1;







|







9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
    }else{
      if( mType==0 ) mType = SQLITE_TRACE_STMT;
      sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
    }
  }else
#endif /* !defined(SQLITE_OMIT_TRACE) */

#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
    int ii;
    int lenOpt;
    char *zOpt;
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
      rc = 1;
Changes to src/test1.c.
1127
1128
1129
1130
1131
1132
1133

1134

1135
1136
1137
1138
1139
1140
1141

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " DB\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;

  sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);

  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
**
** x_count() counts the number of non-null arguments.  But there are







>

>







1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " DB\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0);
#endif
  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
**
** x_count() counts the number of non-null arguments.  But there are
Changes to src/vdbe.c.
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
    printf(" si:%lld", p->u.i);
  }else if( (p->flags & (MEM_IntReal))!=0 ){
    printf(" ir:%lld", p->u.i);
  }else if( p->flags & MEM_Int ){
    printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
  }else if( p->flags & MEM_Real ){
    printf(" r:%g", p->u.r);
#endif
  }else if( sqlite3VdbeMemIsRowSet(p) ){
    printf(" (rowset)");
  }else{
    char zBuf[200];
    sqlite3VdbeMemPrettyPrint(p, zBuf);
    printf(" %s", zBuf);







|







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
    printf(" si:%lld", p->u.i);
  }else if( (p->flags & (MEM_IntReal))!=0 ){
    printf(" ir:%lld", p->u.i);
  }else if( p->flags & MEM_Int ){
    printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
  }else if( p->flags & MEM_Real ){
    printf(" r:%.17g", p->u.r);
#endif
  }else if( sqlite3VdbeMemIsRowSet(p) ){
    printf(" (rowset)");
  }else{
    char zBuf[200];
    sqlite3VdbeMemPrettyPrint(p, zBuf);
    printf(" %s", zBuf);
Changes to test/affinity2.test.
114
115
116
117
118
119
120




121
122
123
124
125
126
127
128
129

130
131
} {0 '-1' 1}
do_execsql_test 507 {
  SELECT * FROM t0 WHERE +-+'ce' >= t0.c0;
} {-1 {}}
 
# 2019-08-30 ticket https://www.sqlite.org/src/info/40812aea1fde9594
#




do_execsql_test 600 {
  DROP TABLE IF EXISTS t0;
  CREATE TABLE t0(c0 REAL UNIQUE);
  INSERT INTO t0(c0) VALUES (3175546974276630385);
  SELECT 3175546974276630385 < c0 FROM t0;
} {1}
do_execsql_test 601 {
  SELECT 1 FROM t0 WHERE 3175546974276630385 < c0;
} {1}


finish_test







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


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
} {0 '-1' 1}
do_execsql_test 507 {
  SELECT * FROM t0 WHERE +-+'ce' >= t0.c0;
} {-1 {}}
 
# 2019-08-30 ticket https://www.sqlite.org/src/info/40812aea1fde9594
#
# Due to some differences in floating point computations, these tests do not
# work under valgrind.
#
if {![info exists ::G(valgrind)]} {
  do_execsql_test 600 {
    DROP TABLE IF EXISTS t0;
    CREATE TABLE t0(c0 REAL UNIQUE);
    INSERT INTO t0(c0) VALUES (3175546974276630385);
    SELECT 3175546974276630385 < c0 FROM t0;
  } {1}
  do_execsql_test 601 {
    SELECT 1 FROM t0 WHERE 3175546974276630385 < c0;
  } {1}
}

finish_test
Changes to test/corruptM.test.
17
18
19
20
21
22
23










24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198

199
200
201
202
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptM

# These tests deal with corrupt database files
#
database_may_be_corrupt











db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test corruptM-100 {
  CREATE TABLE t1(a,b,c);
  INSERT INTO t1 VALUES(111,222,333);
  CREATE INDEX i1 ON t1(b);
  CREATE VIEW v2 AS SELECT 15,22;
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN SELECT 5; END;
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_execsql_test corruptM-101 {
  PRAGMA writable_schema=on;
  UPDATE sqlite_master SET tbl_name=NULL WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 {} | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-102 {
  catchsql {
    PRAGMA quick_check;
  } db2

} {1 {malformed database schema (t1)}}
db2 close

do_execsql_test corruptM-110 {
  UPDATE sqlite_master SET tbl_name='tx' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 tx | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-111 {
  catchsql {
    PRAGMA quick_check;
  } db2

} {1 {malformed database schema (t1)}}
db2 close
do_execsql_test corruptM-112 {
  UPDATE sqlite_master SET tbl_name='t1', type='tabl' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {tabl t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-113 {
  catchsql {
    PRAGMA quick_check;
  } db2

} {1 {malformed database schema (t1)}}
db2 close
do_execsql_test corruptM-114 {
  UPDATE sqlite_master SET tbl_name='t9',type='table',name='t9'WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t9 t9 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-114 {
  catchsql {
    PRAGMA quick_check;
  } db2

} {1 {malformed database schema (t9)}}
db2 close

do_execsql_test corruptM-120 {
  UPDATE sqlite_master SET name='t1',tbl_name='T1' WHERE name='t9';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-121 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {0 {ok 111 222 333 15 22}}
db2 close

do_execsql_test corruptM-130 {
  UPDATE sqlite_master SET type='view' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {view t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-131 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (t1)}}
db2 close

do_execsql_test corruptM-140 {
  UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='t1';
  UPDATE sqlite_master SET tbl_name='tx' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 tx | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-141 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (i1)}}
db2 close

do_execsql_test corruptM-150 {
  UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | table i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-151 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (i1)}}
db2 close

do_execsql_test corruptM-160 {
  UPDATE sqlite_master SET type='view', tbl_name='t1' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | view i1 t1 | view v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-161 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (i1)}}
db2 close

do_execsql_test corruptM-170 {
  UPDATE sqlite_master SET type='index', tbl_name='t1' WHERE name='i1';
  UPDATE sqlite_master SET type='table', tbl_name='v2' WHERE name='v2';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | table v2 v2 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-171 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (v2)}}
db2 close

do_execsql_test corruptM-180 {
  UPDATE sqlite_master SET type='view',name='v3',tbl_name='v3' WHERE name='v2';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v3 v3 | trigger r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-181 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (v3)}}
db2 close

do_execsql_test corruptM-190 {
  UPDATE sqlite_master SET type='view',name='v2',tbl_name='v2' WHERE name='v3';
  UPDATE sqlite_master SET type='view' WHERE name='r1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | view r1 t1 |}
sqlite3 db2 test.db
do_test corruptM-191 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (r1)}}
db2 close
do_execsql_test corruptM-192 {
  UPDATE sqlite_master SET type='trigger',tbl_name='v2' WHERE name='r1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 v2 |}
sqlite3 db2 test.db
do_test corruptM-193 {
  catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;
  } db2

} {1 {malformed database schema (r1)}}
db2 close

finish_test







>
>
>
>
>
>
>
>
>
>

















<

|

<
>

<





<

|

<
>

<




<

|

<
>

<




<

|

<
>

<





<

|


<
>

<





<

|


<
>

<






<

|


<
>

<





<

|


<
>

<





<

|


<
>

<






<

|


<
>

<





<

|


<
>

<






<

|


<
>

<




<

|


<
>

<


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53

54
55

56
57
58
59
60

61
62
63

64
65

66
67
68
69

70
71
72

73
74

75
76
77
78

79
80
81

82
83

84
85
86
87
88

89
90
91
92

93
94

95
96
97
98
99

100
101
102
103

104
105

106
107
108
109
110
111

112
113
114
115

116
117

118
119
120
121
122

123
124
125
126

127
128

129
130
131
132
133

134
135
136
137

138
139

140
141
142
143
144
145

146
147
148
149

150
151

152
153
154
155
156

157
158
159
160

161
162

163
164
165
166
167
168

169
170
171
172

173
174

175
176
177
178

179
180
181
182

183
184

185
186
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix corruptM

# These tests deal with corrupt database files
#
database_may_be_corrupt

proc open_db2_and_catchsql {sql} {
  set rc [catch { sqlite3 db2 test.db } msg]
  if {$rc} {
    return [list $rc $msg]
  }
  set res [catchsql $sql db2]
  db2 close
  set res
}

db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test corruptM-100 {
  CREATE TABLE t1(a,b,c);
  INSERT INTO t1 VALUES(111,222,333);
  CREATE INDEX i1 ON t1(b);
  CREATE VIEW v2 AS SELECT 15,22;
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN SELECT 5; END;
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}
do_execsql_test corruptM-101 {
  PRAGMA writable_schema=on;
  UPDATE sqlite_master SET tbl_name=NULL WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 {} | index i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-102 {
  open_db2_and_catchsql {
    PRAGMA quick_check;

  }
} {1 {malformed database schema (t1)}}


do_execsql_test corruptM-110 {
  UPDATE sqlite_master SET tbl_name='tx' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 tx | index i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-111 {
  open_db2_and_catchsql {
    PRAGMA quick_check;

  }
} {1 {malformed database schema (t1)}}

do_execsql_test corruptM-112 {
  UPDATE sqlite_master SET tbl_name='t1', type='tabl' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {tabl t1 t1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-113 {
  open_db2_and_catchsql {
    PRAGMA quick_check;

  }
} {1 {malformed database schema (t1)}}

do_execsql_test corruptM-114 {
  UPDATE sqlite_master SET tbl_name='t9',type='table',name='t9'WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t9 t9 | index i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-114 {
  open_db2_and_catchsql {
    PRAGMA quick_check;

  }
} {1 {malformed database schema (t9)}}


do_execsql_test corruptM-120 {
  UPDATE sqlite_master SET name='t1',tbl_name='T1' WHERE name='t9';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-121 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  } 
} {0 {ok 111 222 333 15 22}}


do_execsql_test corruptM-130 {
  UPDATE sqlite_master SET type='view' WHERE name='t1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {view t1 T1 | index i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-131 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (t1)}}


do_execsql_test corruptM-140 {
  UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='t1';
  UPDATE sqlite_master SET tbl_name='tx' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 tx | view v2 v2 | trigger r1 t1 |}

do_test corruptM-141 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (i1)}}


do_execsql_test corruptM-150 {
  UPDATE sqlite_master SET type='table', tbl_name='t1' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | table i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-151 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (i1)}}


do_execsql_test corruptM-160 {
  UPDATE sqlite_master SET type='view', tbl_name='t1' WHERE name='i1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | view i1 t1 | view v2 v2 | trigger r1 t1 |}

do_test corruptM-161 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (i1)}}


do_execsql_test corruptM-170 {
  UPDATE sqlite_master SET type='index', tbl_name='t1' WHERE name='i1';
  UPDATE sqlite_master SET type='table', tbl_name='v2' WHERE name='v2';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | table v2 v2 | trigger r1 t1 |}

do_test corruptM-171 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (v2)}}


do_execsql_test corruptM-180 {
  UPDATE sqlite_master SET type='view',name='v3',tbl_name='v3' WHERE name='v2';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v3 v3 | trigger r1 t1 |}

do_test corruptM-181 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (v3)}}


do_execsql_test corruptM-190 {
  UPDATE sqlite_master SET type='view',name='v2',tbl_name='v2' WHERE name='v3';
  UPDATE sqlite_master SET type='view' WHERE name='r1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | view r1 t1 |}

do_test corruptM-191 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (r1)}}

do_execsql_test corruptM-192 {
  UPDATE sqlite_master SET type='trigger',tbl_name='v2' WHERE name='r1';
  SELECT type, name, tbl_name, '|' FROM sqlite_master;
} {table t1 t1 | index i1 t1 | view v2 v2 | trigger r1 v2 |}

do_test corruptM-193 {
  open_db2_and_catchsql {
    PRAGMA quick_check;
    SELECT * FROM t1, v2;

  }
} {1 {malformed database schema (r1)}}


finish_test
Added test/fts4merge5.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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 2019 October 02
#
# 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 script is testing the FTS4 module.
#

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

# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
  finish_test
  return
}

source $testdir/genesis.tcl

do_execsql_test 1.1 { 
  CREATE TABLE t1(docid, words);
}
fts_kjv_genesis

do_execsql_test 1.2 {
  CREATE VIRTUAL TABLE x1 USING fts3; 
  INSERT INTO x1(x1) VALUES('nodesize=64');
  INSERT INTO x1(x1) VALUES('maxpending=64');
}

do_execsql_test 1.3 {
  INSERT INTO x1(docid, content) SELECT * FROM t1;
}

for {set tn 1} {1} {incr tn} {
  set tc1 [db total_changes]
  do_execsql_test 1.4.$tn.1 {
    INSERT INTO x1(x1) VALUES('merge=1,2');
  }
  set tc2 [db total_changes]

  if {($tc2 - $tc1)<2} break

  do_execsql_test 1.4.$tn.1 {
    INSERT INTO x1(x1) VALUES('integrity-check');
  }
}



finish_test
Changes to test/permutations.test.
122
123
124
125
126
127
128

129
130
131
132
133
134
135
  vtab_err.test walslow.test walcrash.test walcrash3.test
  walthread.test rtree3.test indexfault.test securedel2.test
  sort3.test sort4.test fts4growth.test fts4growth2.test
  bigsort.test walprotocol.test mmap4.test fuzzer2.test
  walcrash2.test e_fkey.test backup.test

  fts4merge.test fts4merge2.test fts4merge4.test fts4check.test

  fts3cov.test fts3snippet.test fts3corrupt2.test fts3an.test
  fts3defer.test fts4langid.test fts3sort.test fts5unicode.test

  rtree4.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
  set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]







>







122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  vtab_err.test walslow.test walcrash.test walcrash3.test
  walthread.test rtree3.test indexfault.test securedel2.test
  sort3.test sort4.test fts4growth.test fts4growth2.test
  bigsort.test walprotocol.test mmap4.test fuzzer2.test
  walcrash2.test e_fkey.test backup.test

  fts4merge.test fts4merge2.test fts4merge4.test fts4check.test
  fts4merge5.test
  fts3cov.test fts3snippet.test fts3corrupt2.test fts3an.test
  fts3defer.test fts4langid.test fts3sort.test fts5unicode.test

  rtree4.test
}]
if {[info exists ::env(QUICKTEST_INCLUDE)]} {
  set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  walfault.test  walbak.test  journal2.test    tkt-9d68c883.test
} 

test_suite "coverage-analyze" -description {
  Coverage tests for file analyze.c.
} -files {
  analyze3.test analyze4.test analyze5.test analyze6.test
  analyze7.test analyze8.test analyze9.test analyzeA.test
  analyze.test analyzeB.test mallocA.test
} 

test_suite "coverage-sorter" -description {
  Coverage tests for file vdbesort.c.
} -files {
  sort.test sortfault.test
} 







|
|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
  walfault.test  walbak.test  journal2.test    tkt-9d68c883.test
} 

test_suite "coverage-analyze" -description {
  Coverage tests for file analyze.c.
} -files {
  analyze3.test analyze4.test analyze5.test analyze6.test
  analyze7.test analyze8.test analyze9.test
  analyze.test mallocA.test
} 

test_suite "coverage-sorter" -description {
  Coverage tests for file vdbesort.c.
} -files {
  sort.test sortfault.test
} 
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
test_suite "utf16" -description {
  Run tests using UTF-16 databases
} -presql {
  pragma encoding = 'UTF-16'
} -files {
    alter.test alter3.test
    analyze.test analyze3.test analyze4.test analyze5.test analyze6.test
    analyze7.test analyze8.test analyze9.test analyzeA.test analyzeB.test
    auth.test bind.test blob.test capi2.test capi3.test collate1.test
    collate2.test collate3.test collate4.test collate5.test collate6.test
    conflict.test date.test delete.test expr.test fkey1.test func.test
    hook.test index.test insert2.test insert.test interrupt.test in.test
    intpkey.test ioerr.test join2.test join.test lastinsert.test
    laststmtchanges.test limit.test lock2.test lock.test main.test 
    memdb.test minmax.test misc1.test misc2.test misc3.test notnull.test







|







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
test_suite "utf16" -description {
  Run tests using UTF-16 databases
} -presql {
  pragma encoding = 'UTF-16'
} -files {
    alter.test alter3.test
    analyze.test analyze3.test analyze4.test analyze5.test analyze6.test
    analyze7.test analyze8.test analyze9.test
    auth.test bind.test blob.test capi2.test capi3.test collate1.test
    collate2.test collate3.test collate4.test collate5.test collate6.test
    conflict.test date.test delete.test expr.test fkey1.test func.test
    hook.test index.test insert2.test insert.test interrupt.test in.test
    intpkey.test ioerr.test join2.test join.test lastinsert.test
    laststmtchanges.test limit.test lock2.test lock.test main.test 
    memdb.test minmax.test misc1.test misc2.test misc3.test notnull.test
Changes to test/releasetest.tcl.
407
408
409
410
411
412
413


414
415
416
417
418
419
420
        set rc 1
        set errmsg $line
      }
    }
    if {[regexp {runtime error: +(.*)} $line all msg]} {
      # skip over "value is outside range" errors
      if {[regexp {value .* is outside the range of representable} $line]} {


         # noop
      } else {
        incr ::NERRCASE
        if {$rc==0} {
          set rc 1
          set errmsg $msg
        }







>
>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
        set rc 1
        set errmsg $line
      }
    }
    if {[regexp {runtime error: +(.*)} $line all msg]} {
      # skip over "value is outside range" errors
      if {[regexp {value .* is outside the range of representable} $line]} {
         # noop
      } elseif {[regexp {overflow: .* cannot be represented} $line]} {
         # noop
      } else {
        incr ::NERRCASE
        if {$rc==0} {
          set rc 1
          set errmsg $msg
        }
Changes to test/wapptest.tcl.
821
822
823
824
825
826
827

828
829




830
831
832
833
834
835
836
      lappend lWappArg [lindex $argv $i]
    }
  } else {
    lappend lTestArg $arg
  }
}


for {set i 0} {$i < [llength $lTestArg]} {incr i} {
  switch -- [lindex $lTestArg $i] {




    -platform {
      if {$i==[llength $lTestArg]-1} { wapptest_usage }
      incr i
      set arg [lindex $lTestArg $i]
      set lPlatform [releasetest_data platforms]
      if {[lsearch $lPlatform $arg]<0} {
        puts stderr "No such platform: $arg. Platforms are: $lPlatform"







>

|
>
>
>
>







821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
      lappend lWappArg [lindex $argv $i]
    }
  } else {
    lappend lTestArg $arg
  }
}

wapptest_init
for {set i 0} {$i < [llength $lTestArg]} {incr i} {
  set opt [lindex $lTestArg $i]
  if {[string range $opt 0 1]=="--"} {
    set opt [string range $opt 1 end]
  }
  switch -- $opt {
    -platform {
      if {$i==[llength $lTestArg]-1} { wapptest_usage }
      incr i
      set arg [lindex $lTestArg $i]
      set lPlatform [releasetest_data platforms]
      if {[lsearch $lPlatform $arg]<0} {
        puts stderr "No such platform: $arg. Platforms are: $lPlatform"
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
    default {
      puts stderr "Unrecognized option: [lindex $lTestArg $i]"
      wapptest_usage
    }
  }
}

wapptest_init
if {$G(noui)==0} {
  wapp-start $lWappArg
} else {
  wapptest_run
  do_some_stuff
  vwait forever
}








<








883
884
885
886
887
888
889

890
891
892
893
894
895
896
897
    default {
      puts stderr "Unrecognized option: [lindex $lTestArg $i]"
      wapptest_usage
    }
  }
}


if {$G(noui)==0} {
  wapp-start $lWappArg
} else {
  wapptest_run
  do_some_stuff
  vwait forever
}

Changes to test/without_rowid1.test.
12
13
14
15
16
17
18




19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# This file implements regression tests for SQLite library.  The
# focus of this file is testing WITHOUT ROWID tables.
#

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





# Create and query a WITHOUT ROWID table.
#
do_execsql_test without_rowid1-1.0 {
  CREATE TABLE t1(a,b,c,d, PRIMARY KEY(c,a)) WITHOUT ROWID;
  CREATE INDEX t1bd ON t1(b, d);
  INSERT INTO t1 VALUES('journal','sherman','ammonia','helena');
  INSERT INTO t1 VALUES('dynamic','juliet','flipper','command');
  INSERT INTO t1 VALUES('journal','sherman','gamma','patriot');
  INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena');
  SELECT *, '|' FROM t1 ORDER BY c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

integrity_check without_rowid1-1.0ic

do_execsql_test without_rowid1-1.0ixi {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {c 1 a 1 b 0 d 0}

do_execsql_test without_rowid1-1.1 {
  SELECT *, '|' FROM t1 ORDER BY +c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}








>
>
>
>















|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# This file implements regression tests for SQLite library.  The
# focus of this file is testing WITHOUT ROWID tables.
#

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

proc do_execsql_test_if_vtab {tn sql {res {}}} {
  ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}

# Create and query a WITHOUT ROWID table.
#
do_execsql_test without_rowid1-1.0 {
  CREATE TABLE t1(a,b,c,d, PRIMARY KEY(c,a)) WITHOUT ROWID;
  CREATE INDEX t1bd ON t1(b, d);
  INSERT INTO t1 VALUES('journal','sherman','ammonia','helena');
  INSERT INTO t1 VALUES('dynamic','juliet','flipper','command');
  INSERT INTO t1 VALUES('journal','sherman','gamma','patriot');
  INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena');
  SELECT *, '|' FROM t1 ORDER BY c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

integrity_check without_rowid1-1.0ic

do_execsql_test_if_vtab without_rowid1-1.0ixi {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {c 1 a 1 b 0 d 0}

do_execsql_test without_rowid1-1.1 {
  SELECT *, '|' FROM t1 ORDER BY +c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  INSERT INTO t4 VALUES('abc', 'def');
  SELECT * FROM t4;
} {abc def}
do_execsql_test 2.1.2 {
  UPDATE t4 SET a = 'ABC';
  SELECT * FROM t4;
} {ABC def}
do_execsql_test 2.1.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}

do_execsql_test 2.2.1 {
  DROP TABLE t4;
  CREATE TABLE t4 (b, a COLLATE nocase PRIMARY KEY) WITHOUT ROWID;
  INSERT INTO t4(a, b) VALUES('abc', 'def');
  SELECT * FROM t4;
} {def abc}

do_execsql_test 2.2.2 {
  UPDATE t4 SET a = 'ABC', b = 'xyz';
  SELECT * FROM t4;
} {xyz ABC}

do_execsql_test 2.2.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}


do_execsql_test 2.3.1 {
  CREATE TABLE t5 (a, b, PRIMARY KEY(b, a)) WITHOUT ROWID;
  INSERT INTO t5(a, b) VALUES('abc', 'def');
  UPDATE t5 SET a='abc', b='def';
} {}

do_execsql_test 2.3.2 {
  SELECT name, coll, key FROM pragma_index_xinfo('t5');
} {b BINARY 1 a BINARY 1}


do_execsql_test 2.4.1 {
  CREATE TABLE t6 (
    a COLLATE nocase, b, c UNIQUE, PRIMARY KEY(b, a)
  ) WITHOUT ROWID;

  INSERT INTO t6(a, b, c) VALUES('abc', 'def', 'ghi');
  UPDATE t6 SET a='ABC', c='ghi';
} {}

do_execsql_test 2.4.2 {
  SELECT * FROM t6 ORDER BY b, a;
  SELECT * FROM t6 ORDER BY c;
} {ABC def ghi ABC def ghi}

do_execsql_test 2.4.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t6');
} {b BINARY 1 a nocase 1 c BINARY 0}


#-------------------------------------------------------------------------
# Unless the destination table is completely empty, the xfer optimization 
# is disabled for WITHOUT ROWID tables. The following tests check for







|















|










|


















|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
  INSERT INTO t4 VALUES('abc', 'def');
  SELECT * FROM t4;
} {abc def}
do_execsql_test 2.1.2 {
  UPDATE t4 SET a = 'ABC';
  SELECT * FROM t4;
} {ABC def}
do_execsql_test_if_vtab 2.1.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}

do_execsql_test 2.2.1 {
  DROP TABLE t4;
  CREATE TABLE t4 (b, a COLLATE nocase PRIMARY KEY) WITHOUT ROWID;
  INSERT INTO t4(a, b) VALUES('abc', 'def');
  SELECT * FROM t4;
} {def abc}

do_execsql_test 2.2.2 {
  UPDATE t4 SET a = 'ABC', b = 'xyz';
  SELECT * FROM t4;
} {xyz ABC}

do_execsql_test_if_vtab 2.2.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t4');
} {a nocase 1 b BINARY 0}


do_execsql_test 2.3.1 {
  CREATE TABLE t5 (a, b, PRIMARY KEY(b, a)) WITHOUT ROWID;
  INSERT INTO t5(a, b) VALUES('abc', 'def');
  UPDATE t5 SET a='abc', b='def';
} {}

do_execsql_test_if_vtab 2.3.2 {
  SELECT name, coll, key FROM pragma_index_xinfo('t5');
} {b BINARY 1 a BINARY 1}


do_execsql_test 2.4.1 {
  CREATE TABLE t6 (
    a COLLATE nocase, b, c UNIQUE, PRIMARY KEY(b, a)
  ) WITHOUT ROWID;

  INSERT INTO t6(a, b, c) VALUES('abc', 'def', 'ghi');
  UPDATE t6 SET a='ABC', c='ghi';
} {}

do_execsql_test 2.4.2 {
  SELECT * FROM t6 ORDER BY b, a;
  SELECT * FROM t6 ORDER BY c;
} {ABC def ghi ABC def ghi}

do_execsql_test_if_vtab 2.4.3 {
  SELECT name, coll, key FROM pragma_index_xinfo('t6');
} {b BINARY 1 a nocase 1 c BINARY 0}


#-------------------------------------------------------------------------
# Unless the destination table is completely empty, the xfer optimization 
# is disabled for WITHOUT ROWID tables. The following tests check for
Changes to test/without_rowid6.test.
11
12
13
14
15
16
17




18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#
# Verify that WITHOUT ROWID tables work correctly when the PRIMARY KEY
# has redundant columns.
#

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





do_execsql_test without_rowid6-100 {
  CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,a,b,c,d,a,b,c)) WITHOUT ROWID;
  CREATE INDEX t1a ON t1(b, b);
  WITH RECURSIVE
    c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<1000)
  INSERT INTO t1(a,b,c,d,e) SELECT i, i+1000, printf('x%dy',i), 0, 0 FROM c;
  ANALYZE;
} {}
do_execsql_test without_rowid6-101 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {a 1 b 1 c 1 d 1 e 0}
do_execsql_test without_rowid6-110 {
  SELECT c FROM t1 WHERE a=123;
} {x123y}
do_execsql_test without_rowid6-120 {
  SELECT c FROM t1 WHERE b=1123;







>
>
>
>









|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#
# Verify that WITHOUT ROWID tables work correctly when the PRIMARY KEY
# has redundant columns.
#

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

proc do_execsql_test_if_vtab {tn sql {res {}}} {
  ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}

do_execsql_test without_rowid6-100 {
  CREATE TABLE t1(a,b,c,d,e, PRIMARY KEY(a,b,c,a,b,c,d,a,b,c)) WITHOUT ROWID;
  CREATE INDEX t1a ON t1(b, b);
  WITH RECURSIVE
    c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<1000)
  INSERT INTO t1(a,b,c,d,e) SELECT i, i+1000, printf('x%dy',i), 0, 0 FROM c;
  ANALYZE;
} {}
do_execsql_test_if_vtab without_rowid6-101 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {a 1 b 1 c 1 d 1 e 0}
do_execsql_test without_rowid6-110 {
  SELECT c FROM t1 WHERE a=123;
} {x123y}
do_execsql_test without_rowid6-120 {
  SELECT c FROM t1 WHERE b=1123;
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
    b UNIQUE,
    c UNIQUE,
    PRIMARY KEY(b)
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test without_rowid6-201 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 a 0 c 0}
do_execsql_test without_rowid6-210 {
  EXPLAIN QUERY PLAN
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {/SEARCH TABLE t1 USING PRIMARY KEY .b>../}
do_execsql_test without_rowid6-220 {







|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    b UNIQUE,
    c UNIQUE,
    PRIMARY KEY(b)
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test_if_vtab without_rowid6-201 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 a 0 c 0}
do_execsql_test without_rowid6-210 {
  EXPLAIN QUERY PLAN
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {/SEARCH TABLE t1 USING PRIMARY KEY .b>../}
do_execsql_test without_rowid6-220 {
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
  CREATE TABLE t1(a,b,c,
    UNIQUE(b,c),
    PRIMARY KEY(b,c)
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test without_rowid6-501 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 c 1 a 0}
do_execsql_test without_rowid6-510 {
  EXPLAIN QUERY PLAN
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {/SEARCH TABLE t1 USING PRIMARY KEY .b>../}
do_execsql_test without_rowid6-520 {







|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  CREATE TABLE t1(a,b,c,
    UNIQUE(b,c),
    PRIMARY KEY(b,c)
  ) WITHOUT ROWID;
  INSERT INTO t1(a,b,c) VALUES(1,8,3),(4,5,6),(7,2,9);
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {4 1}
do_execsql_test_if_vtab without_rowid6-501 {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {b 1 c 1 a 0}
do_execsql_test without_rowid6-510 {
  EXPLAIN QUERY PLAN
  SELECT a FROM t1 WHERE b>3 ORDER BY b;
} {/SEARCH TABLE t1 USING PRIMARY KEY .b>../}
do_execsql_test without_rowid6-520 {
Changes to test/without_rowid7.test.
10
11
12
13
14
15
16




17
18
19
20
21
22
23
#*************************************************************************
# This file implements regression tests for SQLite library.  
#

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





do_execsql_test 1.0 {
  CREATE TABLE t1(a, b COLLATE nocase, PRIMARY KEY(a, a, b)) WITHOUT ROWID;
}

do_catchsql_test 1.1 {
  INSERT INTO t1 VALUES(1, 'one'), (1, 'ONE');







>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#*************************************************************************
# This file implements regression tests for SQLite library.  
#

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

proc do_execsql_test_if_vtab {tn sql {res {}}} {
  ifcapable vtab { uplevel [list do_execsql_test $tn $sql $res] }
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b COLLATE nocase, PRIMARY KEY(a, a, b)) WITHOUT ROWID;
}

do_catchsql_test 1.1 {
  INSERT INTO t1 VALUES(1, 'one'), (1, 'ONE');
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  INSERT INTO t2 VALUES(1, 'one');
  SELECT b FROM t2;
} {one}

do_execsql_test 2.2a {
  PRAGMA index_info(t2);
} {0 0 a 1 0 a}
do_execsql_test 2.2b {
  SELECT *, '|' FROM pragma_index_info('t2');
} {0 0 a | 1 0 a |}
do_execsql_test 2.3a {
  PRAGMA index_xinfo(t2);
} {0 0 a 0 nocase 1 1 0 a 0 BINARY 1 2 1 b 0 BINARY 0}
do_execsql_test 2.3b {
  SELECT *, '|' FROM pragma_index_xinfo('t2');
} {0 0 a 0 nocase 1 | 1 0 a 0 BINARY 1 | 2 1 b 0 BINARY 0 |}

do_execsql_test 2.4 {
  CREATE TABLE t3(a, b, PRIMARY KEY(a COLLATE nocase, a));
  PRAGMA index_info(t3);
} {}



finish_test







|





|











36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  INSERT INTO t2 VALUES(1, 'one');
  SELECT b FROM t2;
} {one}

do_execsql_test 2.2a {
  PRAGMA index_info(t2);
} {0 0 a 1 0 a}
do_execsql_test_if_vtab 2.2b {
  SELECT *, '|' FROM pragma_index_info('t2');
} {0 0 a | 1 0 a |}
do_execsql_test 2.3a {
  PRAGMA index_xinfo(t2);
} {0 0 a 0 nocase 1 1 0 a 0 BINARY 1 2 1 b 0 BINARY 0}
do_execsql_test_if_vtab 2.3b {
  SELECT *, '|' FROM pragma_index_xinfo('t2');
} {0 0 a 0 nocase 1 | 1 0 a 0 BINARY 1 | 2 1 b 0 BINARY 0 |}

do_execsql_test 2.4 {
  CREATE TABLE t3(a, b, PRIMARY KEY(a COLLATE nocase, a));
  PRAGMA index_info(t3);
} {}



finish_test