SQLite

Check-in [f2a8b5ccfb]
Login

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

Overview
Comment:Fix the expected output on tests so that it corresponds to the new query planner results. All of veryquick.test is now passing with SQLITE_ENABLE_STAT2.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | branch-3.7.2
Files: files | file ages | folders
SHA1: f2a8b5ccfb46b6be5c8857bc495de14e55851bf4
User & Date: drh 2011-02-12 14:23:48.545
Context
2011-03-04
01:23
Backport the query planner enhancement of [952f5e8c69904] to the 3.7.2 branch. (check-in: 440d995661 user: drh tags: branch-3.7.2)
2011-02-12
14:23
Fix the expected output on tests so that it corresponds to the new query planner results. All of veryquick.test is now passing with SQLITE_ENABLE_STAT2. (check-in: f2a8b5ccfb user: drh tags: branch-3.7.2)
05:34
Fix problems in the backport, reducing the number of errors in the TCL tests to just a few dozen. Most of the remaining errors seem to be real and desirable changes of behavior. (check-in: 9d2b0af266 user: drh tags: branch-3.7.2)
Changes
Unified Diff Ignore Whitespace Patch
Changes to test/analyze.test.
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
    ANALYZE main.t1;
  }
} {0 {}}
do_test analyze-1.11 {
  execsql {
    SELECT * FROM sqlite_stat1
  }
} {}
do_test analyze-1.12 {
  catchsql {
    ANALYZE t1;
  }
} {0 {}}
do_test analyze-1.13 {
  execsql {
    SELECT * FROM sqlite_stat1
  }
} {}

# Create some indices that can be analyzed.  But do not yet add
# data.  Without data in the tables, no analysis is done.
#
do_test analyze-2.1 {
  execsql {
    CREATE INDEX t1i1 ON t1(a);
    ANALYZE main.t1;
    SELECT * FROM sqlite_stat1 ORDER BY idx;
  }
} {}
do_test analyze-2.2 {
  execsql {
    CREATE INDEX t1i2 ON t1(b);
    ANALYZE t1;
    SELECT * FROM sqlite_stat1 ORDER BY idx;
  }
} {}
do_test analyze-2.3 {
  execsql {
    CREATE INDEX t1i3 ON t1(a,b);
    ANALYZE main;
    SELECT * FROM sqlite_stat1 ORDER BY idx;
  }
} {}

# Start adding data to the table.  Verify that the analysis
# is done correctly.
#
do_test analyze-3.1 {
  execsql {
    INSERT INTO t1 VALUES(1,2);







|









|










|






|






|







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
    ANALYZE main.t1;
  }
} {0 {}}
do_test analyze-1.11 {
  execsql {
    SELECT * FROM sqlite_stat1
  }
} {t1 {} 0}
do_test analyze-1.12 {
  catchsql {
    ANALYZE t1;
  }
} {0 {}}
do_test analyze-1.13 {
  execsql {
    SELECT * FROM sqlite_stat1
  }
} {t1 {} 0}

# Create some indices that can be analyzed.  But do not yet add
# data.  Without data in the tables, no analysis is done.
#
do_test analyze-2.1 {
  execsql {
    CREATE INDEX t1i1 ON t1(a);
    ANALYZE main.t1;
    SELECT * FROM sqlite_stat1 ORDER BY idx;
  }
} {t1 {} 0}
do_test analyze-2.2 {
  execsql {
    CREATE INDEX t1i2 ON t1(b);
    ANALYZE t1;
    SELECT * FROM sqlite_stat1 ORDER BY idx;
  }
} {t1 {} 0}
do_test analyze-2.3 {
  execsql {
    CREATE INDEX t1i3 ON t1(a,b);
    ANALYZE main;
    SELECT * FROM sqlite_stat1 ORDER BY idx;
  }
} {t1 {} 0}

# Start adding data to the table.  Verify that the analysis
# is done correctly.
#
do_test analyze-3.1 {
  execsql {
    INSERT INTO t1 VALUES(1,2);
Changes to test/analyze2.test.
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
  }
  for {set i 0} {$i < 1000} {incr i} {
    execsql { INSERT INTO t1 VALUES($i, $i) }
  }
  execsql COMMIT
  execsql ANALYZE
} {}
do_eqp_test 2.2 {
  SELECT * FROM t1 WHERE x>500 AND y>700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)}
}
do_eqp_test 2.3 {
  SELECT * FROM t1 WHERE x>700 AND y>500
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)}
}
do_eqp_test 2.3 {
  SELECT * FROM t1 WHERE y>700 AND x>500
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)}
}
do_eqp_test 2.4 {
  SELECT * FROM t1 WHERE y>500 AND x>700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)}
}
do_eqp_test 2.5 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 200 AND y BETWEEN 400 AND 700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~25 rows)}
}
do_eqp_test 2.6 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 400 AND 700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~75 rows)}
}
do_eqp_test 2.7 {
  SELECT * FROM t1 WHERE x BETWEEN -400 AND -300 AND y BETWEEN 100 AND 300
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)}
}
do_eqp_test 2.8 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN -400 AND -300
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)}
}
do_eqp_test 2.9 {
  SELECT * FROM t1 WHERE x BETWEEN 500 AND 100 AND y BETWEEN 100 AND 300
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)}
}
do_eqp_test 2.10 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN 500 AND 100
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)}
}

do_test analyze2-3.1 {
  set alphabet [list a b c d e f g h i j]







|




|




|




|




|




|




|




|




|




|







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
  }
  for {set i 0} {$i < 1000} {incr i} {
    execsql { INSERT INTO t1 VALUES($i, $i) }
  }
  execsql COMMIT
  execsql ANALYZE
} {}
do_eqp_test analyze2-2.2 {
  SELECT * FROM t1 WHERE x>500 AND y>700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)}
}
do_eqp_test analyze2-2.3 {
  SELECT * FROM t1 WHERE x>700 AND y>500
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)}
}
do_eqp_test analyze2-2.3 {
  SELECT * FROM t1 WHERE y>700 AND x>500
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)}
}
do_eqp_test analyze2-2.4 {
  SELECT * FROM t1 WHERE y>500 AND x>700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)}
}
do_eqp_test analyze2-2.5 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 200 AND y BETWEEN 400 AND 700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~25 rows)}
}
do_eqp_test analyze2-2.6 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 400 AND 700
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~75 rows)}
}
do_eqp_test analyze2-2.7 {
  SELECT * FROM t1 WHERE x BETWEEN -400 AND -300 AND y BETWEEN 100 AND 300
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)}
}
do_eqp_test analyze2-2.8 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN -400 AND -300
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)}
}
do_eqp_test analyze2-2.9 {
  SELECT * FROM t1 WHERE x BETWEEN 500 AND 100 AND y BETWEEN 100 AND 300
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)}
}
do_eqp_test analyze2-2.10 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN 500 AND 100
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)}
}

