File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / insert4.test
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:16 2012 UTC (12 years, 10 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    1: # 2007 January 24
    2: #
    3: # The author disclaims copyright to this source code.  In place of
    4: # a legal notice, here is a blessing:
    5: #
    6: #    May you do good and not evil.
    7: #    May you find forgiveness for yourself and forgive others.
    8: #    May you share freely, never taking more than you give.
    9: #
   10: #***********************************************************************
   11: # This file implements regression tests for SQLite library.  The
   12: # focus of this file is testing the INSERT transfer optimization.
   13: #
   14: # $Id: insert4.test,v 1.1.1.1 2012/02/21 17:04:16 misho Exp $
   15: 
   16: set testdir [file dirname $argv0]
   17: source $testdir/tester.tcl
   18: 
   19: ifcapable !view||!subquery {
   20:   finish_test
   21:   return
   22: }
   23: 
   24: # The sqlite3_xferopt_count variable is incremented whenever the 
   25: # insert transfer optimization applies.
   26: #
   27: # This procedure runs a test to see if the sqlite3_xferopt_count is
   28: # set to N.
   29: #
   30: proc xferopt_test {testname N} {
   31:   do_test $testname {set ::sqlite3_xferopt_count} $N
   32: }
   33: 
   34: # Create tables used for testing.
   35: #
   36: execsql {
   37:   PRAGMA legacy_file_format = 0;
   38:   CREATE TABLE t1(a int, b int, check(b>a));
   39:   CREATE TABLE t2(x int, y int);
   40:   CREATE VIEW v2 AS SELECT y, x FROM t2;
   41:   CREATE TABLE t3(a int, b int);
   42: }
   43: 
   44: # Ticket #2252.  Make sure the an INSERT from identical tables
   45: # does not violate constraints.
   46: #
   47: do_test insert4-1.1 {
   48:   set sqlite3_xferopt_count 0
   49:   execsql {
   50:     DELETE FROM t1;
   51:     DELETE FROM t2;
   52:     INSERT INTO t2 VALUES(9,1);
   53:   }
   54:   catchsql {
   55:     INSERT INTO t1 SELECT * FROM t2;
   56:   }
   57: } {1 {constraint failed}}
   58: xferopt_test insert4-1.2 0
   59: do_test insert4-1.3 {
   60:   execsql {
   61:     SELECT * FROM t1;
   62:   }
   63: } {}
   64: 
   65: # Tests to make sure that the transfer optimization is not occurring
   66: # when it is not a valid optimization.
   67: #
   68: # The SELECT must be against a real table.
   69: do_test insert4-2.1.1 {
   70:   execsql {
   71:     DELETE FROM t1;
   72:     INSERT INTO t1 SELECT 4, 8;
   73:     SELECT * FROM t1;
   74:   }
   75: } {4 8}
   76: xferopt_test insert4-2.1.2  0
   77: do_test insert4-2.2.1 {
   78:   catchsql {
   79:     DELETE FROM t1;
   80:     INSERT INTO t1 SELECT * FROM v2;
   81:     SELECT * FROM t1;
   82:   }
   83: } {0 {1 9}}
   84: xferopt_test insert4-2.2.2 0
   85: 
   86: # Do not run the transfer optimization if there is a LIMIT clause
   87: #
   88: do_test insert4-2.3.1 {
   89:   execsql {
   90:     DELETE FROM t2;
   91:     INSERT INTO t2 VALUES(9,1);
   92:     INSERT INTO t2 SELECT y, x FROM t2;
   93:     INSERT INTO t3 SELECT * FROM t2 LIMIT 1;
   94:     SELECT * FROM t3;
   95:   }
   96: } {9 1}
   97: xferopt_test insert4-2.3.2  0
   98: do_test insert4-2.3.3 {
   99:   catchsql {
  100:     DELETE FROM t1;
  101:     INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
  102:     SELECT * FROM t1;
  103:   }
  104: } {1 {constraint failed}}
  105: xferopt_test insert4-2.3.4 0
  106: 
  107: # Do not run the transfer optimization if there is a DISTINCT
  108: #
  109: do_test insert4-2.4.1 {
  110:   execsql {
  111:     DELETE FROM t3;
  112:     INSERT INTO t3 SELECT DISTINCT * FROM t2;
  113:     SELECT * FROM t3;
  114:   }
  115: } {9 1 1 9}
  116: xferopt_test insert4-2.4.2 0
  117: do_test insert4-2.4.3 {
  118:   catchsql {
  119:     DELETE FROM t1;
  120:     INSERT INTO t1 SELECT DISTINCT * FROM t2;
  121:   }
  122: } {1 {constraint failed}}
  123: xferopt_test insert4-2.4.4 0
  124: 
  125: # The following procedure constructs two tables then tries to transfer
  126: # data from one table to the other.  Checks are made to make sure the
  127: # transfer is successful and that the transfer optimization was used or
  128: # not, as appropriate.
  129: #
  130: #     xfer_check TESTID  XFER-USED   INIT-DATA   DEST-SCHEMA   SRC-SCHEMA 
  131: #
  132: # The TESTID argument is the symbolic name for this test.  The XFER-USED
  133: # argument is true if the transfer optimization should be employed and
  134: # false if not.  INIT-DATA is a single row of data that is to be 
  135: # transfered.  DEST-SCHEMA and SRC-SCHEMA are table declarations for
  136: # the destination and source tables.
  137: #
  138: proc xfer_check {testid xferused initdata destschema srcschema} {
  139:   execsql "CREATE TABLE dest($destschema)"
  140:   execsql "CREATE TABLE src($srcschema)"
  141:   execsql "INSERT INTO src VALUES([join $initdata ,])"
  142:   set ::sqlite3_xferopt_count 0
  143:   do_test $testid.1 {
  144:     execsql {
  145:       INSERT INTO dest SELECT * FROM src;
  146:       SELECT * FROM dest;
  147:     }
  148:   } $initdata
  149:   do_test $testid.2 {
  150:     set ::sqlite3_xferopt_count
  151:   } $xferused
  152:   execsql {
  153:     DROP TABLE dest;
  154:     DROP TABLE src;
  155:   }
  156: }
  157: 
  158: 
  159: # Do run the transfer optimization if tables have identical
  160: # CHECK constraints.
  161: #
  162: xfer_check insert4-3.1 1 {1 9} \
  163:     {a int, b int CHECK(b>a)} \
  164:     {x int, y int CHECK(y>x)}
  165: xfer_check insert4-3.2 1 {1 9} \
  166:     {a int, b int CHECK(b>a)} \
  167:     {x int CHECK(y>x), y int}
  168: 
  169: # Do run the transfer optimization if the destination table lacks
  170: # any CHECK constraints regardless of whether or not there are CHECK
  171: # constraints on the source table.
  172: #
  173: xfer_check insert4-3.3 1 {1 9} \
  174:     {a int, b int} \
  175:     {x int, y int CHECK(y>x)}
  176: 
  177: # Do run the transfer optimization if the destination table omits
  178: # NOT NULL constraints that the source table has.
  179: #
  180: xfer_check insert4-3.4 0 {1 9} \
  181:     {a int, b int CHECK(b>a)} \
  182:     {x int, y int}
  183: 
  184: # Do not run the optimization if the destination has NOT NULL
  185: # constraints that the source table lacks.
  186: #
  187: xfer_check insert4-3.5 0 {1 9} \
  188:     {a int, b int NOT NULL} \
  189:     {x int, y int}
  190: xfer_check insert4-3.6 0 {1 9} \
  191:     {a int, b int NOT NULL} \
  192:     {x int NOT NULL, y int}
  193: xfer_check insert4-3.7 0 {1 9} \
  194:     {a int NOT NULL, b int NOT NULL} \
  195:     {x int NOT NULL, y int}
  196: xfer_check insert4-3.8 0 {1 9} \
  197:     {a int NOT NULL, b int} \
  198:     {x int, y int}
  199: 
  200: 
  201: # Do run the transfer optimization if the destination table and
  202: # source table have the same NOT NULL constraints or if the 
  203: # source table has extra NOT NULL constraints.
  204: #
  205: xfer_check insert4-3.9 1 {1 9} \
  206:     {a int, b int} \
  207:     {x int NOT NULL, y int}
  208: xfer_check insert4-3.10 1 {1 9} \
  209:     {a int, b int} \
  210:     {x int NOT NULL, y int NOT NULL}
  211: xfer_check insert4-3.11 1 {1 9} \
  212:     {a int NOT NULL, b int} \
  213:     {x int NOT NULL, y int NOT NULL}
  214: xfer_check insert4-3.12 1 {1 9} \
  215:     {a int, b int NOT NULL} \
  216:     {x int NOT NULL, y int NOT NULL}
  217: 
  218: # Do not run the optimization if any corresponding table
  219: # columns have different affinities.
  220: #
  221: xfer_check insert4-3.20 0 {1 9} \
  222:     {a text, b int} \
  223:     {x int, b int}
  224: xfer_check insert4-3.21 0 {1 9} \
  225:     {a int, b int} \
  226:     {x text, b int}
  227: 
  228: # "int" and "integer" are equivalent so the optimization should
  229: # run here.
  230: #
  231: xfer_check insert4-3.22 1 {1 9} \
  232:     {a int, b int} \
  233:     {x integer, b int}
  234: 
  235: # Ticket #2291.
  236: #
  237: 
  238: do_test insert4-4.1a {
  239:   execsql {CREATE TABLE t4(a, b, UNIQUE(a,b))}
  240: } {}
  241: ifcapable vacuum {
  242:   do_test insert4-4.1b {
  243:     execsql {
  244:       INSERT INTO t4 VALUES(NULL,0);
  245:       INSERT INTO t4 VALUES(NULL,1);
  246:       INSERT INTO t4 VALUES(NULL,1);
  247:       VACUUM;   
  248:     }
  249:   } {}
  250: }
  251: 
  252: # Check some error conditions:
  253: #
  254: do_test insert4-5.1 {
  255:   # Table does not exist.
  256:   catchsql { INSERT INTO t2 SELECT * FROM nosuchtable }
  257: } {1 {no such table: nosuchtable}}
  258: do_test insert4-5.2 {
  259:   # Number of columns does not match.
  260:   catchsql { 
  261:     CREATE TABLE t5(a, b, c);
  262:     INSERT INTO t4 SELECT * FROM t5;
  263:   }
  264: } {1 {table t4 has 2 columns but 3 values were supplied}}
  265: 
  266: do_test insert4-6.1 {
  267:   set ::sqlite3_xferopt_count 0
  268:   execsql {
  269:     CREATE INDEX t2_i2 ON t2(x, y COLLATE nocase); 
  270:     CREATE INDEX t2_i1 ON t2(x ASC, y DESC);
  271:     CREATE INDEX t3_i1 ON t3(a, b);
  272:     INSERT INTO t2 SELECT * FROM t3;
  273:   }
  274:   set ::sqlite3_xferopt_count
  275: } {0}
  276: do_test insert4-6.2 {
  277:   set ::sqlite3_xferopt_count 0
  278:   execsql {
  279:     DROP INDEX t2_i2;
  280:     INSERT INTO t2 SELECT * FROM t3;
  281:   }
  282:   set ::sqlite3_xferopt_count
  283: } {0}
  284: do_test insert4-6.3 {
  285:   set ::sqlite3_xferopt_count 0
  286:   execsql {
  287:     DROP INDEX t2_i1;
  288:     CREATE INDEX t2_i1 ON t2(x ASC, y ASC);
  289:     INSERT INTO t2 SELECT * FROM t3;
  290:   }
  291:   set ::sqlite3_xferopt_count
  292: } {1}
  293: do_test insert4-6.4 {
  294:   set ::sqlite3_xferopt_count 0
  295:   execsql {
  296:     DROP INDEX t2_i1;
  297:     CREATE INDEX t2_i1 ON t2(x ASC, y COLLATE RTRIM);
  298:     INSERT INTO t2 SELECT * FROM t3;
  299:   }
  300:   set ::sqlite3_xferopt_count
  301: } {0}
  302: 
  303: 
  304: do_test insert4-6.5 {
  305:   execsql {
  306:     CREATE TABLE t6a(x CHECK( x<>'abc' ));
  307:     INSERT INTO t6a VALUES('ABC');
  308:     SELECT * FROM t6a;
  309:   }
  310: } {ABC}
  311: do_test insert4-6.6 {
  312:   execsql {
  313:     CREATE TABLE t6b(x CHECK( x<>'abc' COLLATE nocase ));
  314:   }
  315:   catchsql {
  316:     INSERT INTO t6b SELECT * FROM t6a;
  317:   }
  318: } {1 {constraint failed}}
  319: do_test insert4-6.7 {
  320:   execsql {
  321:     DROP TABLE t6b;
  322:     CREATE TABLE t6b(x CHECK( x COLLATE nocase <>'abc' ));
  323:   }
  324:   catchsql {
  325:     INSERT INTO t6b SELECT * FROM t6a;
  326:   }
  327: } {1 {constraint failed}}
  328: 
  329: # Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
  330: # Disable the xfer optimization if the destination table contains
  331: # a foreign key constraint
  332: #
  333: ifcapable foreignkey {
  334:   do_test insert4-7.1 {
  335:     set ::sqlite3_xferopt_count 0
  336:     execsql {
  337:       CREATE TABLE t7a(x INTEGER PRIMARY KEY); INSERT INTO t7a VALUES(123);
  338:       CREATE TABLE t7b(y INTEGER REFERENCES t7a);
  339:       CREATE TABLE t7c(z INT);  INSERT INTO t7c VALUES(234);
  340:       INSERT INTO t7b SELECT * FROM t7c;
  341:       SELECT * FROM t7b;
  342:     }
  343:   } {234}
  344:   do_test insert4-7.2 {
  345:     set ::sqlite3_xferopt_count
  346:   } {1}
  347:   do_test insert4-7.3 {
  348:     set ::sqlite3_xferopt_count 0
  349:     execsql {
  350:       DELETE FROM t7b;
  351:       PRAGMA foreign_keys=ON;
  352:     }
  353:     catchsql {
  354:       INSERT INTO t7b SELECT * FROM t7c;
  355:     }
  356:   } {1 {foreign key constraint failed}}
  357:   do_test insert4-7.4 {
  358:     execsql {SELECT * FROM t7b}
  359:   } {}
  360:   do_test insert4-7.5 {
  361:     set ::sqlite3_xferopt_count
  362:   } {0}
  363:   do_test insert4-7.6 {
  364:     set ::sqlite3_xferopt_count 0
  365:     execsql {
  366:       DELETE FROM t7b; DELETE FROM t7c;
  367:       INSERT INTO t7c VALUES(123);
  368:       INSERT INTO t7b SELECT * FROM t7c;
  369:       SELECT * FROM t7b;
  370:     }
  371:   } {123}
  372:   do_test insert4-7.7 {
  373:     set ::sqlite3_xferopt_count
  374:   } {0}
  375:   do_test insert4-7.7 {
  376:     set ::sqlite3_xferopt_count 0
  377:     execsql {
  378:       PRAGMA foreign_keys=OFF;
  379:       DELETE FROM t7b;
  380:       INSERT INTO t7b SELECT * FROM t7c;
  381:       SELECT * FROM t7b;
  382:     }
  383:   } {123}
  384:   do_test insert4-7.8 {
  385:     set ::sqlite3_xferopt_count
  386:   } {1}
  387: }
  388: 
  389: # Ticket [676bc02b87176125635cb174d110b431581912bb]
  390: # Make sure INTEGER PRIMARY KEY ON CONFLICT ... works with the xfer
  391: # optimization.
  392: #
  393: do_test insert4-8.1 {
  394:   execsql {
  395:     DROP TABLE IF EXISTS t1;
  396:     DROP TABLE IF EXISTS t2;
  397:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
  398:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y);
  399:     INSERT INTO t1 VALUES(1,2);
  400:     INSERT INTO t2 VALUES(1,3);
  401:     INSERT INTO t1 SELECT * FROM t2;
  402:     SELECT * FROM t1;
  403:   }
  404: } {1 3}
  405: do_test insert4-8.2 {
  406:   execsql {
  407:     DROP TABLE IF EXISTS t1;
  408:     DROP TABLE IF EXISTS t2;
  409:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
  410:     CREATE TABLE t2(x, y);
  411:     INSERT INTO t1 VALUES(1,2);
  412:     INSERT INTO t2 VALUES(1,3);
  413:     INSERT INTO t1 SELECT * FROM t2;
  414:     SELECT * FROM t1;
  415:   }
  416: } {1 3}
  417: do_test insert4-8.3 {
  418:   execsql {
  419:     DROP TABLE IF EXISTS t1;
  420:     DROP TABLE IF EXISTS t2;
  421:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
  422:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y);
  423:     INSERT INTO t1 VALUES(1,2);
  424:     INSERT INTO t2 VALUES(1,3);
  425:     INSERT INTO t1 SELECT * FROM t2;
  426:     SELECT * FROM t1;
  427:   }
  428: } {1 2}
  429: do_test insert4-8.4 {
  430:   execsql {
  431:     DROP TABLE IF EXISTS t1;
  432:     DROP TABLE IF EXISTS t2;
  433:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
  434:     CREATE TABLE t2(x, y);
  435:     INSERT INTO t1 VALUES(1,2);
  436:     INSERT INTO t2 VALUES(1,3);
  437:     INSERT INTO t1 SELECT * FROM t2;
  438:     SELECT * FROM t1;
  439:   }
  440: } {1 2}
  441: do_test insert4-8.5 {
  442:   execsql {
  443:     DROP TABLE IF EXISTS t1;
  444:     DROP TABLE IF EXISTS t2;
  445:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b);
  446:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y);
  447:     INSERT INTO t1 VALUES(1,2);
  448:     INSERT INTO t2 VALUES(-99,100);
  449:     INSERT INTO t2 VALUES(1,3);
  450:     SELECT * FROM t1;
  451:   }
  452:   catchsql {
  453:     INSERT INTO t1 SELECT * FROM t2;
  454:   }
  455: } {1 {PRIMARY KEY must be unique}}
  456: do_test insert4-8.6 {
  457:   execsql {
  458:     SELECT * FROM t1;
  459:   }
  460: } {-99 100 1 2} 
  461: do_test insert4-8.7 {
  462:   execsql {
  463:     DROP TABLE IF EXISTS t1;
  464:     DROP TABLE IF EXISTS t2;
  465:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b);
  466:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y);
  467:     INSERT INTO t1 VALUES(1,2);
  468:     INSERT INTO t2 VALUES(-99,100);
  469:     INSERT INTO t2 VALUES(1,3);
  470:     SELECT * FROM t1;
  471:   }
  472:   catchsql {
  473:     INSERT INTO t1 SELECT * FROM t2;
  474:   }
  475: } {1 {PRIMARY KEY must be unique}}
  476: do_test insert4-8.8 {
  477:   execsql {
  478:     SELECT * FROM t1;
  479:   }
  480: } {1 2} 
  481: do_test insert4-8.9 {
  482:   execsql {
  483:     DROP TABLE IF EXISTS t1;
  484:     DROP TABLE IF EXISTS t2;
  485:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b);
  486:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y);
  487:     INSERT INTO t1 VALUES(1,2);
  488:     INSERT INTO t2 VALUES(-99,100);
  489:     INSERT INTO t2 VALUES(1,3);
  490:     SELECT * FROM t1;
  491:   }
  492:   catchsql {
  493:     BEGIN;
  494:     INSERT INTO t1 VALUES(2,3);
  495:     INSERT INTO t1 SELECT * FROM t2;
  496:   }
  497: } {1 {PRIMARY KEY must be unique}}
  498: do_test insert4-8.10 {
  499:   catchsql {COMMIT}
  500: } {1 {cannot commit - no transaction is active}}
  501: do_test insert4-8.11 {
  502:   execsql {
  503:     SELECT * FROM t1;
  504:   }
  505: } {1 2} 
  506: 
  507: do_test insert4-8.21 {
  508:   execsql {
  509:     DROP TABLE IF EXISTS t1;
  510:     DROP TABLE IF EXISTS t2;
  511:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b);
  512:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT REPLACE, y);
  513:     INSERT INTO t2 VALUES(1,3);
  514:     INSERT INTO t1 SELECT * FROM t2;
  515:     SELECT * FROM t1;
  516:   }
  517: } {1 3}
  518: do_test insert4-8.22 {
  519:   execsql {
  520:     DROP TABLE IF EXISTS t1;
  521:     DROP TABLE IF EXISTS t2;
  522:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT IGNORE, b);
  523:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT IGNORE, y);
  524:     INSERT INTO t2 VALUES(1,3);
  525:     INSERT INTO t1 SELECT * FROM t2;
  526:     SELECT * FROM t1;
  527:   }
  528: } {1 3}
  529: do_test insert4-8.23 {
  530:   execsql {
  531:     DROP TABLE IF EXISTS t1;
  532:     DROP TABLE IF EXISTS t2;
  533:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ABORT, b);
  534:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ABORT, y);
  535:     INSERT INTO t2 VALUES(1,3);
  536:     INSERT INTO t1 SELECT * FROM t2;
  537:     SELECT * FROM t1;
  538:   }
  539: } {1 3}
  540: do_test insert4-8.24 {
  541:   execsql {
  542:     DROP TABLE IF EXISTS t1;
  543:     DROP TABLE IF EXISTS t2;
  544:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT FAIL, b);
  545:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT FAIL, y);
  546:     INSERT INTO t2 VALUES(1,3);
  547:     INSERT INTO t1 SELECT * FROM t2;
  548:     SELECT * FROM t1;
  549:   }
  550: } {1 3}
  551: do_test insert4-8.25 {
  552:   execsql {
  553:     DROP TABLE IF EXISTS t1;
  554:     DROP TABLE IF EXISTS t2;
  555:     CREATE TABLE t1(a INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, b);
  556:     CREATE TABLE t2(x INTEGER PRIMARY KEY ON CONFLICT ROLLBACK, y);
  557:     INSERT INTO t2 VALUES(1,3);
  558:     INSERT INTO t1 SELECT * FROM t2;
  559:     SELECT * FROM t1;
  560:   }
  561: } {1 3}
  562: 
  563: 
  564: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>