mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Fix the ".import" command in the CLI so that it works correctly with tables
that contain computed columns. [forum:/forumpost/ca014d7358|forum post ca014d7358]. FossilOrigin-Name: 95a9c88b258f18ac671a4c712603931167cc8bd0b86e41481b200c08043338b5
This commit is contained in:
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\smore\sdocs\sfor\sthe\sOPFS\sdelete-before-open\sfeature.
|
C Fix\sthe\s".import"\scommand\sin\sthe\sCLI\sso\sthat\sit\sworks\scorrectly\swith\stables\nthat\scontain\scomputed\scolumns.\n[forum:/forumpost/ca014d7358|forum\spost\sca014d7358].
|
||||||
D 2024-03-11T09:39:52.643
|
D 2024-03-11T11:24:59.268
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -751,7 +751,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
|||||||
F src/resolve.c ef87e3bc7700bfe761a7bbee2ce6084f1766dc816dd82a3ae77c133eec898432
|
F src/resolve.c ef87e3bc7700bfe761a7bbee2ce6084f1766dc816dd82a3ae77c133eec898432
|
||||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||||
F src/select.c 43fabfc01bf87addd15e39f112f1e2ade15b19594835ab8a9e5bd50839d4e1b1
|
F src/select.c 43fabfc01bf87addd15e39f112f1e2ade15b19594835ab8a9e5bd50839d4e1b1
|
||||||
F src/shell.c.in 74a51fcae1bd945bcc818b6273a901f204410f4e8d2648221352a486ba2fe5ea
|
F src/shell.c.in cf80c636bccb0ff9db46995e39d69ca21fde2a8a331d1691e4d62a69d7841c8a
|
||||||
F src/sqlite.h.in 19a2db3995a699bd7f6dfb423856242bfceb7ec849a93c91d241d19fc28d9f0f
|
F src/sqlite.h.in 19a2db3995a699bd7f6dfb423856242bfceb7ec849a93c91d241d19fc28d9f0f
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||||
@ -1604,7 +1604,7 @@ F test/shell1.test c7127a5e780ffc9e14c476773127fdf292c6db226529c44c1676f37b37931
|
|||||||
F test/shell2.test 35226c070a8c7f64fd016dfac2a0db2a40f709b3131f61daacd9dad61536c9cb
|
F test/shell2.test 35226c070a8c7f64fd016dfac2a0db2a40f709b3131f61daacd9dad61536c9cb
|
||||||
F test/shell3.test 91febeac0412812bf6370abb8ed72700e32bf8f9878849414518f662dfd55e8a
|
F test/shell3.test 91febeac0412812bf6370abb8ed72700e32bf8f9878849414518f662dfd55e8a
|
||||||
F test/shell4.test 947029e5a9efae9054d424b309fc0311439c0c3a0866ebfa3b8a771120708220
|
F test/shell4.test 947029e5a9efae9054d424b309fc0311439c0c3a0866ebfa3b8a771120708220
|
||||||
F test/shell5.test c8b6c54f26ec537f8558273d7ed293ca3725ef42e6b12b8f151718628bd1473b
|
F test/shell5.test 263bfd6a49049295277e3f5bdc221390dc5e72f39954b23d43204ed81993304f
|
||||||
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
|
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
|
||||||
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
|
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
|
||||||
F test/shell8.test 3fd093d481aaa94dc77fb73f1044c1f19c7efe3477a395cc4f7450133bc54915
|
F test/shell8.test 3fd093d481aaa94dc77fb73f1044c1f19c7efe3477a395cc4f7450133bc54915
|
||||||
@ -2177,8 +2177,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P e87cf0d7700d33a439c91725460fbfe3a1765b48f71b4d73c38cadf6c166e0bd
|
P cb8d9c269c01f78f09069a2361e15087d9aeac63e9f1fd63fbd96b951384e9aa
|
||||||
R 86fc5680f4ee4960f4c1dcde68c7d5ad
|
R 9bba8f8b4bc3bf41627766fe1aa44b9c
|
||||||
U stephan
|
U drh
|
||||||
Z ee95146c516bc7ecdb021be98ac7e603
|
Z 1d2e3bf230fd6cd6fbc6ff6c84cfd8fb
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
cb8d9c269c01f78f09069a2361e15087d9aeac63e9f1fd63fbd96b951384e9aa
|
95a9c88b258f18ac671a4c712603931167cc8bd0b86e41481b200c08043338b5
|
@ -8778,16 +8778,15 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
#ifndef SQLITE_SHELL_FIDDLE
|
#ifndef SQLITE_SHELL_FIDDLE
|
||||||
if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){
|
if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){
|
||||||
char *zTable = 0; /* Insert data into this table */
|
char *zTable = 0; /* Insert data into this table */
|
||||||
char *zSchema = 0; /* within this schema (may default to "main") */
|
char *zSchema = 0; /* Schema of zTable */
|
||||||
char *zFile = 0; /* Name of file to extra content from */
|
char *zFile = 0; /* Name of file to extra content from */
|
||||||
sqlite3_stmt *pStmt = NULL; /* A statement */
|
sqlite3_stmt *pStmt = NULL; /* A statement */
|
||||||
int nCol; /* Number of columns in the table */
|
int nCol; /* Number of columns in the table */
|
||||||
int nByte; /* Number of bytes in an SQL string */
|
i64 nByte; /* Number of bytes in an SQL string */
|
||||||
int i, j; /* Loop counters */
|
int i, j; /* Loop counters */
|
||||||
int needCommit; /* True to COMMIT or ROLLBACK at end */
|
int needCommit; /* True to COMMIT or ROLLBACK at end */
|
||||||
int nSep; /* Number of bytes in p->colSeparator[] */
|
int nSep; /* Number of bytes in p->colSeparator[] */
|
||||||
char *zSql; /* An SQL statement */
|
char *zSql = 0; /* An SQL statement */
|
||||||
char *zFullTabName; /* Table name with schema if applicable */
|
|
||||||
ImportCtx sCtx; /* Reader context */
|
ImportCtx sCtx; /* Reader context */
|
||||||
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
|
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
|
||||||
int eVerbose = 0; /* Larger for more console output */
|
int eVerbose = 0; /* Larger for more console output */
|
||||||
@ -8921,24 +8920,14 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
while( (nSkip--)>0 ){
|
while( (nSkip--)>0 ){
|
||||||
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
|
while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
|
||||||
}
|
}
|
||||||
if( zSchema!=0 ){
|
|
||||||
zFullTabName = sqlite3_mprintf("\"%w\".\"%w\"", zSchema, zTable);
|
|
||||||
}else{
|
|
||||||
zFullTabName = sqlite3_mprintf("\"%w\"", zTable);
|
|
||||||
}
|
|
||||||
zSql = sqlite3_mprintf("SELECT * FROM %s", zFullTabName);
|
|
||||||
if( zSql==0 || zFullTabName==0 ){
|
|
||||||
import_cleanup(&sCtx);
|
|
||||||
shell_out_of_memory();
|
|
||||||
}
|
|
||||||
nByte = strlen30(zSql);
|
|
||||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
|
||||||
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
|
import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
|
||||||
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
|
if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) ){
|
||||||
|
/* Table does not exist. Create it. */
|
||||||
sqlite3 *dbCols = 0;
|
sqlite3 *dbCols = 0;
|
||||||
char *zRenames = 0;
|
char *zRenames = 0;
|
||||||
char *zColDefs;
|
char *zColDefs;
|
||||||
zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
|
zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
|
||||||
|
zSchema ? zSchema : "main", zTable);
|
||||||
while( xRead(&sCtx) ){
|
while( xRead(&sCtx) ){
|
||||||
zAutoColumn(sCtx.z, &dbCols, 0);
|
zAutoColumn(sCtx.z, &dbCols, 0);
|
||||||
if( sCtx.cTerm!=sCtx.cColSep ) break;
|
if( sCtx.cTerm!=sCtx.cColSep ) break;
|
||||||
@ -8953,34 +8942,50 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
assert(dbCols==0);
|
assert(dbCols==0);
|
||||||
if( zColDefs==0 ){
|
if( zColDefs==0 ){
|
||||||
eputf("%s: empty file\n", sCtx.zFile);
|
eputf("%s: empty file\n", sCtx.zFile);
|
||||||
import_fail:
|
|
||||||
sqlite3_free(zCreate);
|
|
||||||
sqlite3_free(zSql);
|
|
||||||
sqlite3_free(zFullTabName);
|
|
||||||
import_cleanup(&sCtx);
|
import_cleanup(&sCtx);
|
||||||
rc = 1;
|
rc = 1;
|
||||||
goto meta_command_exit;
|
goto meta_command_exit;
|
||||||
}
|
}
|
||||||
zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
|
zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
|
||||||
|
if( zCreate==0 ){
|
||||||
|
import_cleanup(&sCtx);
|
||||||
|
shell_out_of_memory();
|
||||||
|
}
|
||||||
if( eVerbose>=1 ){
|
if( eVerbose>=1 ){
|
||||||
oputf("%s\n", zCreate);
|
oputf("%s\n", zCreate);
|
||||||
}
|
}
|
||||||
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
|
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
|
||||||
if( rc ){
|
|
||||||
eputf("%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
|
|
||||||
goto import_fail;
|
|
||||||
}
|
|
||||||
sqlite3_free(zCreate);
|
sqlite3_free(zCreate);
|
||||||
zCreate = 0;
|
zCreate = 0;
|
||||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
if( rc ){
|
||||||
|
eputf("%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
|
||||||
|
import_cleanup(&sCtx);
|
||||||
|
rc = 1;
|
||||||
|
goto meta_command_exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);",
|
||||||
|
zTable, zSchema);
|
||||||
|
if( zSql==0 ){
|
||||||
|
import_cleanup(&sCtx);
|
||||||
|
shell_out_of_memory();
|
||||||
|
}
|
||||||
|
nByte = strlen(zSql);
|
||||||
|
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||||
|
sqlite3_free(zSql);
|
||||||
|
zSql = 0;
|
||||||
if( rc ){
|
if( rc ){
|
||||||
if (pStmt) sqlite3_finalize(pStmt);
|
if (pStmt) sqlite3_finalize(pStmt);
|
||||||
eputf("Error: %s\n", sqlite3_errmsg(p->db));
|
eputf("Error: %s\n", sqlite3_errmsg(p->db));
|
||||||
goto import_fail;
|
import_cleanup(&sCtx);
|
||||||
|
rc = 1;
|
||||||
|
goto meta_command_exit;
|
||||||
|
}
|
||||||
|
if( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||||
|
nCol = sqlite3_column_int(pStmt, 0);
|
||||||
|
}else{
|
||||||
|
nCol = 0;
|
||||||
}
|
}
|
||||||
sqlite3_free(zSql);
|
|
||||||
nCol = sqlite3_column_count(pStmt);
|
|
||||||
sqlite3_finalize(pStmt);
|
sqlite3_finalize(pStmt);
|
||||||
pStmt = 0;
|
pStmt = 0;
|
||||||
if( nCol==0 ) return 0; /* no columns, no error */
|
if( nCol==0 ) return 0; /* no columns, no error */
|
||||||
@ -8989,7 +8994,12 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
import_cleanup(&sCtx);
|
import_cleanup(&sCtx);
|
||||||
shell_out_of_memory();
|
shell_out_of_memory();
|
||||||
}
|
}
|
||||||
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zFullTabName);
|
if( zSchema ){
|
||||||
|
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?",
|
||||||
|
zSchema, zTable);
|
||||||
|
}else{
|
||||||
|
sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
|
||||||
|
}
|
||||||
j = strlen30(zSql);
|
j = strlen30(zSql);
|
||||||
for(i=1; i<nCol; i++){
|
for(i=1; i<nCol; i++){
|
||||||
zSql[j++] = ',';
|
zSql[j++] = ',';
|
||||||
@ -9001,13 +9011,15 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
oputf("Insert using: %s\n", zSql);
|
oputf("Insert using: %s\n", zSql);
|
||||||
}
|
}
|
||||||
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
|
||||||
|
sqlite3_free(zSql);
|
||||||
|
zSql = 0;
|
||||||
if( rc ){
|
if( rc ){
|
||||||
eputf("Error: %s\n", sqlite3_errmsg(p->db));
|
eputf("Error: %s\n", sqlite3_errmsg(p->db));
|
||||||
if (pStmt) sqlite3_finalize(pStmt);
|
if (pStmt) sqlite3_finalize(pStmt);
|
||||||
goto import_fail;
|
import_cleanup(&sCtx);
|
||||||
|
rc = 1;
|
||||||
|
goto meta_command_exit;
|
||||||
}
|
}
|
||||||
sqlite3_free(zSql);
|
|
||||||
sqlite3_free(zFullTabName);
|
|
||||||
needCommit = sqlite3_get_autocommit(p->db);
|
needCommit = sqlite3_get_autocommit(p->db);
|
||||||
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
||||||
do{
|
do{
|
||||||
|
@ -570,4 +570,18 @@ SELECT * FROM t1;}
|
|||||||
} {0 { 1 = あい
|
} {0 { 1 = あい
|
||||||
2 = うえお}}
|
2 = うえお}}
|
||||||
|
|
||||||
|
# 2024-03-11 https://sqlite.org/forum/forumpost/ca014d7358
|
||||||
|
# Import into a table that contains computed columns.
|
||||||
|
#
|
||||||
|
do_test shell5-7.1 {
|
||||||
|
set out [open shell5.csv w]
|
||||||
|
fconfigure $out -translation lf
|
||||||
|
puts $out {aaa|bbb}
|
||||||
|
close $out
|
||||||
|
forcedelete test.db
|
||||||
|
catchcmd :memory: {CREATE TABLE t1(a TEXT, b TEXT, c AS (a||b));
|
||||||
|
.import shell5.csv t1
|
||||||
|
SELECT * FROM t1;}
|
||||||
|
} {0 aaa|bbb|aaabbb}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user