do_test analyze2-3.1 {
  set alphabet [list a b c d e f g h i j]
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't1_y' 
    GROUP BY tbl,idx
  }
} {t1 t1_y {100 299 499 699 899 ajj cjj ejj gjj ijj}}

do_eqp_test 3.3 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 'a' AND 'b'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~50 rows)}
}
do_eqp_test 3.4 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 400 AND y BETWEEN 'a' AND 'h'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~100 rows)}
}
do_eqp_test 3.5 {
  SELECT * FROM t1 WHERE x<'a' AND y>'h'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)}
}
do_eqp_test 3.6 {
  SELECT * FROM t1 WHERE x<444 AND y>'h'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)}
}
do_eqp_test 3.7 {
  SELECT * FROM t1 WHERE x<221 AND y>'g'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x<?) (~66 rows)}
}

do_test analyze2-4.1 {
  execsql { CREATE TABLE t3(a COLLATE nocase, b) }







|




|




|




|




|







195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't1_y' 
    GROUP BY tbl,idx
  }
} {t1 t1_y {100 299 499 699 899 ajj cjj ejj gjj ijj}}

do_eqp_test analyze2-3.3 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 'a' AND 'b'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~50 rows)}
}
do_eqp_test analyze2-3.4 {
  SELECT * FROM t1 WHERE x BETWEEN 100 AND 400 AND y BETWEEN 'a' AND 'h'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~100 rows)}
}
do_eqp_test analyze2-3.5 {
  SELECT * FROM t1 WHERE x<'a' AND y>'h'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)}
}
do_eqp_test analyze2-3.6 {
  SELECT * FROM t1 WHERE x<444 AND y>'h'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)}
}
do_eqp_test analyze2-3.7 {
  SELECT * FROM t1 WHERE x<221 AND y>'g'
} {
  0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x<?) (~66 rows)}
}

do_test analyze2-4.1 {
  execsql { CREATE TABLE t3(a COLLATE nocase, b) }
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't3b' 
    GROUP BY tbl,idx
  }
} {t3 t3b {AbA CIj EIj GIj IIj bIj dIj fIj hIj jIj}}

do_eqp_test 4.4 {
  SELECT * FROM t3 WHERE a > 'A' AND a < 'C' AND b > 'A' AND b < 'C'
} {
  0 0 0 {SEARCH TABLE t3 USING INDEX t3b (b>? AND b<?) (~11 rows)}
}
do_eqp_test 4.5 {
  SELECT * FROM t3 WHERE a > 'A' AND a < 'c' AND b > 'A' AND b < 'c'
} {
  0 0 0 {SEARCH TABLE t3 USING INDEX t3a (a>? AND a<?) (~22 rows)}
}

ifcapable utf16 {
  proc test_collate {enc lhs rhs} {







|




|







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
    SELECT tbl,idx,group_concat(sample,' ') 
    FROM sqlite_stat2 
    WHERE idx = 't3b' 
    GROUP BY tbl,idx
  }
} {t3 t3b {AbA CIj EIj GIj IIj bIj dIj fIj hIj jIj}}

do_eqp_test analyze2-4.4 {
  SELECT * FROM t3 WHERE a > 'A' AND a < 'C' AND b > 'A' AND b < 'C'
} {
  0 0 0 {SEARCH TABLE t3 USING INDEX t3b (b>? AND b<?) (~11 rows)}
}
do_eqp_test analyze2-4.5 {
  SELECT * FROM t3 WHERE a > 'A' AND a < 'c' AND b > 'A' AND b < 'c'
} {
  0 0 0 {SEARCH TABLE t3 USING INDEX t3a (a>? AND a<?) (~22 rows)}
}

ifcapable utf16 {
  proc test_collate {enc lhs rhs} {
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    execsql { 
      SELECT tbl,idx,group_concat(sample,' ') 
      FROM sqlite_stat2 
      WHERE tbl = 't4' 
      GROUP BY tbl,idx
    }
  } {t4 t4x {afa bej cej dej eej fej gej hej iej jej}}
  do_eqp_test 5.3 {
    SELECT * FROM t4 WHERE x>'ccc'
  } {0 0 0 {SEARCH TABLE t4 USING COVERING INDEX t4x (x>?) (~800 rows)}}
  do_eqp_test 5.4 {
    SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ccc' AND t42.x>'ggg'
  } {
    0 0 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~300 rows)} 
    0 1 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~800 rows)}
  }
  do_eqp_test 5.5 {
    SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ddd' AND t42.x>'ccc'
  } {
    0 0 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~700 rows)} 
    0 1 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~800 rows)}
  }
}








|


|





|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    execsql { 
      SELECT tbl,idx,group_concat(sample,' ') 
      FROM sqlite_stat2 
      WHERE tbl = 't4' 
      GROUP BY tbl,idx
    }
  } {t4 t4x {afa bej cej dej eej fej gej hej iej jej}}
  do_eqp_test analyze2-5.3 {
    SELECT * FROM t4 WHERE x>'ccc'
  } {0 0 0 {SEARCH TABLE t4 USING COVERING INDEX t4x (x>?) (~800 rows)}}
  do_eqp_test analyze2-5.4 {
    SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ccc' AND t42.x>'ggg'
  } {
    0 0 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~300 rows)} 
    0 1 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~800 rows)}
  }
  do_eqp_test analyze2-5.5 {
    SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ddd' AND t42.x>'ccc'
  } {
    0 0 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~700 rows)} 
    0 1 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~800 rows)}
  }
}

