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 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 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 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 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 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 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 394 395 396 397 398 399 400 401 402 403 404 405 406
|
# 2010 September 18
#
# 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.
#
#***********************************************************************
#
# The majority of this file implements tests to verify that the "testable
# statements" in the lang_insert.html document are correct.
#
# Also, it contains tests to verify the statements in (the very short)
# lang_replace.html.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Organization of tests:
#
# e_insert-0.*: Test the syntax diagram.
#
# e_insert-1.*: Test statements of the form "INSERT ... VALUES(...)".
#
# e_insert-2.*: Test statements of the form "INSERT ... SELECT ...".
#
# e_insert-3.*: Test statements of the form "INSERT ... DEFAULT VALUES".
#
# e_insert-4.*: Test statements regarding the conflict clause.
#
# e_insert-5.*: Test that the qualified table name and "DEFAULT VALUES"
# syntaxes do not work in trigger bodies.
#
do_execsql_test e_insert-0.0 {
CREATE TABLE a1(a, b);
CREATE TABLE a2(a, b, c DEFAULT 'xyz');
CREATE TABLE a3(x DEFAULT 1.0, y DEFAULT 'string', z);
CREATE TABLE a4(c UNIQUE, d);
} {}
proc do_insert_tests {args} {
uplevel do_select_tests $args
}
# EVIDENCE-OF: R-41448-54465 -- syntax diagram insert-stmt
#
do_insert_tests e_insert-0 {
1 "INSERT INTO a1 DEFAULT VALUES" {}
2 "INSERT INTO main.a1 DEFAULT VALUES" {}
3 "INSERT OR ROLLBACK INTO main.a1 DEFAULT VALUES" {}
4 "INSERT OR ROLLBACK INTO a1 DEFAULT VALUES" {}
5 "INSERT OR ABORT INTO main.a1 DEFAULT VALUES" {}
6 "INSERT OR ABORT INTO a1 DEFAULT VALUES" {}
7 "INSERT OR REPLACE INTO main.a1 DEFAULT VALUES" {}
8 "INSERT OR REPLACE INTO a1 DEFAULT VALUES" {}
9 "INSERT OR FAIL INTO main.a1 DEFAULT VALUES" {}
10 "INSERT OR FAIL INTO a1 DEFAULT VALUES" {}
11 "INSERT OR FAIL INTO main.a1 DEFAULT VALUES" {}
12 "INSERT OR IGNORE INTO a1 DEFAULT VALUES" {}
13 "REPLACE INTO a1 DEFAULT VALUES" {}
14 "REPLACE INTO main.a1 DEFAULT VALUES" {}
15 "INSERT INTO a1 VALUES(1, 2)" {}
16 "INSERT INTO main.a1 VALUES(1, 2)" {}
17 "INSERT OR ROLLBACK INTO main.a1 VALUES(1, 2)" {}
18 "INSERT OR ROLLBACK INTO a1 VALUES(1, 2)" {}
19 "INSERT OR ABORT INTO main.a1 VALUES(1, 2)" {}
20 "INSERT OR ABORT INTO a1 VALUES(1, 2)" {}
21 "INSERT OR REPLACE INTO main.a1 VALUES(1, 2)" {}
22 "INSERT OR REPLACE INTO a1 VALUES(1, 2)" {}
23 "INSERT OR FAIL INTO main.a1 VALUES(1, 2)" {}
24 "INSERT OR FAIL INTO a1 VALUES(1, 2)" {}
25 "INSERT OR FAIL INTO main.a1 VALUES(1, 2)" {}
26 "INSERT OR IGNORE INTO a1 VALUES(1, 2)" {}
27 "REPLACE INTO a1 VALUES(1, 2)" {}
28 "REPLACE INTO main.a1 VALUES(1, 2)" {}
29 "INSERT INTO a1 (b, a) VALUES(1, 2)" {}
30 "INSERT INTO main.a1 (b, a) VALUES(1, 2)" {}
31 "INSERT OR ROLLBACK INTO main.a1 (b, a) VALUES(1, 2)" {}
32 "INSERT OR ROLLBACK INTO a1 (b, a) VALUES(1, 2)" {}
33 "INSERT OR ABORT INTO main.a1 (b, a) VALUES(1, 2)" {}
34 "INSERT OR ABORT INTO a1 (b, a) VALUES(1, 2)" {}
35 "INSERT OR REPLACE INTO main.a1 (b, a) VALUES(1, 2)" {}
36 "INSERT OR REPLACE INTO a1 (b, a) VALUES(1, 2)" {}
37 "INSERT OR FAIL INTO main.a1 (b, a) VALUES(1, 2)" {}
38 "INSERT OR FAIL INTO a1 (b, a) VALUES(1, 2)" {}
39 "INSERT OR FAIL INTO main.a1 (b, a) VALUES(1, 2)" {}
40 "INSERT OR IGNORE INTO a1 (b, a) VALUES(1, 2)" {}
41 "REPLACE INTO a1 (b, a) VALUES(1, 2)" {}
42 "REPLACE INTO main.a1 (b, a) VALUES(1, 2)" {}
43 "INSERT INTO a1 SELECT c, b FROM a2" {}
44 "INSERT INTO main.a1 SELECT c, b FROM a2" {}
45 "INSERT OR ROLLBACK INTO main.a1 SELECT c, b FROM a2" {}
46 "INSERT OR ROLLBACK INTO a1 SELECT c, b FROM a2" {}
47 "INSERT OR ABORT INTO main.a1 SELECT c, b FROM a2" {}
48 "INSERT OR ABORT INTO a1 SELECT c, b FROM a2" {}
49 "INSERT OR REPLACE INTO main.a1 SELECT c, b FROM a2" {}
50 "INSERT OR REPLACE INTO a1 SELECT c, b FROM a2" {}
51 "INSERT OR FAIL INTO main.a1 SELECT c, b FROM a2" {}
52 "INSERT OR FAIL INTO a1 SELECT c, b FROM a2" {}
53 "INSERT OR FAIL INTO main.a1 SELECT c, b FROM a2" {}
54 "INSERT OR IGNORE INTO a1 SELECT c, b FROM a2" {}
55 "REPLACE INTO a1 SELECT c, b FROM a2" {}
56 "REPLACE INTO main.a1 SELECT c, b FROM a2" {}
57 "INSERT INTO a1 (b, a) SELECT c, b FROM a2" {}
58 "INSERT INTO main.a1 (b, a) SELECT c, b FROM a2" {}
59 "INSERT OR ROLLBACK INTO main.a1 (b, a) SELECT c, b FROM a2" {}
60 "INSERT OR ROLLBACK INTO a1 (b, a) SELECT c, b FROM a2" {}
61 "INSERT OR ABORT INTO main.a1 (b, a) SELECT c, b FROM a2" {}
62 "INSERT OR ABORT INTO a1 (b, a) SELECT c, b FROM a2" {}
63 "INSERT OR REPLACE INTO main.a1 (b, a) SELECT c, b FROM a2" {}
64 "INSERT OR REPLACE INTO a1 (b, a) SELECT c, b FROM a2" {}
65 "INSERT OR FAIL INTO main.a1 (b, a) SELECT c, b FROM a2" {}
66 "INSERT OR FAIL INTO a1 (b, a) SELECT c, b FROM a2" {}
67 "INSERT OR FAIL INTO main.a1 (b, a) SELECT c, b FROM a2" {}
68 "INSERT OR IGNORE INTO a1 (b, a) SELECT c, b FROM a2" {}
69 "REPLACE INTO a1 (b, a) SELECT c, b FROM a2" {}
70 "REPLACE INTO main.a1 (b, a) SELECT c, b FROM a2" {}
}
delete_all_data
# EVIDENCE-OF: R-20288-20462 The first form (with the "VALUES" keyword)
# creates a single new row in an existing table.
#
do_insert_tests e_insert-1.1 {
0 "SELECT count(*) FROM a2" {0}
1a "INSERT INTO a2 VALUES(1, 2, 3)" {}
1b "SELECT count(*) FROM a2" {1}
2a "INSERT INTO a2(a, b) VALUES(1, 2)" {}
2b "SELECT count(*) FROM a2" {2}
}
# EVIDENCE-OF: R-36040-20870 If no column-list is specified then the
# number of values must be the same as the number of columns in the
# table.
#
# A test in the block above verifies that if the VALUES list has the
# correct number of columns (for table a2, 3 columns) works. So these
# tests just show that other values cause an error.
#
do_insert_tests e_insert-1.2 -error {
table %s has %d columns but %d values were supplied
} {
1 "INSERT INTO a2 VALUES(1)" {a2 3 1}
2 "INSERT INTO a2 VALUES(1,2)" {a2 3 2}
3 "INSERT INTO a2 VALUES(1,2,3,4)" {a2 3 4}
4 "INSERT INTO a2 VALUES(1,2,3,4,5)" {a2 3 5}
}
# EVIDENCE-OF: R-52422-65517 In this case the result of evaluting the
# left-most expression in the VALUES list is inserted into the left-most
# column of the new row, and so on.
#
delete_all_data
do_insert_tests e_insert-1.3 {
1a "INSERT INTO a2 VALUES(1, 2, 3)" {}
1b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {1 2 3}
2a "INSERT INTO a2 VALUES('abc', NULL, 3*3+1)" {}
2b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {abc {} 10}
3a "INSERT INTO a2 VALUES((SELECT count(*) FROM a2), 'x', 'y')" {}
3b "SELECT * FROM a2 WHERE oid=last_insert_rowid()" {2 x y}
}
# EVIDENCE-OF: R-62524-00361 If a column-list is specified, then the
# number of values must match the number of specified columns.
#
do_insert_tests e_insert-1.4 -error {
%d values for %d columns
} {
1 "INSERT INTO a2(a, b, c) VALUES(1)" {1 3}
2 "INSERT INTO a2(a, b, c) VALUES(1,2)" {2 3}
3 "INSERT INTO a2(a, b, c) VALUES(1,2,3,4)" {4 3}
4 "INSERT INTO a2(a, b, c) VALUES(1,2,3,4,5)" {5 3}
5 "INSERT INTO a2(c, a) VALUES(1)" {1 2}
6 "INSERT INTO a2(c, a) VALUES(1,2,3)" {3 2}
7 "INSERT INTO a2(c, a) VALUES(1,2,3,4)" {4 2}
8 "INSERT INTO a2(c, a) VALUES(1,2,3,4,5)" {5 2}
}
# EVIDENCE-OF: R-07016-26442 Each of the named columns of the new row is
# populated with the results of evaluating the corresponding VALUES
# expression.
#
# EVIDENCE-OF: R-12183-43719 Table columns that do not appear in the
# column list are populated with the default column value (specified as
# part of the CREATE TABLE statement), or with NULL if no default value
# is specified.
#
delete_all_data
do_insert_tests e_insert-1.5 {
1a "INSERT INTO a2(b, c) VALUES('b', 'c')" {}
1b "SELECT * FROM a2" {{} b c}
2a "INSERT INTO a2(a, b) VALUES('a', 'b')" {}
2b "SELECT * FROM a2" {{} b c a b xyz}
}
# EVIDENCE-OF: R-52173-30215 A new entry is inserted into the table for
# each row of data returned by executing the SELECT statement.
#
delete_all_data
do_insert_tests e_insert-2.1 {
0 "SELECT count(*) FROM a1" {0}
1a "SELECT count(*) FROM (SELECT 1, 2)" {1}
1b "INSERT INTO a1 SELECT 1, 2" {}
1c "SELECT count(*) FROM a1" {1}
2a "SELECT count(*) FROM (SELECT b, a FROM a1)" {1}
2b "INSERT INTO a1 SELECT b, a FROM a1" {}
2c "SELECT count(*) FROM a1" {2}
3a "SELECT count(*) FROM (SELECT b, a FROM a1)" {2}
3b "INSERT INTO a1 SELECT b, a FROM a1" {}
3c "SELECT count(*) FROM a1" {4}
4a "SELECT count(*) FROM (SELECT b, a FROM a1)" {4}
4b "INSERT INTO a1 SELECT b, a FROM a1" {}
4c "SELECT count(*) FROM a1" {8}
4a "SELECT count(*) FROM (SELECT min(b), min(a) FROM a1)" {1}
4b "INSERT INTO a1 SELECT min(b), min(a) FROM a1" {}
4c "SELECT count(*) FROM a1" {9}
}
# EVIDENCE-OF: R-63614-47421 If a column-list is specified, the number
# of columns in the result of the SELECT must be the same as the number
# of items in the column-list.
#
do_insert_tests e_insert-2.2 -error {
%d values for %d columns
} {
1 "INSERT INTO a3(x, y) SELECT a, b, c FROM a2" {3 2}
2 "INSERT INTO a3(x, y) SELECT * FROM a2" {3 2}
3 "INSERT INTO a3(x, y) SELECT * FROM a2 CROSS JOIN a1" {5 2}
4 "INSERT INTO a3(x, y) SELECT * FROM a2 NATURAL JOIN a1" {3 2}
5 "INSERT INTO a3(x, y) SELECT a2.a FROM a2,a1" {1 2}
6 "INSERT INTO a3(z) SELECT a, b, c FROM a2" {3 1}
7 "INSERT INTO a3(z) SELECT * FROM a2" {3 1}
8 "INSERT INTO a3(z) SELECT * FROM a2 CROSS JOIN a1" {5 1}
9 "INSERT INTO a3(z) SELECT * FROM a2 NATURAL JOIN a1" {3 1}
10 "INSERT INTO a3(z) SELECT a1.* FROM a2,a1" {2 1}
}
# EVIDENCE-OF: R-58951-07798 Otherwise, if no column-list is specified,
# the number of columns in the result of the SELECT must be the same as
# the number of columns in the table.
#
do_insert_tests e_insert-2.3 -error {
table %s has %d columns but %d values were supplied
} {
1 "INSERT INTO a1 SELECT a, b, c FROM a2" {a1 2 3}
2 "INSERT INTO a1 SELECT * FROM a2" {a1 2 3}
3 "INSERT INTO a1 SELECT * FROM a2 CROSS JOIN a1" {a1 2 5}
4 "INSERT INTO a1 SELECT * FROM a2 NATURAL JOIN a1" {a1 2 3}
5 "INSERT INTO a1 SELECT a2.a FROM a2,a1" {a1 2 1}
}
# EVIDENCE-OF: R-31074-37730 Any SELECT statement, including compound
# SELECTs and SELECT statements with ORDER BY and/or LIMIT clauses, may
# be used in an INSERT statement of this form.
#
delete_all_data
do_execsql_test e_insert-2.3.0 {
INSERT INTO a1 VALUES('x', 'y');
} {}
do_insert_tests e_insert-2.3 {
1 "INSERT INTO a1 SELECT a,b FROM a1 UNION SELECT b,a FROM a1 ORDER BY 1" {}
2 "INSERT INTO a1(b, a) SELECT * FROM a1 LIMIT 1" {}
3 "INSERT INTO a1 SELECT 'a'||a, 'b'||b FROM a1 LIMIT 2 OFFSET 1" {}
4 "INSERT INTO a1 SELECT * FROM a1 ORDER BY b, a" {}
S "SELECT * FROM a1" {
x y
x y y x
y x
ax by ay bx
ay bx ax by y x y x x y x y
}
}
# EVIDENCE-OF: R-25149-22012 The INSERT ... DEFAULT VALUES statement
# inserts a single new row into the named table.
#
delete_all_data
do_insert_tests e_insert-3.1 {
1 "SELECT count(*) FROM a3" {0}
2a "INSERT INTO a3 DEFAULT VALUES" {}
2b "SELECT count(*) FROM a3" {1}
}
# EVIDENCE-OF: R-18927-01951 Each column of the new row is populated
# with its default value, or with a NULL if no default value is
# specified as part of the column definition in the CREATE TABLE
# statement.
#
delete_all_data
do_insert_tests e_insert-3.2 {
1.1 "INSERT INTO a3 DEFAULT VALUES" {}
1.2 "SELECT * FROM a3" {1.0 string {}}
2.1 "INSERT INTO a3 DEFAULT VALUES" {}
2.2 "SELECT * FROM a3" {1.0 string {} 1.0 string {}}
3.1 "INSERT INTO a2 DEFAULT VALUES" {}
3.2 "SELECT * FROM a2" {{} {} xyz}
4.1 "INSERT INTO a2 DEFAULT VALUES" {}
4.2 "SELECT * FROM a2" {{} {} xyz {} {} xyz}
5.1 "INSERT INTO a1 DEFAULT VALUES" {}
5.2 "SELECT * FROM a1" {{} {}}
6.1 "INSERT INTO a1 DEFAULT VALUES" {}
6.2 "SELECT * FROM a1" {{} {} {} {}}
}
# EVIDENCE-OF: R-46928-50290 The optional conflict-clause allows the
# specification of an alternative constraint conflict resolution
# algorithm to use during this one INSERT command.
#
# EVIDENCE-OF: R-23110-47146 the parser allows the use of the single
# keyword REPLACE as an alias for "INSERT OR REPLACE".
#
# The two requirements above are tested by e_select-4.1.* and
# e_select-4.2.*, respectively.
#
# EVIDENCE-OF: R-03421-22330 The REPLACE command is an alias for the
# "INSERT OR REPLACE" variant of the INSERT command.
#
# This is a dup of R-23110-47146. Therefore it is also verified
# by e_select-4.2.*. This requirement is the only one from
# lang_replace.html.
#
do_execsql_test e_insert-4.1.0 {
INSERT INTO a4 VALUES(1, 'a');
INSERT INTO a4 VALUES(2, 'a');
INSERT INTO a4 VALUES(3, 'a');
} {}
foreach {tn sql error ac data } {
1.1 "INSERT INTO a4 VALUES(2,'b')" {column c is not unique} 1 {1 a 2 a 3 a}
1.2 "INSERT OR REPLACE INTO a4 VALUES(2, 'b')" {} 1 {1 a 3 a 2 b}
1.3 "INSERT OR IGNORE INTO a4 VALUES(3, 'c')" {} 1 {1 a 3 a 2 b}
1.4 "BEGIN" {} 0 {1 a 3 a 2 b}
1.5 "INSERT INTO a4 VALUES(1, 'd')" {column c is not unique} 0 {1 a 3 a 2 b}
1.6 "INSERT OR ABORT INTO a4 VALUES(1, 'd')"
{column c is not unique} 0 {1 a 3 a 2 b}
1.7 "INSERT OR ROLLBACK INTO a4 VALUES(1, 'd')"
{column c is not unique} 1 {1 a 3 a 2 b}
1.8 "INSERT INTO a4 SELECT 4, 'e' UNION ALL SELECT 3, 'e'"
{column c is not unique} 1 {1 a 3 a 2 b}
1.9 "INSERT OR FAIL INTO a4 SELECT 4, 'e' UNION ALL SELECT 3, 'e'"
{column c is not unique} 1 {1 a 3 a 2 b 4 e}
2.1 "INSERT INTO a4 VALUES(2,'f')"
{column c is not unique} 1 {1 a 3 a 2 b 4 e}
2.2 "REPLACE INTO a4 VALUES(2, 'f')" {} 1 {1 a 3 a 4 e 2 f}
} {
do_catchsql_test e_insert-4.1.$tn.1 $sql [list [expr {$error!=""}] $error]
do_execsql_test e_insert-4.1.$tn.2 {SELECT * FROM a4} [list {*}$data]
do_test e_insert-4.1.$tn.3 {sqlite3_get_autocommit db} $ac
}
# EVIDENCE-OF: R-64196-02418 The optional "database-name." prefix on the
# table-name is support for top-level INSERT statements only.
#
# EVIDENCE-OF: R-05731-00924 The table name must be unqualified for
# INSERT statements that occur within CREATE TRIGGER statements.
#
set err {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}}
do_catchsql_test e_insert-5.1.1 {
CREATE TRIGGER AFTER UPDATE ON a1 BEGIN
INSERT INTO main.a4 VALUES(new.a, new.b);
END;
} $err
do_catchsql_test e_insert-5.1.2 {
CREATE TEMP TABLE IF NOT EXISTS tmptable(a, b);
CREATE TRIGGER AFTER DELETE ON a3 BEGIN
INSERT INTO temp.tmptable VALUES(1, 2);
END;
} $err
# EVIDENCE-OF: R-15888-36326 Similarly, the "DEFAULT VALUES" form of the
# INSERT statement is supported for top-level INSERT statements only and
# not for INSERT statements within triggers.
#
do_catchsql_test e_insert-5.2.1 {
CREATE TRIGGER AFTER UPDATE ON a1 BEGIN
INSERT INTO a4 DEFAULT VALUES;
END;
} {1 {near "DEFAULT": syntax error}}
delete_all_data
finish_test
|