@@ -967,9 +967,9 @@ csv_vtab_connect(sqlite3* db, void *aux, int argc, const char * const *argv,
967967 sqlite3_vtab * * vtabp , char * * errp )
968968{
969969 csv_file * csv ;
970- int rc = SQLITE_ERROR , i , ncnames , row1 ;
970+ int rc = SQLITE_ERROR , i , k , ncnames , row1 , * colmap = 0 ;
971971 char * * cnames , * schema = 0 , * * nargv ;
972- csv_vtab * vtab ;
972+ csv_vtab * vtab = 0 ;
973973
974974 if (argc < 4 ) {
975975 * errp = sqlite3_mprintf ("input file name missing" );
@@ -991,6 +991,12 @@ csv_vtab_connect(sqlite3* db, void *aux, int argc, const char * const *argv,
991991 sqlite3_free (nargv [i ]);
992992 }
993993 }
994+ if (vtab ) {
995+ sqlite3_free (vtab );
996+ }
997+ if (colmap ) {
998+ sqlite3_free (colmap );
999+ }
9941000 return rc ;
9951001 }
9961002 if (!csv -> sep && !csv -> quot ) {
@@ -1028,7 +1034,14 @@ csv_vtab_connect(sqlite3* db, void *aux, int argc, const char * const *argv,
10281034 ncnames = csv_ncols (csv );
10291035 cnames = 0 ;
10301036 }
1031- vtab = sqlite3_malloc (sizeof (csv_vtab ) + ncnames );
1037+ colmap = sqlite3_malloc (sizeof (int ) * ncnames );
1038+ if (!colmap ) {
1039+ csv_close (csv );
1040+ * errp = sqlite3_mprintf ("out of memory" );
1041+ goto cleanup ;
1042+ }
1043+ memset (colmap , 0 , sizeof (int ) * ncnames );
1044+ vtab = sqlite3_malloc (sizeof (csv_vtab ) + ncnames );
10321045 if (!vtab ) {
10331046 csv_close (csv );
10341047 * errp = sqlite3_mprintf ("out of memory" );
@@ -1044,12 +1057,38 @@ csv_vtab_connect(sqlite3* db, void *aux, int argc, const char * const *argv,
10441057 }
10451058 vtab -> csv = csv ;
10461059 append (& schema , "CREATE TABLE x(" , 0 );
1060+ for (i = 0 ; cnames && (i < ncnames ); i ++ ) {
1061+ if (!cnames [i ] || (cnames [i ][0 ] == '\0' )) {
1062+ continue ;
1063+ }
1064+ k = strlen (cnames [i ]);
1065+ if ((k > 7 ) && (strncasecmp ("column_" , cnames [i ], 7 ) == 0 )) {
1066+ char c ;
1067+
1068+ if (sscanf (cnames [i ] + 7 , "%d%c" , & k , & c ) == 1 ) {
1069+ colmap [i ] = k ;
1070+ }
1071+ }
1072+ }
10471073 for (i = 0 ; i < ncnames ; i ++ ) {
10481074 vtab -> coltypes [i ] = SQLITE_TEXT ;
1049- if (!cnames || !cnames [i ]) {
1075+ if (!cnames || !cnames [i ] || (cnames [i ][0 ] == '\0' )) {
1076+ int want = i + 1 ;
10501077 char colname [64 ];
10511078
1052- sprintf (colname , "column_%d" , i + 1 );
1079+ while (1 ) {
1080+ for (k = 0 ; k < ncnames ; k ++ ) {
1081+ if ((k != i ) && (colmap [k ] == want )) {
1082+ want ++ ;
1083+ break ;
1084+ }
1085+ }
1086+ if (k >= ncnames ) {
1087+ colmap [i ] = want ;
1088+ break ;
1089+ }
1090+ }
1091+ sprintf (colname , "column_%d" , colmap [i ]);
10531092 append (& schema , colname , '"' );
10541093 } else if (row1 > 0 ) {
10551094 append (& schema , cnames [i ], '"' );
@@ -1082,13 +1121,13 @@ csv_vtab_connect(sqlite3* db, void *aux, int argc, const char * const *argv,
10821121 rc = sqlite3_declare_vtab (db , schema );
10831122 if (rc != SQLITE_OK ) {
10841123 csv_close (csv );
1085- sqlite3_free (vtab );
10861124 * errp = sqlite3_mprintf ("table definition failed, error %d, "
10871125 "schema '%s'" , rc , schema );
10881126 goto cleanup ;
10891127 }
10901128 * vtabp = & vtab -> vtab ;
10911129 * errp = 0 ;
1130+ vtab = 0 ;
10921131 goto cleanup ;
10931132}
10941133
@@ -1162,7 +1201,7 @@ csv_vtab_bestindex(sqlite3_vtab *vtab, sqlite3_index_info *info)
11621201static int
11631202csv_vtab_open (sqlite3_vtab * vtab , sqlite3_vtab_cursor * * cursorp )
11641203{
1165- csv_cursor * cur = sqlite3_malloc (sizeof (* cur ));
1204+ csv_cursor * cur = sqlite3_malloc (sizeof (* cur ));
11661205 csv_vtab * tab = (csv_vtab * ) vtab ;
11671206
11681207 if (!cur ) {
@@ -1351,7 +1390,7 @@ static void
13511390csv_import_func (sqlite3_context * ctx , int argc , sqlite3_value * * argv )
13521391{
13531392 csv_file * csv ;
1354- int rc , i , ncnames , row1 , convert = 0 , useargs = 0 ;
1393+ int rc , i , k , ncnames , row1 , convert = 0 , useargs = 0 , * colmap = 0 ;
13551394 char * tname , * fname , * sql = 0 , * * cnames , * coltypes = 0 ;
13561395 sqlite3 * db = (sqlite3 * ) sqlite3_user_data (ctx );
13571396 sqlite3_stmt * stmt = 0 ;
@@ -1380,8 +1419,8 @@ csv_import_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
13801419 sqlite3_finalize (stmt );
13811420 }
13821421 append_free (& sql );
1383- if (coltypes ) {
1384- sqlite3_free (coltypes );
1422+ if (colmap ) {
1423+ sqlite3_free (colmap );
13851424 }
13861425 if (csv ) {
13871426 csv_close (csv );
@@ -1478,14 +1517,30 @@ csv_import_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
14781517 /* create new table */
14791518 sqlite3_finalize (stmt );
14801519 stmt = 0 ;
1481- coltypes = sqlite3_malloc (ncnames );
1482- if (!coltypes ) {
1520+ colmap = ( int * ) sqlite3_malloc (ncnames + sizeof ( int ) * ncnames );
1521+ if (!colmap ) {
14831522 goto oom ;
14841523 }
1524+ memset (colmap , 0 , sizeof (int ) * ncnames );
1525+ coltypes = (char * ) (colmap + ncnames );
14851526 append (& sql , "CREATE TABLE " , 0 );
14861527 append (& sql , tname , '"' );
14871528 append (& sql , "(" , 0 );
1529+ for (i = 0 ; cnames && (i < ncnames ); i ++ ) {
1530+ if (!cnames [i ] || (cnames [i ][0 ] == '\0' )) {
1531+ continue ;
1532+ }
1533+ k = strlen (cnames [i ]);
1534+ if ((k > 7 ) && (strncasecmp ("column_" , cnames [i ], 7 ) == 0 )) {
1535+ char c ;
1536+
1537+ if (sscanf (cnames [i ] + 7 , "%d%c" , & k , & c ) == 1 ) {
1538+ colmap [i ] = k ;
1539+ }
1540+ }
1541+ }
14881542 for (i = 0 ; i < ncnames ; i ++ ) {
1543+ int want = i + 1 ;
14891544 char colname [64 ];
14901545
14911546 coltypes [i ] = SQLITE_TEXT ;
@@ -1505,7 +1560,19 @@ csv_import_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
15051560 coltypes [i ] = maptype (type );
15061561 } else if (!cnames || !cnames [i ]) {
15071562defcol :
1508- sprintf (colname , "column_%d" , i + 1 );
1563+ while (1 ) {
1564+ for (k = 0 ; k < ncnames ; k ++ ) {
1565+ if ((k != i ) && (colmap [k ] == want )) {
1566+ want ++ ;
1567+ break ;
1568+ }
1569+ }
1570+ if (k >= ncnames ) {
1571+ colmap [i ] = want ;
1572+ break ;
1573+ }
1574+ }
1575+ sprintf (colname , "column_%d" , colmap [i ]);
15091576 append (& sql , colname , '"' );
15101577 } else if (row1 > 0 ) {
15111578 append (& sql , cnames [i ], '"' );
0 commit comments