CLI's .import column rename made more minimal, and reports renames.
FossilOrigin-Name: c626cff7f99ec502ebd46f9cdafc3d088697544ef5d6559b6b3ae85679b4f9fa
This commit is contained in:
parent
42de1c52dd
commit
3363386145
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Sync\sw/trunk,\sfix\szAutoColumns\splacement\sblunder,\sall\sto\spass\sall\sTCL\stests
|
||||
D 2022-02-13T22:18:22.163
|
||||
C CLI's\s.import\scolumn\srename\smade\smore\sminimal,\sand\sreports\srenames.
|
||||
D 2022-02-14T01:12:46.316
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
|
||||
F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 3baa9dd8cf240654773c7974e2bcce398ac9dd24419c36684156963defe43b35
|
||||
F src/shell.c.in 233a5c7f0ee9a9d1b88f1caed538d813390bb474082d9d74504d846ccb49f31e x
|
||||
F src/shell.c.in 1289a2e10f48e75956700f61aac63beff7f05988ac7a4c701800b9f0e9adad4e x
|
||||
F src/sqlite.h.in 7047c4b60fa550264d6363bb1d983540e7828fb19d2d1e5aa43b52ca13144807
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6
|
||||
@ -1392,7 +1392,7 @@ F test/shell1.test b224e0793c5f48aa3749e65d8c64b93a30731bd206f2e41e6c5f1bee1bdb1
|
||||
F test/shell2.test 89e4b2db062d52baed75022227b462d085cff495809de1699652779d8e0257d6
|
||||
F test/shell3.test a50628ab1d78d90889d9d3f32fb2c084ee15674771e96afe954aaa0accd1de3c
|
||||
F test/shell4.test 8f6c0fce4abed19a8a7f7262517149812a04caa905d01bdc8f5e92573504b759
|
||||
F test/shell5.test 1be5454b8376e363f99cd0947ab43e1121e5b802c067d1fe7089e3461de1421d x
|
||||
F test/shell5.test 3be444397eb1e91619ce289a6216a8df9ac690cc45d5e9595f60e750a944161f x
|
||||
F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
|
||||
F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
|
||||
F test/shell8.test 388471d16e4de767333107e30653983f186232c0e863f4490bb230419e830aae
|
||||
@ -1944,8 +1944,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 433e5ead2b711d1e3b0b62cf8cb5a8a65e2474c68ef2173317ed4323fc8bdc58 bf8dbfd499e732f14c7a8efee527e8ce155937dbb2a3e85213f8aa64ac497189
|
||||
R d0a4f648a76dcc064c4b8040fefbc80a
|
||||
P 67dc59f46d742ad69742fb34540a3074af163a3f1a0f9093f83db2276bf944ca
|
||||
R ef7ea611e7a4e14ff938dd85400a84e0
|
||||
U larrybr
|
||||
Z 9500253e6d614600afa73cc694266a23
|
||||
Z 0a705a46f17a261142cf326cb58d0cbc
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
67dc59f46d742ad69742fb34540a3074af163a3f1a0f9093f83db2276bf944ca
|
||||
c626cff7f99ec502ebd46f9cdafc3d088697544ef5d6559b6b3ae85679b4f9fa
|
@ -7830,8 +7830,9 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
|
||||
* (a) The db was not initialized and zCol==0 (There are no columns.)
|
||||
* (b) zCol!=0 (Column was added, db initialized as needed.)
|
||||
* The 3rd argument, pRenamed, references an out parameter. If the
|
||||
* pointer is non-zero, its referent will be set to 1 if renaming was
|
||||
* necessary, or set to 0 if none was done.
|
||||
* pointer is non-zero, its referent will be set to a summary of renames
|
||||
* done if renaming was necessary, or set to 0 if none was done. The out
|
||||
* string (if any) must be sqlite3_free()'ed by the caller.
|
||||
*/
|
||||
#ifdef SHELL_DEBUG
|
||||
#define rc_err_oom_die(rc) \
|
||||
@ -7862,12 +7863,17 @@ static const char *zCOL_DB = ":memory:";
|
||||
# define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP)
|
||||
#endif
|
||||
|
||||
static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, int *pRenamed){
|
||||
static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, char **pzRenamed){
|
||||
/* Queries and D{D,M}L used here */
|
||||
static const char * const zTabMake = "\
|
||||
CREATE TABLE ColNames(\
|
||||
cpos INTEGER PRIMARY KEY,\
|
||||
name TEXT, nlen INT, chop INT, reps INT, suff TEXT)\
|
||||
name TEXT, nlen INT, chop INT, reps INT, suff TEXT);\
|
||||
CREATE VIEW RepeatedNames AS \
|
||||
SELECT DISTINCT t.name FROM ColNames t \
|
||||
WHERE t.name COLLATE NOCASE IN (\
|
||||
SELECT o.name FROM ColNames o WHERE o.cpos<>t.cpos\
|
||||
);\
|
||||
";
|
||||
static const char * const zTabFill = "\
|
||||
INSERT INTO ColNames(name,nlen,chop,reps,suff)\
|
||||
@ -7877,6 +7883,7 @@ INSERT INTO ColNames(name,nlen,chop,reps,suff)\
|
||||
SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\
|
||||
<count(name) FROM ColNames\
|
||||
";
|
||||
#ifdef SHELL_COLUMN_RENAME_CLEAN
|
||||
static const char * const zDedoctor = "\
|
||||
UPDATE ColNames SET chop=iif(\
|
||||
(substring(name,nlen,1) BETWEEN '0' AND '9')\
|
||||
@ -7885,6 +7892,7 @@ UPDATE ColNames SET chop=iif(\
|
||||
0\
|
||||
)\
|
||||
";
|
||||
#endif
|
||||
static const char * const zSetReps = "\
|
||||
UPDATE ColNames AS t SET reps=\
|
||||
(SELECT count(*) FROM ColNames d \
|
||||
@ -7898,11 +7906,40 @@ SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
|
||||
";
|
||||
#endif
|
||||
static const char * const zRenameRank =
|
||||
#ifndef SHELL_COLUMN_RENAME_DML
|
||||
#ifdef SHELL_COLUMN_RENAME_CLEAN
|
||||
"UPDATE ColNames AS t SET suff="
|
||||
"iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')"
|
||||
#else
|
||||
SHELL_COLUMN_RENAME_DML
|
||||
#else /* ...RENAME_MINIMAL_ONE_PASS */
|
||||
"WITH Lzn(nlz) AS (" /* Find minimum extraneous leading 0's for uniqueness */
|
||||
" SELECT 0 AS nlz"
|
||||
" UNION"
|
||||
" SELECT nlz+1 AS nlz FROM Lzn"
|
||||
" WHERE EXISTS("
|
||||
" SELECT 1"
|
||||
" FROM ColNames t, ColNames o"
|
||||
" WHERE"
|
||||
" iif(t.name IN (SELECT * FROM RepeatedNames),"
|
||||
" printf('%s"AUTOCOLUMN_SEP"%s',"
|
||||
" t.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,t.cpos),2)),"
|
||||
" t.name"
|
||||
" )"
|
||||
" ="
|
||||
" iif(o.name IN (SELECT * FROM RepeatedNames),"
|
||||
" printf('%s"AUTOCOLUMN_SEP"%s',"
|
||||
" o.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,o.cpos),2)),"
|
||||
" o.name"
|
||||
" )"
|
||||
" COLLATE NOCASE"
|
||||
" AND o.cpos<>t.cpos"
|
||||
" GROUP BY t.cpos"
|
||||
" )"
|
||||
") UPDATE Colnames AS t SET"
|
||||
" chop = 0," /* No chopping, never touch incoming names. */
|
||||
" suff = iif(name IN (SELECT * FROM RepeatedNames),"
|
||||
" printf('"AUTOCOLUMN_SEP"%s', substring("
|
||||
" printf('%.*c%0.*d',(SELECT max(nlz) FROM Lzn)+1,'0',1,t.cpos),2)),"
|
||||
" ''"
|
||||
" )"
|
||||
#endif
|
||||
;
|
||||
static const char * const zCollectVar = "\
|
||||
@ -7916,7 +7953,12 @@ FROM (\
|
||||
SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \
|
||||
FROM ColNames ORDER BY cpos\
|
||||
)";
|
||||
|
||||
static const char * const zRenamesDone =
|
||||
"SELECT group_concat("
|
||||
" printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff)),"
|
||||
" ','||x'0a')"
|
||||
"FROM ColNames WHERE suff<>'' OR chop!=0"
|
||||
;
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
assert(pDb!=0);
|
||||
@ -7926,7 +7968,8 @@ FROM (\
|
||||
if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
|
||||
#ifdef SHELL_COLFIX_DB
|
||||
if(*zCOL_DB!=':')
|
||||
sqlite3_exec(*pDb,"drop table if exists ColNames",0,0,0);
|
||||
sqlite3_exec(*pDb,"drop table if exists ColNames;"
|
||||
"drop view if exists RepeatedNames;",0,0,0);
|
||||
#endif
|
||||
rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
|
||||
rc_err_oom_die(rc);
|
||||
@ -7952,8 +7995,10 @@ FROM (\
|
||||
# define nDigits 2
|
||||
#endif
|
||||
if( hasDupes ){
|
||||
#ifdef SHELL_COLUMN_RENAME_CLEAN
|
||||
rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
|
||||
rc_err_oom_die(rc);
|
||||
#endif
|
||||
rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0);
|
||||
rc_err_oom_die(rc);
|
||||
rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0);
|
||||
@ -7972,7 +8017,17 @@ FROM (\
|
||||
}else{
|
||||
zColsSpec = 0;
|
||||
}
|
||||
if( pRenamed!=0 ) *pRenamed = hasDupes;
|
||||
if( pzRenamed!=0 ){
|
||||
if( !hasDupes ) *pzRenamed = 0;
|
||||
else{
|
||||
sqlite3_finalize(pStmt);
|
||||
if( SQLITE_OK==sqlite3_prepare_v2(*pDb, zRenamesDone, -1, &pStmt, 0)
|
||||
&& SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
*pzRenamed = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
|
||||
}else
|
||||
*pzRenamed = 0;
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_close(*pDb);
|
||||
*pDb = 0;
|
||||
@ -8929,17 +8984,18 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"",
|
||||
zSchema, zTable);
|
||||
sqlite3 *dbCols = 0;
|
||||
int renamed = 0;
|
||||
char *zRenames = 0;
|
||||
char *zColDefs;
|
||||
while( xRead(&sCtx) ){
|
||||
zAutoColumn(sCtx.z, &dbCols, 0);
|
||||
if( sCtx.cTerm!=sCtx.cColSep ) break;
|
||||
}
|
||||
zColDefs = zAutoColumn(0, &dbCols, &renamed);
|
||||
if( renamed!=0 ){
|
||||
zColDefs = zAutoColumn(0, &dbCols, &zRenames);
|
||||
if( zRenames!=0 ){
|
||||
utf8_printf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
|
||||
"Columns renamed during .import %s due to duplicates.\n",
|
||||
sCtx.zFile);
|
||||
"Columns renamed during .import %s due to duplicates:\n"
|
||||
"%s\n", sCtx.zFile, zRenames);
|
||||
sqlite3_free(zRenames);
|
||||
}
|
||||
assert(dbCols==0);
|
||||
if( zColDefs==0 ){
|
||||
|
@ -484,20 +484,26 @@ CREATE TABLE t8(a, b, c);
|
||||
do_test shell5-5.1 {
|
||||
set out [open shell5.csv w]
|
||||
fconfigure $out -translation lf
|
||||
puts $out {"","x","x","y","z","z_0"}
|
||||
puts $out {0,"ex2","ex3","wye4","zee5","zee6"}
|
||||
puts $out {"","x","x","y","z","z_0","z_5","z"}
|
||||
puts $out {0,"x2","x3","y4","z5","z6","z7","z8"}
|
||||
close $out
|
||||
forcedelete test.db
|
||||
catchcmd test.db {.import -csv shell5.csv t1
|
||||
.mode line
|
||||
SELECT * FROM t1;}
|
||||
} {1 { ? = 0
|
||||
x_2 = ex2
|
||||
x_3 = ex3
|
||||
y = wye4
|
||||
z_5 = zee5
|
||||
z_6 = zee6
|
||||
Columns renamed during .import shell5.csv due to duplicates.}}
|
||||
x_02 = x2
|
||||
x_03 = x3
|
||||
y = y4
|
||||
z_05 = z5
|
||||
z_0 = z6
|
||||
z_5 = z7
|
||||
z_08 = z8
|
||||
Columns renamed during .import shell5.csv due to duplicates:
|
||||
"x" to "x_02",
|
||||
"x" to "x_03",
|
||||
"z" to "z_05",
|
||||
"z" to "z_08"}}
|
||||
|
||||
do_test shell5-5.1 {
|
||||
set out [open shell5.csv w]
|
||||
@ -513,6 +519,10 @@ SELECT * FROM t1;}
|
||||
cow_2 = lll
|
||||
CoW_3 = ulu
|
||||
cOw_4 = lul
|
||||
Columns renamed during .import shell5.csv due to duplicates.}}
|
||||
Columns renamed during .import shell5.csv due to duplicates:
|
||||
"COW" to "COW_1",
|
||||
"cow" to "cow_2",
|
||||
"CoW" to "CoW_3",
|
||||
"cOw" to "cOw_4"}}
|
||||
|
||||
finish_test
|
||||
|
Loading…
x
Reference in New Issue
Block a user