Changes to test/analyze3.test.
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  }
  execsql {
    COMMIT;
    ANALYZE;
  }
} {}

do_test analyze3-1.1.2 {
  eqp { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test analyze3-1.1.3 {
  eqp { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
} {0 0 {TABLE t1}}

do_test analyze3-1.1.4 {
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.1.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]







|
|
|
|
|
|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  }
  execsql {
    COMMIT;
    ANALYZE;
  }
} {}

do_eqp_test analyze3-1.1.2 {
  SELECT sum(y) FROM t1 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~100 rows)}}
do_eqp_test analyze3-1.1.3 {
  SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 
} {0 0 0 {SCAN TABLE t1 (~111 rows)}}

do_test analyze3-1.1.4 {
  sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.1.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
      CREATE TABLE t2(x TEXT, y);
      INSERT INTO t2 SELECT * FROM t1;
      CREATE INDEX i2 ON t2(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_test analyze3-1.2.2 {
  eqp { SELECT sum(y) FROM t2 WHERE x>1 AND x<2 }
} {0 0 {TABLE t2 WITH INDEX i2}}
do_test analyze3-1.2.3 {
  eqp { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
} {0 0 {TABLE t2}}
do_test analyze3-1.2.4 {
  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
} {161 0 4760}
do_test analyze3-1.2.5 {
  set l [string range "12" 0 end]
  set u [string range "20" 0 end]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}







|
|
|
|
|
|







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
      CREATE TABLE t2(x TEXT, y);
      INSERT INTO t2 SELECT * FROM t1;
      CREATE INDEX i2 ON t2(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_eqp_test analyze3-1.2.2 {
  SELECT sum(y) FROM t2 WHERE x>1 AND x<2
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~200 rows)}}
do_eqp_test analyze3-1.2.3 {
  SELECT sum(y) FROM t2 WHERE x>0 AND x<99
} {0 0 0 {SCAN TABLE t2 (~111 rows)}}
do_test analyze3-1.2.4 {
  sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
} {161 0 4760}
do_test analyze3-1.2.5 {
  set l [string range "12" 0 end]
  set u [string range "20" 0 end]
  sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
      CREATE TABLE t3(y TEXT, x INTEGER);
      INSERT INTO t3 SELECT y, x FROM t1;
      CREATE INDEX i3 ON t3(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_test analyze3-1.3.2 {
  eqp { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
} {0 0 {TABLE t3 WITH INDEX i3}}
do_test analyze3-1.3.3 {
  eqp { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
} {0 0 {TABLE t3}}

do_test analyze3-1.3.4 {
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.3.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]







|
|
|
|
|
|







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
      CREATE TABLE t3(y TEXT, x INTEGER);
      INSERT INTO t3 SELECT y, x FROM t1;
      CREATE INDEX i3 ON t3(x);
    COMMIT;
    ANALYZE;
  }
} {}
do_eqp_test analyze3-1.3.2 {
  SELECT sum(y) FROM t3 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~100 rows)}}
do_eqp_test analyze3-1.3.3 {
  SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
} {0 0 0 {SCAN TABLE t3 (~111 rows)}}

do_test analyze3-1.3.4 {
  sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
} {199 0 14850}
do_test analyze3-1.3.5 {
  set l [string range "200" 0 end]
  set u [string range "300" 0 end]
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
    append t [lindex {a b c d e f g h i j} [expr $i/100]]
    append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
    execsql { INSERT INTO t1 VALUES($i, $t) }
  }
  execsql COMMIT
} {}
do_test analyze3-2.2 {
  eqp { SELECT count(a) FROM t1 WHERE b LIKE 'a%' }
} {0 0 {TABLE t1 WITH INDEX i1}}
do_test analyze3-2.3 {
  eqp { SELECT count(a) FROM t1 WHERE b LIKE '%a' }
} {0 0 {TABLE t1}}

do_test analyze3-2.4 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
} {101 0 100}
do_test analyze3-2.5 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
} {999 999 100}







|
|
|
|
|
|







242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
    append t [lindex {a b c d e f g h i j} [expr $i/100]]
    append t [lindex {a b c d e f g h i j} [expr ($i/10)%10]]
    append t [lindex {a b c d e f g h i j} [expr ($i%10)]]
    execsql { INSERT INTO t1 VALUES($i, $t) }
  }
  execsql COMMIT
} {}
do_eqp_test analyze3-2.2 {
  SELECT count(a) FROM t1 WHERE b LIKE 'a%'
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?) (~30000 rows)}}
do_eqp_test analyze3-2.3 {
  SELECT count(a) FROM t1 WHERE b LIKE '%a'
} {0 0 0 {SCAN TABLE t1 (~500000 rows)}}

do_test analyze3-2.4 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
} {101 0 100}
do_test analyze3-2.5 {
  sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
} {999 999 100}
Changes to test/auth.test.
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
      CREATE TABLE t4(a,b,c);
      CREATE INDEX t4i1 ON t4(a);
      CREATE INDEX t4i2 ON t4(b,a,c);
      INSERT INTO t4 VALUES(1,2,3);
      ANALYZE;
    }
    set ::authargs
  } {t4 {} main {}}
  do_test auth-1.295 {
    execsql {
      SELECT count(*) FROM sqlite_stat1;
    }
  } 2
  proc auth {code args} {
    if {$code=="SQLITE_ANALYZE"} {
      set ::authargs [concat $::authargs $args]
      return SQLITE_DENY
    }
    return SQLITE_OK
  }
  do_test auth-1.296 {
    set ::authargs {}
    catchsql {
      ANALYZE;
    }
  } {1 {not authorized}}
  do_test auth-1.297 {
    execsql {
      SELECT count(*) FROM sqlite_stat1;
    }
  } 2
} ;# ifcapable analyze


