]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Incremental improvements to .import, and new test cases.
authordrh <>
Mon, 29 Dec 2025 19:04:41 +0000 (19:04 +0000)
committerdrh <>
Mon, 29 Dec 2025 19:04:41 +0000 (19:04 +0000)
FossilOrigin-Name: 5a1e931b19c346bdc8d1a51fa6ef8ee04b7371cdf5df2ee32e1333226c42d327

manifest
manifest.uuid
src/shell.c.in
test/import01.sql

index 2c5860cd1a1407485c0582d2239bcbb274331fc7..8f2d8a0032ed1527bf23586cc48db041305d593a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sto\sthe\sunix\sbuild\sdocumentation.
-D 2025-12-29T12:46:35.028
+C Incremental\simprovements\sto\s.import,\sand\snew\stest\scases.
+D 2025-12-29T19:04:41.234
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -737,7 +737,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c 85852256d860f3ba5be4a9edc1238e68dbea082a0167f31b7345c821ae45775d
-F src/shell.c.in 8806b477d53b3937a995aa1f214f8aa444c16043688525cb95fd81b30c2849e2
+F src/shell.c.in 439bd0703be4c6f1d42952501712245504e5f540fe753137948b57459c45d446
 F src/sqlite.h.in b6599377f02ef9d545a8da48959213928b63291ad83ff65e5f3a72bf4fec595d
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998
@@ -1265,7 +1265,7 @@ F test/hook.test 2d89bf9480646feb8093be3a58ea502d6521906779ed960de31dd9c4502c054
 F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8
 F test/icu.test 8da7d52cd9722c82f33b0466ed915460cb03c23a38f18a9a2d3ff97da9a4a8c0
 F test/ieee754.test 0d3ab84ab2069c9994c833a7cd820ee6037f0cf888e206a4a7fc05f735d5790a
-F test/import01.sql 1e73de7fe4d23e83678cb0d0d58484fc34c5f583803a19b7477ee0308a207cd0
+F test/import01.sql 87d58a2418cd912568fd27e03cb7c1246cae06a0c72007e784f31d17f7f9230b
 F test/imposter1.sql fc5ad0945bb19622688c7a1cd7dfd1cefa4b013bac9e2628c22b03c7309f021f
 F test/imposter1.test 5a20b2cdeb53e65fc57cdb10a33750bd4ef6259909eaf1972253b9e79f7a3fb2
 F test/in.test edf979bff3244b9e47849e2b43886631354c8213791f42da92216f08012141af
@@ -2189,8 +2189,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c f40bccf0236f8bcc34b299781b7d34cb269ace23afe5c1b8a9d966e2fa1ce9e5
-P adf5d624cf109ebd05952e5df62f143f40829070cbcbe43280d371a60db7470b
-R d9c87e99e2eda5a65dccb1c2239e0357
+P 004cf4ad3cb0c05e501a464bee55e8ed168c4825cf419902890593468ca4d588
+R 9e128f52189eb35675757e15cd903b93
 U drh
-Z d9b7bd5e3ec50be58dc81d2728d15b04
+Z 589f22d91422bd38ec49b8857de91380
 # Remove this line to create a well-formed Fossil manifest.
