1*1da57d55SToomas Soome#
27c478bd9Sstevel@tonic-gate# 2001 September 15
37c478bd9Sstevel@tonic-gate#
47c478bd9Sstevel@tonic-gate# The author disclaims copyright to this source code.  In place of
57c478bd9Sstevel@tonic-gate# a legal notice, here is a blessing:
67c478bd9Sstevel@tonic-gate#
77c478bd9Sstevel@tonic-gate#    May you do good and not evil.
87c478bd9Sstevel@tonic-gate#    May you find forgiveness for yourself and forgive others.
97c478bd9Sstevel@tonic-gate#    May you share freely, never taking more than you give.
107c478bd9Sstevel@tonic-gate#
117c478bd9Sstevel@tonic-gate#***********************************************************************
127c478bd9Sstevel@tonic-gate# This file implements regression tests for SQLite library.  The
137c478bd9Sstevel@tonic-gate# focus of this file is testing the COPY statement.
147c478bd9Sstevel@tonic-gate#
157c478bd9Sstevel@tonic-gate# $Id: copy.test,v 1.17 2004/02/17 18:26:57 dougcurrie Exp $
167c478bd9Sstevel@tonic-gate
177c478bd9Sstevel@tonic-gateset testdir [file dirname $argv0]
187c478bd9Sstevel@tonic-gatesource $testdir/tester.tcl
197c478bd9Sstevel@tonic-gate
207c478bd9Sstevel@tonic-gate# Create a file of data from which to copy.
217c478bd9Sstevel@tonic-gate#
227c478bd9Sstevel@tonic-gateset f [open data1.txt w]
237c478bd9Sstevel@tonic-gateputs $f "11\t22\t33"
247c478bd9Sstevel@tonic-gateputs $f "22\t33\t11"
257c478bd9Sstevel@tonic-gateclose $f
267c478bd9Sstevel@tonic-gateset f [open data2.txt w]
277c478bd9Sstevel@tonic-gateputs $f "11\t22\t33"
287c478bd9Sstevel@tonic-gateputs $f "\\."
297c478bd9Sstevel@tonic-gateputs $f "22\t33\t11"
307c478bd9Sstevel@tonic-gateclose $f
317c478bd9Sstevel@tonic-gateset f [open data3.txt w]
327c478bd9Sstevel@tonic-gateputs $f "11\t22\t33\t44"
337c478bd9Sstevel@tonic-gateputs $f "22\t33\t11"
347c478bd9Sstevel@tonic-gateclose $f
357c478bd9Sstevel@tonic-gateset f [open data4.txt w]
367c478bd9Sstevel@tonic-gateputs $f "11 | 22 | 33"
377c478bd9Sstevel@tonic-gateputs $f "22 | 33 | 11"
387c478bd9Sstevel@tonic-gateclose $f
397c478bd9Sstevel@tonic-gateset f [open data5.txt w]
407c478bd9Sstevel@tonic-gateputs $f "11|22|33"
417c478bd9Sstevel@tonic-gateputs $f "22|33|11"
427c478bd9Sstevel@tonic-gateclose $f
437c478bd9Sstevel@tonic-gateset f [open dataX.txt w]
44*1da57d55SToomas Soomefconfigure $f -translation binary
457c478bd9Sstevel@tonic-gateputs -nonewline $f "11|22|33\r"
467c478bd9Sstevel@tonic-gateputs -nonewline $f "22|33|44\r\n"
477c478bd9Sstevel@tonic-gateputs -nonewline $f "33|44|55\n"
487c478bd9Sstevel@tonic-gateputs -nonewline $f "44|55|66\r"
497c478bd9Sstevel@tonic-gateputs -nonewline $f "55|66|77\r\n"
507c478bd9Sstevel@tonic-gateputs -nonewline $f "66|77|88\n"
517c478bd9Sstevel@tonic-gateclose $f
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate# Try to COPY into a non-existant table.
547c478bd9Sstevel@tonic-gate#
557c478bd9Sstevel@tonic-gatedo_test copy-1.1 {
567c478bd9Sstevel@tonic-gate  set v [catch {execsql {COPY test1 FROM 'data1.txt'}} msg]
577c478bd9Sstevel@tonic-gate  lappend v $msg
587c478bd9Sstevel@tonic-gate} {1 {no such table: test1}}
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate# Try to insert into sqlite_master
617c478bd9Sstevel@tonic-gate#
627c478bd9Sstevel@tonic-gatedo_test copy-1.2 {
637c478bd9Sstevel@tonic-gate  set v [catch {execsql {COPY sqlite_master FROM 'data2.txt'}} msg]
647c478bd9Sstevel@tonic-gate  lappend v $msg
657c478bd9Sstevel@tonic-gate} {1 {table sqlite_master may not be modified}}
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate# Do some actual inserts
687c478bd9Sstevel@tonic-gate#
697c478bd9Sstevel@tonic-gatedo_test copy-1.3 {
707c478bd9Sstevel@tonic-gate  execsql {CREATE TABLE test1(one int, two int, three int)}
717c478bd9Sstevel@tonic-gate  execsql {COPY test1 FROM 'data1.txt'}
727c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 ORDER BY one}
737c478bd9Sstevel@tonic-gate} {11 22 33 22 33 11}
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate# Make sure input terminates at \.
767c478bd9Sstevel@tonic-gate#
777c478bd9Sstevel@tonic-gatedo_test copy-1.4 {
787c478bd9Sstevel@tonic-gate  execsql {DELETE FROM test1}
797c478bd9Sstevel@tonic-gate  execsql {COPY test1 FROM 'data2.txt'}
807c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 ORDER BY one}
817c478bd9Sstevel@tonic-gate} {11 22 33}
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate# Test out the USING DELIMITERS clause
847c478bd9Sstevel@tonic-gate#
857c478bd9Sstevel@tonic-gatedo_test copy-1.5 {
867c478bd9Sstevel@tonic-gate  execsql {DELETE FROM test1}
877c478bd9Sstevel@tonic-gate  execsql {COPY test1 FROM 'data4.txt' USING DELIMITERS ' | '}
887c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 ORDER BY one}
897c478bd9Sstevel@tonic-gate} {11 22 33 22 33 11}
907c478bd9Sstevel@tonic-gatedo_test copy-1.6 {
917c478bd9Sstevel@tonic-gate  execsql {DELETE FROM test1}
927c478bd9Sstevel@tonic-gate  execsql {COPY test1 FROM 'data5.txt' USING DELIMITERS '|'}
937c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 ORDER BY one}
947c478bd9Sstevel@tonic-gate} {11 22 33 22 33 11}
957c478bd9Sstevel@tonic-gatedo_test copy-1.7 {
967c478bd9Sstevel@tonic-gate  execsql {DELETE FROM test1}
977c478bd9Sstevel@tonic-gate  execsql {COPY test1 FROM 'data4.txt' USING DELIMITERS '|'}
987c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 ORDER BY one}
997c478bd9Sstevel@tonic-gate} {{11 } { 22 } { 33} {22 } { 33 } { 11}}
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate# Try copying into a table that has one or more indices.
1027c478bd9Sstevel@tonic-gate#
1037c478bd9Sstevel@tonic-gatedo_test copy-1.8 {
1047c478bd9Sstevel@tonic-gate  execsql {DELETE FROM test1}
1057c478bd9Sstevel@tonic-gate  execsql {CREATE INDEX index1 ON test1(one)}
1067c478bd9Sstevel@tonic-gate  execsql {CREATE INDEX index2 ON test1(two)}
1077c478bd9Sstevel@tonic-gate  execsql {CREATE INDEX index3 ON test1(three)}
1087c478bd9Sstevel@tonic-gate  execsql {COPY test1 from 'data1.txt'}
1097c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 WHERE one=11}
1107c478bd9Sstevel@tonic-gate} {11 22 33}
1117c478bd9Sstevel@tonic-gatedo_test copy-1.8b {
1127c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 WHERE one=22}
1137c478bd9Sstevel@tonic-gate} {22 33 11}
1147c478bd9Sstevel@tonic-gatedo_test copy-1.8c {
1157c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 WHERE two=22}
1167c478bd9Sstevel@tonic-gate} {11 22 33}
1177c478bd9Sstevel@tonic-gatedo_test copy-1.8d {
1187c478bd9Sstevel@tonic-gate  execsql {SELECT * FROM test1 WHERE three=11}
1197c478bd9Sstevel@tonic-gate} {22 33 11}
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate# Try inserting really long data
1237c478bd9Sstevel@tonic-gate#
1247c478bd9Sstevel@tonic-gateset x {}
1257c478bd9Sstevel@tonic-gatefor {set i 0} {$i<100} {incr i} {
1267c478bd9Sstevel@tonic-gate  append x "($i)-abcdefghijklmnopqrstyvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-"
1277c478bd9Sstevel@tonic-gate}
1287c478bd9Sstevel@tonic-gatedo_test copy-2.1 {
1297c478bd9Sstevel@tonic-gate  execsql {CREATE TABLE test2(a int, x text)}
1307c478bd9Sstevel@tonic-gate  set f [open data21.txt w]
1317c478bd9Sstevel@tonic-gate  puts $f "123\t$x"
1327c478bd9Sstevel@tonic-gate  close $f
1337c478bd9Sstevel@tonic-gate  execsql {COPY test2 FROM 'data21.txt'}
1347c478bd9Sstevel@tonic-gate  execsql {SELECT x from test2}
1357c478bd9Sstevel@tonic-gate} $x
1367c478bd9Sstevel@tonic-gatefile delete -force data21.txt
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate# Test the escape character mechanism
1397c478bd9Sstevel@tonic-gate#
1407c478bd9Sstevel@tonic-gatedo_test copy-3.1 {
1417c478bd9Sstevel@tonic-gate  set fd [open data6.txt w]
1427c478bd9Sstevel@tonic-gate  puts $fd "hello\\\tworld\t1"
1437c478bd9Sstevel@tonic-gate  puts $fd "hello\tworld\\\t2"
1447c478bd9Sstevel@tonic-gate  close $fd
1457c478bd9Sstevel@tonic-gate  execsql {
1467c478bd9Sstevel@tonic-gate    CREATE TABLE t1(a text, b text);
1477c478bd9Sstevel@tonic-gate    COPY t1 FROM 'data6.txt';
1487c478bd9Sstevel@tonic-gate    SELECT * FROM t1 ORDER BY a;
1497c478bd9Sstevel@tonic-gate  }
1507c478bd9Sstevel@tonic-gate} {hello {world	2} {hello	world} 1}
1517c478bd9Sstevel@tonic-gatedo_test copy-3.2 {
1527c478bd9Sstevel@tonic-gate  set fd [open data6.txt w]
1537c478bd9Sstevel@tonic-gate  puts $fd "1\thello\\\nworld"
1547c478bd9Sstevel@tonic-gate  puts $fd "2\thello world"
1557c478bd9Sstevel@tonic-gate  close $fd
1567c478bd9Sstevel@tonic-gate  execsql {
1577c478bd9Sstevel@tonic-gate    DELETE FROM t1;
1587c478bd9Sstevel@tonic-gate    COPY t1 FROM 'data6.txt';
1597c478bd9Sstevel@tonic-gate    SELECT * FROM t1 ORDER BY a;
1607c478bd9Sstevel@tonic-gate  }
1617c478bd9Sstevel@tonic-gate} {1 {hello
1627c478bd9Sstevel@tonic-gateworld} 2 {hello world}}
1637c478bd9Sstevel@tonic-gatedo_test copy-3.3 {
1647c478bd9Sstevel@tonic-gate  set fd [open data6.txt w]
1657c478bd9Sstevel@tonic-gate  puts $fd "1:hello\\b\\f\\n\\r\\t\\vworld"
1667c478bd9Sstevel@tonic-gate  puts $fd "2:hello world"
1677c478bd9Sstevel@tonic-gate  close $fd
1687c478bd9Sstevel@tonic-gate  execsql {
1697c478bd9Sstevel@tonic-gate    DELETE FROM t1;
1707c478bd9Sstevel@tonic-gate    COPY t1 FROM 'data6.txt' USING DELIMITERS ':';
1717c478bd9Sstevel@tonic-gate    SELECT * FROM t1 ORDER BY a;
1727c478bd9Sstevel@tonic-gate  }
1737c478bd9Sstevel@tonic-gate} [list 1 "hello\b\f\n\r\t\vworld" 2 "hello world"]
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate# Test the embedded NULL logic.
1767c478bd9Sstevel@tonic-gate#
1777c478bd9Sstevel@tonic-gatedo_test copy-4.1 {
1787c478bd9Sstevel@tonic-gate  set fd [open data6.txt w]
1797c478bd9Sstevel@tonic-gate  puts $fd "1\t\\N"
1807c478bd9Sstevel@tonic-gate  puts $fd "\\N\thello world"
1817c478bd9Sstevel@tonic-gate  close $fd
1827c478bd9Sstevel@tonic-gate  execsql {
1837c478bd9Sstevel@tonic-gate    DELETE FROM t1;
1847c478bd9Sstevel@tonic-gate    COPY t1 FROM 'data6.txt';
1857c478bd9Sstevel@tonic-gate    SELECT * FROM t1 WHERE a IS NULL;
1867c478bd9Sstevel@tonic-gate  }
1877c478bd9Sstevel@tonic-gate} {{} {hello world}}
1887c478bd9Sstevel@tonic-gatedo_test copy-4.2 {
1897c478bd9Sstevel@tonic-gate  execsql {
1907c478bd9Sstevel@tonic-gate    SELECT * FROM t1 WHERE b IS NULL;
1917c478bd9Sstevel@tonic-gate  }
1927c478bd9Sstevel@tonic-gate} {1 {}}
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate# Test the conflict resolution logic for COPY
1957c478bd9Sstevel@tonic-gate#
1967c478bd9Sstevel@tonic-gatedo_test copy-5.1 {
1977c478bd9Sstevel@tonic-gate  execsql {
1987c478bd9Sstevel@tonic-gate    DROP TABLE t1;
1997c478bd9Sstevel@tonic-gate    CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c);
2007c478bd9Sstevel@tonic-gate    COPY t1 FROM 'data5.txt' USING DELIMITERS '|';
2017c478bd9Sstevel@tonic-gate    SELECT * FROM t1;
2027c478bd9Sstevel@tonic-gate  }
2037c478bd9Sstevel@tonic-gate} {11 22 33 22 33 11}
2047c478bd9Sstevel@tonic-gatedo_test copy-5.2 {
2057c478bd9Sstevel@tonic-gate  set fd [open data6.txt w]
2067c478bd9Sstevel@tonic-gate  puts $fd "33|22|44"
2077c478bd9Sstevel@tonic-gate  close $fd
2087c478bd9Sstevel@tonic-gate  catchsql {
2097c478bd9Sstevel@tonic-gate    COPY t1 FROM 'data6.txt' USING DELIMITERS '|';
2107c478bd9Sstevel@tonic-gate    SELECT * FROM t1;
2117c478bd9Sstevel@tonic-gate  }
2127c478bd9Sstevel@tonic-gate} {1 {column b is not unique}}
2137c478bd9Sstevel@tonic-gatedo_test copy-5.3 {
2147c478bd9Sstevel@tonic-gate  set fd [open data6.txt w]
2157c478bd9Sstevel@tonic-gate  puts $fd "33|22|44"
2167c478bd9Sstevel@tonic-gate  close $fd
2177c478bd9Sstevel@tonic-gate  catchsql {
2187c478bd9Sstevel@tonic-gate    COPY OR IGNORE t1 FROM 'data6.txt' USING DELIMITERS '|';
2197c478bd9Sstevel@tonic-gate    SELECT * FROM t1;
2207c478bd9Sstevel@tonic-gate  }
2217c478bd9Sstevel@tonic-gate} {0 {11 22 33 22 33 11}}
2227c478bd9Sstevel@tonic-gatedo_test copy-5.4 {
2237c478bd9Sstevel@tonic-gate  set fd [open data6.txt w]
2247c478bd9Sstevel@tonic-gate  puts $fd "33|22|44"
2257c478bd9Sstevel@tonic-gate  close $fd
2267c478bd9Sstevel@tonic-gate  catchsql {
2277c478bd9Sstevel@tonic-gate    COPY OR REPLACE t1 FROM 'data6.txt' USING DELIMITERS '|';
2287c478bd9Sstevel@tonic-gate    SELECT * FROM t1;
2297c478bd9Sstevel@tonic-gate  }
2307c478bd9Sstevel@tonic-gate} {0 {22 33 11 33 22 44}}
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gatedo_test copy-5.5 {
2337c478bd9Sstevel@tonic-gate  execsql {
2347c478bd9Sstevel@tonic-gate    DELETE FROM t1;
2357c478bd9Sstevel@tonic-gate    PRAGMA count_changes=on;
2367c478bd9Sstevel@tonic-gate    COPY t1 FROM 'data5.txt' USING DELIMITERS '|';
2377c478bd9Sstevel@tonic-gate  }
2387c478bd9Sstevel@tonic-gate} {2}
2397c478bd9Sstevel@tonic-gatedo_test copy-5.6 {
2407c478bd9Sstevel@tonic-gate  execsql {
2417c478bd9Sstevel@tonic-gate    COPY OR REPLACE t1 FROM 'data5.txt' USING DELIMITERS '|';
2427c478bd9Sstevel@tonic-gate  }
2437c478bd9Sstevel@tonic-gate} {2}
2447c478bd9Sstevel@tonic-gatedo_test copy-5.7 {
2457c478bd9Sstevel@tonic-gate  execsql {
2467c478bd9Sstevel@tonic-gate    COPY OR IGNORE t1 FROM 'data5.txt' USING DELIMITERS '|';
2477c478bd9Sstevel@tonic-gate  }
2487c478bd9Sstevel@tonic-gate} {0}
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gatedo_test copy-6.1 {
2517c478bd9Sstevel@tonic-gate  execsql {
2527c478bd9Sstevel@tonic-gate    PRAGMA count_changes=off;
2537c478bd9Sstevel@tonic-gate    CREATE TABLE t2(a,b,c);
2547c478bd9Sstevel@tonic-gate    COPY t2 FROM 'dataX.txt' USING DELIMITERS '|';
2557c478bd9Sstevel@tonic-gate    SELECT * FROM t2;
2567c478bd9Sstevel@tonic-gate  }
2577c478bd9Sstevel@tonic-gate} {11 22 33 22 33 44 33 44 55 44 55 66 55 66 77 66 77 88}
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gateintegrity_check copy-7.1
2607c478bd9Sstevel@tonic-gate
261*1da57d55SToomas Soome# Cleanup
2627c478bd9Sstevel@tonic-gate#
2637c478bd9Sstevel@tonic-gate#file delete -force data1.txt data2.txt data3.txt data4.txt data5.txt \
2647c478bd9Sstevel@tonic-gate                   data6.txt dataX.txt
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gatefinish_test
267