# Authorization for ALTER TABLE ADD COLUMN.
# These tests are omitted if the library
# was built without ALTER TABLE support.
ifcapable {altertable} {







|




|

















|







1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
      CREATE TABLE t4(a,b,c);
      CREATE INDEX t4i1 ON t4(a);
      CREATE INDEX t4i2 ON t4(b,a,c);
      INSERT INTO t4 VALUES(1,2,3);
      ANALYZE;
    }
    set ::authargs
  } {t4 {} main {} t2 {} main {}}
  do_test auth-1.295 {
    execsql {
      SELECT count(*) FROM sqlite_stat1;
    }
  } 3
  proc auth {code args} {
    if {$code=="SQLITE_ANALYZE"} {
      set ::authargs [concat $::authargs $args]
      return SQLITE_DENY
    }
    return SQLITE_OK
  }
  do_test auth-1.296 {
    set ::authargs {}
    catchsql {
      ANALYZE;
    }
  } {1 {not authorized}}
  do_test auth-1.297 {
    execsql {
      SELECT count(*) FROM sqlite_stat1;
    }
  } 3
} ;# ifcapable analyze


# Authorization for ALTER TABLE ADD COLUMN.
# These tests are omitted if the library
# was built without ALTER TABLE support.
ifcapable {altertable} {
Changes to test/autoindex1.test.
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
    SELECT count(*) FROM t4;
  }
} {4096}
do_test autoindex1-401 {
  db eval {
    SELECT count(*)
      FROM t4 AS x1
/*      JOIN t4 AS x2 ON x2.a=x1.b
      JOIN t4 AS x3 ON x3.a=x2.b
      JOIN t4 AS x4 ON x4.a=x3.b
      JOIN t4 AS x5 ON x5.a=x4.b
      JOIN t4 AS x6 ON x6.a=x5.b
      JOIN t4 AS x7 ON x7.a=x6.b
      JOIN t4 AS x8 ON x8.a=x7.b
      JOIN t4 AS x9 ON x9.a=x8.b
      JOIN t4 AS x10 ON x10.a=x9.b;*/
  }
} {4087 FIXME}

# Ticket [8011086c85c6c404014c947fcf3eb9f42b184a0d] from 2010-07-08
# Make sure automatic indices are not created for the RHS of an IN expression
# that is not a correlated subquery.
#
do_test autoindex1-500 {
  db eval {
    CREATE TABLE t501(a INTEGER PRIMARY KEY, b);
    CREATE TABLE t502(x INTEGER PRIMARY KEY, y);
    EXPLAIN QUERY PLAN
    SELECT b FROM t501
     WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
  }
} {0 0 {TABLE t501 USING PRIMARY KEY} 0 0 {TABLE t502}}
do_test autoindex1-501 {
  db eval {
    EXPLAIN QUERY PLAN
    SELECT b FROM t501
     WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
  }
} {0 0 {TABLE t501} 0 0 {TABLE t502 WITH AUTOMATIC INDEX}}
do_test autoindex1-502 {
  db eval {
    EXPLAIN QUERY PLAN
    SELECT b FROM t501
     WHERE t501.a=123
       AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
  }
} {0 0 {TABLE t501 USING PRIMARY KEY} 0 0 {TABLE t502}}
    

finish_test







|







|

|













|






|







<
|


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
    SELECT count(*) FROM t4;
  }
} {4096}
do_test autoindex1-401 {
  db eval {
    SELECT count(*)
      FROM t4 AS x1
      JOIN t4 AS x2 ON x2.a=x1.b
      JOIN t4 AS x3 ON x3.a=x2.b
      JOIN t4 AS x4 ON x4.a=x3.b
      JOIN t4 AS x5 ON x5.a=x4.b
      JOIN t4 AS x6 ON x6.a=x5.b
      JOIN t4 AS x7 ON x7.a=x6.b
      JOIN t4 AS x8 ON x8.a=x7.b
      JOIN t4 AS x9 ON x9.a=x8.b
      JOIN t4 AS x10 ON x10.a=x9.b;
  }
} {4087}

# Ticket [8011086c85c6c404014c947fcf3eb9f42b184a0d] from 2010-07-08
# Make sure automatic indices are not created for the RHS of an IN expression
# that is not a correlated subquery.
#
do_test autoindex1-500 {
  db eval {
    CREATE TABLE t501(a INTEGER PRIMARY KEY, b);
    CREATE TABLE t502(x INTEGER PRIMARY KEY, y);
    EXPLAIN QUERY PLAN
    SELECT b FROM t501
     WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
  }
} {0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) (~25 rows)} 0 0 0 {SCAN TABLE t502 (~100000 rows)}}
do_test autoindex1-501 {
  db eval {
    EXPLAIN QUERY PLAN
    SELECT b FROM t501
     WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
  }
} {0 0 0 {SCAN TABLE t501 (~500000 rows)} 0 0 0 {SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?) (~7 rows)}}
do_test autoindex1-502 {
  db eval {
    EXPLAIN QUERY PLAN
    SELECT b FROM t501
     WHERE t501.a=123
       AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
  }

} {0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 0 0 0 {SCAN TABLE t502 (~100000 rows)}}

