]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the CSV import capability in the CLI so that it understands
authordrh <>
Fri, 30 Jan 2026 12:15:25 +0000 (12:15 +0000)
committerdrh <>
Fri, 30 Jan 2026 12:15:25 +0000 (12:15 +0000)
backslash-escaped double-quotes.

FossilOrigin-Name: 7ba0594d3c24531bc014dd029093b0503118a29cfdd13af2a2ebdd456855ce94

manifest
manifest.uuid
src/shell.c.in
test/shell5.test

index e2f96512bde0319810abbf4e24d93691c6952d40..b16027a33198bb11c2eefccfded2811113887a4d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C kvvfs\sfix\sfor\s[https://github.com/sqlite/sqlite-wasm/issues/146|npm\sticket\s#146]:\suse\sof\sa\stest-mode-only\ssymbol\sin\snon-test\sruns\sleads\sto\sa\snull\sderef\sin\sxFileControl().
-D 2026-01-30T06:37:34.096
+C Enhance\sthe\sCSV\simport\scapability\sin\sthe\sCLI\sso\sthat\sit\sunderstands\nbackslash-escaped\sdouble-quotes.
+D 2026-01-30T12:15:25.973
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -739,7 +739,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c 4bee1bb231771e7c6e5aef243b1f74c3d330df5a005909d5e2c338fb1510fe55
-F src/shell.c.in d7c1041d6ad00bee2515842a1950640afe424df2e89ad2d6e3b9e68b184824a5
+F src/shell.c.in 09adbe4663ae8ac344f6cceb4cebbdc474099337c82b106419a1955638c32268
 F src/sqlite.h.in 8bcbaecfe2cbecf8c5c1381354fcdd7d307443e88b4953fccb222456c1267b61
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 1b7a0ee438bb5c2896d0609c537e917d8057b3340f6ad004d2de44f03e3d3cca
@@ -1621,7 +1621,7 @@ F test/shell1.test 56f200ba4b36cbe8229d84d848e6a8d69eb91a75b2deaf28c454027433c6e
 F test/shell2.test dc541d2681503e55466a24d35a4cbf8ca5b90b8fcdef37fc4db07373a67d31d3
 F test/shell3.test 603b448e917537cf77be0f265c05c6f63bc677c63a533c8e96aae923b56f4a0e
 F test/shell4.test e25580a792b7b54560c3a76b6968bd8189261f38979fe28e6bc6312c5db280db
-F test/shell5.test c6d7784404eb28edd9f63d2ff0190b4389f38c35895e06cfa4eaccdf03a127f9
+F test/shell5.test 06df656f0a7f200d5e32717e1791e7cc11147c387e76ba6edce8b7addfa1cf77
 F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8
 F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3
 F test/shell8.test 641cf21a99c59404c24e3062923734951c4099a6b6b6520de00cf7a1249ee871
@@ -2193,8 +2193,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 971d51374e3bf0d0e0b106750dc1e499d1fdbd3233cf8264a534138b27f8d0a1
-R 07a291ec2ea813a86573754ac7084e4d
-U stephan
-Z f16d84840e8d7717506027c5dc194f8c
+P 407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e
+R f26e958d4efb79f8ef1e08564237ec1b
+U drh
+Z e9a4e3f3e0a6390e31312a9d8cbd8430
 # Remove this line to create a well-formed Fossil manifest.
index e0f1b66bc2f7a1954b1b4344f33b70e708636b2a..490c8b59102b3dbaba3f2f27ef4ea92d96b2c500 100644 (file)
@@ -1 +1 @@
-407724c4e80efdf93d885e95b5209a100a3f470fe0298138be57201f65f9817e
+7ba0594d3c24531bc014dd029093b0503118a29cfdd13af2a2ebdd456855ce94
index fbecc22db6faca2f41cd3d372c5319afd6cb4ddc..6943fcd244ce62cc59fe94e84b008b7807c0840b 100644 (file)
@@ -5008,8 +5008,17 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
         break;
       }
       if( pc==cQuote && c!='\r' ){
-        cli_printf(stderr,"%s:%d: unescaped %c character\n", 
-                        p->zFile, p->nLine, cQuote);
+        if( ppc=='\\' ){
+          /* Deal backslash-escaped double-quote within a quoted string.
+          ** This is not RFC 4180 compliant, but one sees this in the
+          ** wild, so we might as well deal with it rather than raise 
+          ** an error. */
+          p->z[p->n-2] = '"';
+          p->n--;
+        }else{
+          cli_printf(stderr,"%s:%d: unescaped %c character\n", 
+                     p->zFile, p->nLine, cQuote);
+        }
       }
       if( c==EOF ){
         cli_printf(stderr,"%s:%d: unterminated %c-quoted field\n",
index 8e1466054531f6a94fa292386a7814e4f64f477d..e9082fd8ad1ff5a60e6e1a6807f3ce56c205a26a 100644 (file)
@@ -338,6 +338,25 @@ do_test shell5-1.10 {
   db eval {SELECT hex(c) FROM t1 ORDER BY rowid}
 } {636F6C756D6E33 783320220D0A64617461222033 783320220A64617461222033}
 
+# Import columns containing quoted strings that contain
+# a backslash-escaped quote.  This is not complaint with
+# RFC 4180, but people do it all the same.
+#
+do_test shell5-1.10.1 {
+  set out [open shell5.csv w]
+  fconfigure $out -translation lf
+  puts $out {column1,column2,column3,column4}
+  puts $out "x1,x2,\"x3 \\\"data\\\" 3\",x4"
+  close $out
+  forcedelete test.db
+  catchcmd test.db {
+    CREATE TABLE t1(a,b,c,d);
+.import -csv shell5.csv t1
+  }
+  sqlite3 db test.db
+  db eval {SELECT c FROM t1 ORDER BY rowid}
+} {column3 {x3 "data" 3}}
+
 # Blank last column with \r\n line endings.
 do_test shell5-1.11 {
   set out [open shell5.csv w]