index 10f71276a2716630d3a7d6df65198b9807d8cafd..0b4f21cd725aa1a3fd77e991f61033afa4674955 100644 (file)
@@ -1 +1 @@
-004cf4ad3cb0c05e501a464bee55e8ed168c4825cf419902890593468ca4d588
+5a1e931b19c346bdc8d1a51fa6ef8ee04b7371cdf5df2ee32e1333226c42d327
index c309d2a0ff4817f99f75e2d094d8a171d9439f79..529de8ca2c564053968589cce0eb1b422a4c56df 100644 (file)
@@ -7462,7 +7462,7 @@ static int dotCmdImport(ShellState *p){
     }
   }
   if( zTable==0 ){
-    cli_printf(p->out, "ERROR: missing %s argument\n",
+    dotCmdError(p, nArg, 0, "Missing %s argument\n",
           zFile==0 ? "FILE" : "TABLE");
     return 1;
   }
@@ -7508,29 +7508,41 @@ static int dotCmdImport(ShellState *p){
     /* Input text comes from subsequent lines of script until the zFile
     ** delimiter */
     int nEndMark = strlen30(sCtx.zFile);
-    sqlite3_str *pPattern = sqlite3_str_new(p->db);
+    sqlite3_str *pContent = sqlite3_str_new(p->db);
     int ckEnd = 1;
+    i64 iStart = p->lineno;
     char zLine[2000];
     while( sqlite3_fgets(zLine,sizeof(zLine),p->in) ){
-      if( ckEnd && cli_strncmp(&sCtx.zFile[2],zLine,nEndMark-2)==0 ) break;
+      if( ckEnd && cli_strncmp(&sCtx.zFile[2],zLine,nEndMark-2)==0 ){
+        ckEnd = 2;
+        if( strchr(zLine,'\n') ) p->lineno++;
+        break;
+      }
       if( strchr(zLine,'\n') ){
         p->lineno++;
         ckEnd = 1;
       }else{
         ckEnd = 0;
       }
-      sqlite3_str_appendall(pPattern, zLine);
+      sqlite3_str_appendall(pContent, zLine);
     }
-    sCtx.zIn = sqlite3_str_finish(pPattern);
+    sCtx.zIn = sqlite3_str_finish(pContent);
     if( sCtx.zIn==0 ){
       sCtx.zIn = sqlite3_mprintf("");
     }
+    if( ckEnd<2 ){
+      cli_printf(stderr, "%s:%lld: Content terminator \"%s\" not found.\n",
+            p->zInFile, iStart, &sCtx.zFile[2]);
+      import_cleanup(&sCtx);
+      return 1;
+    }
   }else{
     sCtx.in = sqlite3_fopen(sCtx.zFile, "rb");
     sCtx.xCloser = fclose;
   }
   if( sCtx.in==0 && sCtx.zIn==0 ){
-    cli_printf(stderr,"Error: cannot open \"%s\"\n", zFile);
+    cli_printf(stderr,"%s:%lld: cannot open \"%s\"\n", zFile, p->lineno);
+    import_cleanup(&sCtx);
     return 1;
   }
   if( eVerbose>=1 ){
@@ -8602,7 +8614,6 @@ dotCmdOutput_error:
 ** All pattern lines and the ENDMARK are discarded.
 **
 ** Options:
-**   --error-prefix TEXT    Change error message prefix text to TEXT
 **   --exact                Do an exact comparison including leading and
 **                          trailing whitespace.
 **   --glob                 Treat PATTERN as a GLOB
index 9b5f420a8d47f40e252c6df69cbbc9a961479e93..61d5e2452bc7ea3e40ba6bb64a67af889ef8dd12 100644 (file)
@@ -68,3 +68,150 @@ SELECT * FROM t1;
 │ one  │ two  │ three │
 ╰──────┴──────┴───────╯
 END
+
+.testcase 130
+DELETE FROM t1;
+.import -csv -colsep "," -rowsep "\n" <<END t1
+this,"is a","test ""with quotes"""
+"second",,"line"
+END
+SELECT * FROM t1;
+.check <<END
+╭────────┬──────┬────────────────────╮
+│   a    │  b   │         c          │
+╞════════╪══════╪════════════════════╡
+│ this   │ is a │ test "with quotes" │
+│ second │      │ line               │
+╰────────┴──────┴────────────────────╯
+END
+.testcase 131
+DELETE FROM t1;
+.import -ascii -colsep "," -rowsep "\n" <<END t1
+this,"is a","test ""with quotes"""
+"second",,"line"
+END
+SELECT * FROM t1;
+.check <<END
+╭──────────┬────────┬────────────────────────╮
+│    a     │   b    │           c            │
+╞══════════╪════════╪════════════════════════╡
+│ this     │ "is a" │ "test ""with quotes""" │
+│ "second" │        │ "line"                 │
+╰──────────┴────────┴────────────────────────╯
+END
+
+.testcase 140
+DROP TABLE t1;
+.import -csv <<END t1
+"abc","def","xy z"
+"This","is","a"
+"test","...",
+END
+SELECT * FROM t1;
+.check <<END
+╭──────┬─────┬──────╮
+│ abc  │ def │ xy z │
+╞══════╪═════╪══════╡
+│ This │ is  │ a    │
+│ test │ ... │      │
+╰──────┴─────┴──────╯
+END
+.testcase 141
+SELECT sql FROM sqlite_schema WHERE name='t1';
+.check <<END
+╭──────────────────────────────────────╮
+│                 sql                  │
+╞══════════════════════════════════════╡
+│ CREATE TABLE "t1"(                   │
+│ "abc" TEXT, "def" TEXT, "xy z" TEXT) │
+╰──────────────────────────────────────╯
+END
+
+.testcase 150
+DROP TABLE t1;
+.import -csv -v <<END t1
+"abc","def","xy z"
+"This","is","a"
+"test","...",
+END
+SELECT * FROM t1;
+.check <<END
+Column separator ",", row separator "\n"
+CREATE TABLE "main"."t1"(
+"abc" TEXT, "def" TEXT, "xy z" TEXT)
+
+Added 2 rows with 0 errors using 3 lines of input
+╭──────┬─────┬──────╮
+│ abc  │ def │ xy z │
+╞══════╪═════╪══════╡
+│ This │ is  │ a    │
+│ test │ ... │      │
+╰──────┴─────┴──────╯
+END
+
+.testcase 160
+DROP TABLE t1;
+.import -csv -schema TEMP <<END t2
+"x"
+"abcdef"
+END
+SELECT * FROM t2;
+.tables
+.check <<END
+╭────────╮
+│   x    │
+╞════════╡
+│ abcdef │
+╰────────╯
+temp.t2
+END
+
+.testcase 170
+.import -csv -skip 2 <<END t3
+a,b,c
+d,e,f
+g,h,i
+j,k,l
+m,n,o
+END
+SELECT * FROM t3;
+.check <<END
+╭───┬───┬───╮
+│ g │ h │ i │
+╞═══╪═══╪═══╡
+│ j │ k │ l │
+│ m │ n │ o │
+╰───┴───┴───╯
+END
+
+.testcase 180
+DELETE FROM t3;
+.import -csv -skip 7 <<END t3
+a,b,c
+d,e,f
+g,h,i
+j,k,l
+m,n,o
+END
+SELECT * FROM t3;
+.check <<END
+END
+
+.testcase 200 --error-prefix ERROR:
+.import -csv
+.check 'ERROR: Missing FILE argument'
+.testcase 201
+.import -csv file1.csv
+.check 'ERROR: Missing TABLE argument'
+.testcase --error-prefix test-error: 202
+.import -csvxyzzy file1.csv
+.check <<END
+test-error: .import -csvxyzzy file1.csv
+test-error:         ^--- unknown option
+END
+.testcase 203
+.import -csv file1.csv t4 -colsep
+.check <<END
+test-error: .import -csv file1.csv t4 -colsep
+test-error:       missing argument ---^
+END