finish_test
Changes to test/e_fkey.test.
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
} {}
do_test e_fkey-25.2 {
  execsql {
    PRAGMA foreign_keys = OFF;
    EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
    EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?;
  }
} {0 0 {TABLE artist} 0 0 {TABLE track}}
do_test e_fkey-25.3 {
  execsql { 
    PRAGMA foreign_keys = ON;
    EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
  }
} {0 0 {TABLE artist} 0 0 {TABLE track}}
do_test e_fkey-25.4 {
  execsql {
    INSERT INTO artist VALUES(5, 'artist 5');
    INSERT INTO artist VALUES(6, 'artist 6');
    INSERT INTO artist VALUES(7, 'artist 7');
    INSERT INTO track VALUES(1, 'track 1', 5);
    INSERT INTO track VALUES(2, 'track 2', 6);







|





|







970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
} {}
do_test e_fkey-25.2 {
  execsql {
    PRAGMA foreign_keys = OFF;
    EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
    EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?;
  }
} {0 0 0 {SCAN TABLE artist (~1000000 rows)} 0 0 0 {SCAN TABLE track (~100000 rows)}}
do_test e_fkey-25.3 {
  execsql { 
    PRAGMA foreign_keys = ON;
    EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
  }
} {0 0 0 {SCAN TABLE artist (~1000000 rows)} 0 0 0 {SCAN TABLE track (~100000 rows)}}
do_test e_fkey-25.4 {
  execsql {
    INSERT INTO artist VALUES(5, 'artist 5');
    INSERT INTO artist VALUES(6, 'artist 6');
    INSERT INTO artist VALUES(7, 'artist 7');
    INSERT INTO track VALUES(1, 'track 1', 5);
    INSERT INTO track VALUES(2, 'track 2', 6);
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
} {}
do_test e_fkey-27.2 {
  eqp { INSERT INTO artist VALUES(?, ?) }
} {}
do_test e_fkey-27.3 {
  eqp { UPDATE artist SET artistid = ?, artistname = ? }
} [list \
  0 0 {TABLE artist} \
  0 0 {TABLE track WITH INDEX trackindex} \
  0 0 {TABLE track WITH INDEX trackindex}
]
do_test e_fkey-27.4 {
  eqp { DELETE FROM artist }
} [list \
  0 0 {TABLE artist} \
  0 0 {TABLE track WITH INDEX trackindex}
]


###########################################################################
### SECTION 4.1: Composite Foreign Key Constraints
###########################################################################








|
|
|




|
|







1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
} {}
do_test e_fkey-27.2 {
  eqp { INSERT INTO artist VALUES(?, ?) }
} {}
do_test e_fkey-27.3 {
  eqp { UPDATE artist SET artistid = ?, artistname = ? }
} [list \
  0 0 0 {SCAN TABLE artist (~1000000 rows)} \
  0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)} \
  0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)}
]
do_test e_fkey-27.4 {
  eqp { DELETE FROM artist }
} [list \
  0 0 0 {SCAN TABLE artist (~1000000 rows)} \
  0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)}
]


###########################################################################
### SECTION 4.1: Composite Foreign Key Constraints
###########################################################################

Changes to test/minmax3.test.
48
49
50
51
52
53
54

55
56
57
58
59
60
61
    INSERT INTO t1 VALUES('1', 'I',   'one');
    INSERT INTO t1 VALUES('2', 'IV',  'four');
    INSERT INTO t1 VALUES('2', NULL,  'three');
    INSERT INTO t1 VALUES('2', 'II',  'two');
    INSERT INTO t1 VALUES('2', 'V',   'five');
    INSERT INTO t1 VALUES('3', 'VI',  'six');
    COMMIT;

  }
} {}
do_test minmax3-1.1.1 {
  # Linear scan.
  count { SELECT max(y) FROM t1 WHERE x = '2'; }
} {V 5}
do_test minmax3-1.1.2 {







>







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    INSERT INTO t1 VALUES('1', 'I',   'one');
    INSERT INTO t1 VALUES('2', 'IV',  'four');
    INSERT INTO t1 VALUES('2', NULL,  'three');
    INSERT INTO t1 VALUES('2', 'II',  'two');
    INSERT INTO t1 VALUES('2', 'V',   'five');
    INSERT INTO t1 VALUES('3', 'VI',  'six');
    COMMIT;
    PRAGMA automatic_index=OFF;
  }
} {}
do_test minmax3-1.1.1 {
  # Linear scan.
  count { SELECT max(y) FROM t1 WHERE x = '2'; }
} {V 5}
do_test minmax3-1.1.2 {
Changes to test/misc4.test.
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
      insert into b values ('01',1);
      insert into b values ('01',2);
      insert into b values ('+1',3);
      insert into b values ('+1',4);
      
      select a.*, x.*
        from a, (select key,sum(period) from b group by key) as x
        where a.key=x.key;
    }
  } {01 data01 01 3 +1 data+1 +1 7}

  # This test case tests the same property as misc4-4.1, but it is
  # a bit smaller which makes it easier to work with while debugging.
  do_test misc4-4.2 {
    execsql {







|







147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
      insert into b values ('01',1);
      insert into b values ('01',2);
      insert into b values ('+1',3);
      insert into b values ('+1',4);
      
      select a.*, x.*
        from a, (select key,sum(period) from b group by key) as x
        where a.key=x.key order by 1 desc;
    }
  } {01 data01 01 3 +1 data+1 +1 7}

  # This test case tests the same property as misc4-4.1, but it is
  # a bit smaller which makes it easier to work with while debugging.
  do_test misc4-4.2 {
    execsql {
Changes to test/select6.test.
454
455
456
457
458
459
460

461
462
463
464
465
466
467
} ;# ifcapable view

# Ticket #1634
#
do_test select6-9.1 {
  execsql {
    SELECT a.x, b.x FROM t1 AS a, (SELECT x FROM t1 LIMIT 2) AS b

  }
} {1 1 1 2 2 1 2 2 3 1 3 2 4 1 4 2}
do_test select6-9.2 {
  execsql {
    SELECT x FROM (SELECT x FROM t1 LIMIT 2);
  }
} {1 2}







>







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
} ;# ifcapable view

# Ticket #1634
#
do_test select6-9.1 {
  execsql {
    SELECT a.x, b.x FROM t1 AS a, (SELECT x FROM t1 LIMIT 2) AS b
     ORDER BY 1, 2
  }
} {1 1 1 2 2 1 2 2 3 1 3 2 4 1 4 2}
do_test select6-9.2 {
  execsql {
    SELECT x FROM (SELECT x FROM t1 LIMIT 2);
  }
} {1 2}
Changes to test/tester.tcl.
329
330
331
332
333
334
335


336
337
338
339
340
341


342
343
344
345
346
347
348
349
350
  } else {
    puts " Ok"
  }
  flush stdout
}
    
proc do_execsql_test {testname sql result} {


  uplevel do_test $testname [list "execsql {$sql}"] [list $result]
}
proc do_catchsql_test {testname sql result} {
  uplevel do_test $testname [list "catchsql {$sql}"] [list $result]
}
proc do_eqp_test {name sql res} {


  uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] \
     [list [string trim $res]]
}


# Run an SQL script.  
# Return the number of microseconds per statement.
#
proc speed_trial {name numstmt units sql} {







>
>
|





>
>
|
<







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
  } else {
    puts " Ok"
  }
  flush stdout
}
    
proc do_execsql_test {testname sql result} {
  set r {}
  foreach x $result {lappend r $x}
  uplevel do_test $testname [list "execsql {$sql}"] [list $r]
}
proc do_catchsql_test {testname sql result} {
  uplevel do_test $testname [list "catchsql {$sql}"] [list $result]
}
proc do_eqp_test {name sql res} {
  set r {}
  foreach x $res {lappend r $x}
  uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $r]

}


# Run an SQL script.  
# Return the number of microseconds per statement.
#
proc speed_trial {name numstmt units sql} {
Changes to test/tkt-78e04e52ea.test.
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
    CREATE INDEX i1 ON ""("" COLLATE nocase);
  }
} {}
do_test tkt-78e04-1.4 {
  execsql {
    EXPLAIN QUERY PLAN SELECT * FROM "" WHERE "" LIKE 'abc%';
  }
} {0 0 {TABLE }}
do_test tkt-78e04-1.5 {
  execsql {
    DROP TABLE "";
    SELECT name FROM sqlite_master;
  }
} {t2}

do_test tkt-78e04-2.1 {
  execsql {
    CREATE INDEX "" ON t2(x);
    EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=5;
  }
} {0 0 {TABLE t2 WITH INDEX }}
do_test tkt-78e04-2.2 {
  execsql {
    DROP INDEX "";
    EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=2;
  }
} {0 0 {TABLE t2}}

finish_test







|












|





|


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
    CREATE INDEX i1 ON ""("" COLLATE nocase);
  }
} {}
do_test tkt-78e04-1.4 {
  execsql {
    EXPLAIN QUERY PLAN SELECT * FROM "" WHERE "" LIKE 'abc%';
  }
} {0 0 0 {SCAN TABLE  (~500000 rows)}}
do_test tkt-78e04-1.5 {
  execsql {
    DROP TABLE "";
    SELECT name FROM sqlite_master;
  }
} {t2}

do_test tkt-78e04-2.1 {
  execsql {
    CREATE INDEX "" ON t2(x);
    EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=5;
  }
} {0 0 0 {SEARCH TABLE t2 USING COVERING INDEX  (x=?) (~10 rows)}}
do_test tkt-78e04-2.2 {
  execsql {
    DROP INDEX "";
    EXPLAIN QUERY PLAN SELECT * FROM t2 WHERE x=2;
  }
} {0 0 0 {SCAN TABLE t2 (~100000 rows)}}

finish_test
Changes to test/tkt3442.test.
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
# These tests perform an EXPLAIN QUERY PLAN on both versions of the 
# SELECT referenced in ticket #3442 (both '5000' and "5000") 
# and verify that the query plan is the same.
#
ifcapable explain {
  do_test tkt3442-1.2 {
    EQP { SELECT node FROM listhash WHERE id='5000' LIMIT 1; }
  } {0 0 {TABLE listhash WITH INDEX ididx}}
  do_test tkt3442-1.3 {
    EQP { SELECT node FROM listhash WHERE id="5000" LIMIT 1; }
  } {0 0 {TABLE listhash WITH INDEX ididx}}
}


# Some extra tests testing other permutations of 5000.
#
ifcapable explain {
  do_test tkt3442-1.4 {
    EQP { SELECT node FROM listhash WHERE id=5000 LIMIT 1; }
  } {0 0 {TABLE listhash WITH INDEX ididx}}
}
do_test tkt3442-1.5 {
  catchsql {
    SELECT node FROM listhash WHERE id=[5000] LIMIT 1;
  }
} {1 {no such column: 5000}}








|


|








|







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
# These tests perform an EXPLAIN QUERY PLAN on both versions of the 
# SELECT referenced in ticket #3442 (both '5000' and "5000") 
# and verify that the query plan is the same.
#
ifcapable explain {
  do_test tkt3442-1.2 {
    EQP { SELECT node FROM listhash WHERE id='5000' LIMIT 1; }
  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?) (~1 rows)}}
  do_test tkt3442-1.3 {
    EQP { SELECT node FROM listhash WHERE id="5000" LIMIT 1; }
  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?) (~1 rows)}}
}


# Some extra tests testing other permutations of 5000.
#
ifcapable explain {
  do_test tkt3442-1.4 {
    EQP { SELECT node FROM listhash WHERE id=5000 LIMIT 1; }
  } {0 0 0 {SEARCH TABLE listhash USING INDEX ididx (id=?) (~1 rows)}}
}
do_test tkt3442-1.5 {
  catchsql {
    SELECT node FROM listhash WHERE id=[5000] LIMIT 1;
  }
} {1 {no such column: 5000}}

Changes to test/tkt3757.test.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  db eval {
     CREATE TABLE t1(x INTEGER, y INTEGER, z TEXT);
     CREATE INDEX t1i1 ON t1(y,z);
     INSERT INTO t1 VALUES(1,2,'three');
     CREATE TABLE t2(a INTEGER, b TEXT);
     INSERT INTO t2 VALUES(2, 'two');
     ANALYZE;
     SELECT * FROM sqlite_stat1;
  }
} {t1 t1i1 {1 1 1}}

# Modify statistics in order to make the optimizer then that:
#
#   (1)  Table T1 has about 250K entries
#   (2)  There are only about 5 distinct values of T1.
#
# Then run a query with "t1.y IN (SELECT ..)" in the WHERE clause.







|

|







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  db eval {
     CREATE TABLE t1(x INTEGER, y INTEGER, z TEXT);
     CREATE INDEX t1i1 ON t1(y,z);
     INSERT INTO t1 VALUES(1,2,'three');
     CREATE TABLE t2(a INTEGER, b TEXT);
     INSERT INTO t2 VALUES(2, 'two');
     ANALYZE;
     SELECT * FROM sqlite_stat1 ORDER BY 1, 2;
  }
} {t1 t1i1 {1 1 1} t2 {} 1}

# Modify statistics in order to make the optimizer then that:
#
#   (1)  Table T1 has about 250K entries
#   (2)  There are only about 5 distinct values of T1.
#
# Then run a query with "t1.y IN (SELECT ..)" in the WHERE clause.
Changes to test/tkt3824.test.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    SELECT a FROM t2 WHERE b=2 AND c IS NULL ORDER BY b, a;
  }
} {5 9 sort}
do_test tkt3824-2.3 {
  lsort [execsql_status {
    SELECT a FROM t2 WHERE b=2 AND c IS NULL ORDER BY b;
  }]
} {5 9 sort}

do_test tkt3824-3.1 {
  db eval {
    CREATE TABLE t3(x,y);
    INSERT INTO t3 SELECT a, b FROM t1;
    INSERT INTO t3 VALUES(234,567);
    CREATE UNIQUE INDEX t3y ON t3(y);







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    SELECT a FROM t2 WHERE b=2 AND c IS NULL ORDER BY b, a;
  }
} {5 9 sort}
do_test tkt3824-2.3 {
  lsort [execsql_status {
    SELECT a FROM t2 WHERE b=2 AND c IS NULL ORDER BY b;
  }]
} {5 9 nosort}

do_test tkt3824-3.1 {
  db eval {
    CREATE TABLE t3(x,y);
    INSERT INTO t3 SELECT a, b FROM t1;
    INSERT INTO t3 VALUES(234,567);
    CREATE UNIQUE INDEX t3y ON t3(y);
Changes to test/where3.test.
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    CREATE INDEX t301c ON t301(c);
    INSERT INTO t301 VALUES(1,2,3);
    CREATE TABLE t302(x, y);
    ANALYZE;
    explain query plan
    SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
  }
} {0 0 {TABLE t302} 1 1 {TABLE t301 USING PRIMARY KEY}}
do_test where3-3.1 {
  execsql {
    explain query plan
    SELECT * FROM t301, t302 WHERE t302.x=5 AND t301.a=t302.y;
  }
} {0 1 {TABLE t302} 1 0 {TABLE t301 USING PRIMARY KEY}}

# Verify that when there are multiple tables in a join which must be
# full table scans that the query planner attempts put the table with
# the fewest number of output rows as the outer loop.
#
do_test where3-4.0 {
  execsql {
    CREATE TABLE t400(a INTEGER PRIMARY KEY, b, c);
    CREATE TABLE t401(p INTEGER PRIMARY KEY, q, r);
    CREATE TABLE t402(x INTEGER PRIMARY KEY, y, z);
    EXPLAIN QUERY PLAN
    SELECT * FROM t400, t401, t402 WHERE t402.z GLOB 'abc*';
  }
} {0 2 {TABLE t402} 1 0 {TABLE t400} 2 1 {TABLE t401}}
do_test where3-4.1 {
  execsql {
    EXPLAIN QUERY PLAN
    SELECT * FROM t400, t401, t402 WHERE t401.r GLOB 'abc*';
  }
} {0 1 {TABLE t401} 1 0 {TABLE t400} 2 2 {TABLE t402}}
do_test where3-4.2 {
  execsql {
    EXPLAIN QUERY PLAN
    SELECT * FROM t400, t401, t402 WHERE t400.c GLOB 'abc*';
  }
} {0 0 {TABLE t400} 1 1 {TABLE t401} 2 2 {TABLE t402}}

finish_test







|





|













|





|





|


223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    CREATE INDEX t301c ON t301(c);
    INSERT INTO t301 VALUES(1,2,3);
    CREATE TABLE t302(x, y);
    ANALYZE;
    explain query plan
    SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
  }
} {0 0 0 {SCAN TABLE t302 (~1 rows)} 0 1 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test where3-3.1 {
  execsql {
    explain query plan
    SELECT * FROM t301, t302 WHERE t302.x=5 AND t301.a=t302.y;
  }
} {0 0 1 {SCAN TABLE t302 (~1 rows)} 0 1 0 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}

# Verify that when there are multiple tables in a join which must be
# full table scans that the query planner attempts put the table with
# the fewest number of output rows as the outer loop.
#
do_test where3-4.0 {
  execsql {
    CREATE TABLE t400(a INTEGER PRIMARY KEY, b, c);
    CREATE TABLE t401(p INTEGER PRIMARY KEY, q, r);
    CREATE TABLE t402(x INTEGER PRIMARY KEY, y, z);
    EXPLAIN QUERY PLAN
    SELECT * FROM t400, t401, t402 WHERE t402.z GLOB 'abc*';
  }
} {0 0 2 {SCAN TABLE t402 (~500000 rows)} 0 1 0 {SCAN TABLE t400 (~1000000 rows)} 0 2 1 {SCAN TABLE t401 (~1000000 rows)}}
do_test where3-4.1 {
  execsql {
    EXPLAIN QUERY PLAN
    SELECT * FROM t400, t401, t402 WHERE t401.r GLOB 'abc*';
  }
} {0 0 1 {SCAN TABLE t401 (~500000 rows)} 0 1 0 {SCAN TABLE t400 (~1000000 rows)} 0 2 2 {SCAN TABLE t402 (~1000000 rows)}}
do_test where3-4.2 {
  execsql {
    EXPLAIN QUERY PLAN
    SELECT * FROM t400, t401, t402 WHERE t400.c GLOB 'abc*';
  }
} {0 0 0 {SCAN TABLE t400 (~500000 rows)} 0 1 1 {SCAN TABLE t401 (~1000000 rows)} 0 2 2 {SCAN TABLE t402 (~1000000 rows)}}

finish_test
Changes to test/where9.test.
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
     WHERE t1.a=t3.y OR t1.b=t3.y*11 OR (t1.c=27027 AND round(t1.d)==80)
    ORDER BY 1, 2, 3
  }
} {1 80 2 1 80 28 1 80 54 1 80 80 2 80 2 2 80 28 2 80 54 2 80 80 scan 1 sort 1}


ifcapable explain {
  do_test where9-3.1 {
    set r [db eval {
      EXPLAIN QUERY PLAN
      SELECT t2.a FROM t1, t2
       WHERE t1.a=80
         AND ((t1.c=t2.c AND t1.d=t2.d) OR t1.f=t2.f)
    }]
    set a [expr {[lsearch $r {TABLE t2 VIA MULTI-INDEX UNION}]>=0}]
    set b [expr {[lsearch $r {TABLE t2 WITH INDEX t2f}]>=0}]
    set c [expr {([lsearch $r {TABLE t2 WITH INDEX t2c}]>=0)+
                  [lsearch $r {TABLE t2 WITH INDEX t2d}]>=0}]
    concat $a $b $c
  } {1 1 1}

  do_test where9-3.2 {
    set r [db eval {
      EXPLAIN QUERY PLAN
      SELECT coalesce(t2.a,9999)
        FROM t1 LEFT JOIN t2 ON (t1.c+1=t2.c AND t1.d=t2.d) OR (t1.f||'x')=t2.f
       WHERE t1.a=80
    }]
    set a [expr {[lsearch $r {TABLE t2 VIA MULTI-INDEX UNION}]>=0}]
    set b [expr {[lsearch $r {TABLE t2 WITH INDEX t2f}]>=0}]
    set c [expr {([lsearch $r {TABLE t2 WITH INDEX t2c}]>=0)+
                  [lsearch $r {TABLE t2 WITH INDEX t2d}]>=0}]
    concat $a $b $c
  } {1 1 1}

} 

# Make sure that INDEXED BY and multi-index OR clauses play well with
# one another.
#
do_test where9-4.1 {
  count_steps {







|
<
|
|
<
|
|
|
|
<
|
<
<
>
|
<
|
|
|
|
|
|
|
<
|
<
<
>







354
355
356
357
358
359
360
361

362
363

364
365
366
367

368


369
370

371
372
373
374
375
376
377

378


379
380
381
382
383
384
385
386
     WHERE t1.a=t3.y OR t1.b=t3.y*11 OR (t1.c=27027 AND round(t1.d)==80)
    ORDER BY 1, 2, 3
  }
} {1 80 2 1 80 28 1 80 54 1 80 80 2 80 2 2 80 28 2 80 54 2 80 80 scan 1 sort 1}


ifcapable explain {
  do_execsql_test where9-3.1 {

    EXPLAIN QUERY PLAN
    SELECT t2.a FROM t1, t2

    WHERE t1.a=80 AND ((t1.c=t2.c AND t1.d=t2.d) OR t1.f=t2.f)
  } {
    0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 
    0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?) (~2 rows)} 

    0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) (~10 rows)}


  }
  do_execsql_test where9-3.2 {

    EXPLAIN QUERY PLAN
    SELECT coalesce(t2.a,9999)
    FROM t1 LEFT JOIN t2 ON (t1.c+1=t2.c AND t1.d=t2.d) OR (t1.f||'x')=t2.f
    WHERE t1.a=80
  } {
    0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 
    0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?) (~2 rows)} 

    0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) (~10 rows)}


  }
} 

# Make sure that INDEXED BY and multi-index OR clauses play well with
# one another.
#
do_test where9-4.1 {
  count_steps {
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496
497
498
499
500

501
502
503
504
505
506
507
  }
} {1 {cannot use index: t1d}}

ifcapable explain {
  # The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
  # the former is an equality test which is expected to return fewer rows.
  #
  do_test where9-5.1 {
    set r [db eval {
      EXPLAIN QUERY PLAN
      SELECT a FROM t1
       WHERE b>1000
         AND (c=31031 OR d IS NULL)
    }]
    set a [expr {[lsearch $r {TABLE t1 VIA MULTI-INDEX UNION}]>=0}]
    set b [expr {[lsearch $r {TABLE t1 WITH INDEX t1b}]>=0}]
    concat $a $b
  } {1 0}


  # In contrast, b=1000 is preferred over any OR-clause.
  #
  do_test where9-5.2 {
    set r [db eval {
      EXPLAIN QUERY PLAN
      SELECT a FROM t1
       WHERE b=1000
         AND (c=31031 OR d IS NULL)
    }]
    set a [expr {[lsearch $r {TABLE t1 VIA MULTI-INDEX UNION}]>=0}]
    set b [expr {[lsearch $r {TABLE t1 WITH INDEX t1b}]>=0}]
    concat $a $b
  } {0 1}


  # Likewise, inequalities in an AND are preferred over inequalities in
  # an OR.
  #
  do_test where9-5.3 {
    set r [db eval {
      EXPLAIN QUERY PLAN
      SELECT a FROM t1
       WHERE b>1000
         AND (c>=31031 OR d IS NULL)
    }]
    set a [expr {[lsearch $r {TABLE t1 VIA MULTI-INDEX UNION}]>=0}]
    set b [expr {[lsearch $r {TABLE t1 WITH INDEX t1b}]>=0}]
    concat $a $b
  } {0 1}

}

############################################################################
# Make sure OR-clauses work correctly on UPDATE and DELETE statements.

do_test where9-6.2.1 {
  db eval {SELECT count(*) FROM t1 UNION ALL SELECT a FROM t1 WHERE a>=85}







|
<
|
<
<
<
|
|
|
<
<
|
>


|
<
|
<
<
<
|
<
|
<
<
|
>



|
<
|
<
<
<
|
|
<
<
<
>







447
448
449
450
451
452
453
454

455



456
457
458


459
460
461
462
463

464



465

466


467
468
469
470
471
472

473



474
475



476
477
478
479
480
481
482
483
  }
} {1 {cannot use index: t1d}}

ifcapable explain {
  # The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
  # the former is an equality test which is expected to return fewer rows.
  #
  do_execsql_test where9-5.1 {

    EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)



  } {
    0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?) (~10 rows)} 
    0 0 0 {SEARCH TABLE t1 USING INDEX t1d (d=?) (~10 rows)}


  }

  # In contrast, b=1000 is preferred over any OR-clause.
  #
  do_execsql_test where9-5.2 {

    EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL)



  } {

    0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~5 rows)}


  }

  # Likewise, inequalities in an AND are preferred over inequalities in
  # an OR.
  #
  do_execsql_test where9-5.3 {

    EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c>=31031 OR d IS NULL)



  } {
    0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>?) (~125000 rows)}



  }
}

############################################################################
# Make sure OR-clauses work correctly on UPDATE and DELETE statements.

do_test where9-6.2.1 {
  db eval {SELECT count(*) FROM t1 UNION ALL SELECT a FROM t1 WHERE a>=85}