Changeset: eb9a9582ba77 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=eb9a9582ba77
Modified Files:
sql/backends/monet5/sql.c
sql/common/sql_types.c
sql/server/rel_updates.c
sql/server/sql_parser.y
sql/server/sql_scan.c
Branch: fixed-width-format
Log Message:
COPY INTO table FWF (1,2,3); now works
diffs (267 lines):
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -3410,10 +3410,16 @@ mvc_import_table_wrap(Client cntxt, MalB
lng *offset = getArgReference_lng(stk, pci, pci->retc + 7);
int *locked = getArgReference_int(stk, pci, pci->retc + 8);
int *besteffort = getArgReference_int(stk, pci, pci->retc + 9);
+ char *fixed_widths = NULL;
str msg = MAL_SUCCEED;
bstream *s = NULL;
stream *ss;
+ if (pci->argc - pci->retc > 10) {
+ fixed_widths = *getArgReference_str(stk, pci, pci->retc + 10);
+
+ }
+
(void) mb; /* NOT USED */
if ((msg = checkSQLContext(cntxt)) != NULL)
return msg;
@@ -3483,14 +3489,29 @@ mvc_import_table_wrap(Client cntxt, MalB
return msg;
}
GDKfree(fn);
-
- // FIXME
- if (GDKgetenv_isyes("testfwf")) {
- fprintf(stderr, "### FWF IMPORT ON %s ###\n", *fname);
- size_t *widths = malloc(sizeof(size_t)*400);
- size_t i = 0;
- widths[i++] = 2; widths[i++] = 2; widths[i++] = 9;
widths[i++] = 12; widths[i++] = 8; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 8;
widths[i++] = 8; widths[i++] = 30; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 9; widths[i++] = 4; widths[i++] = 4; widths[i++] = 2;
widths[i++] = 8; widths[i++] = 9; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 9; widths[i++] = 9; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 9; widths[i++] = 9; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 9; widths[i++] = 9; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 9; widths[i++] = 9; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 9; widths[i++] = 2; widths[i++] = 2; widths[i++] = 4;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; wi
dths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 3; widths[i++] = 2; widths[i++] = 2; widths[i++] = 4;
widths[i++] = 2; widths[i++] = 8; widths[i++] = 2; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i+
+] = 2; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] =
3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 9; widths[i++] = 9;
widths[i++] = 9; widths[i++] = 8; widths[i++] = 8; widths[i++] = 8;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 9; widths[i++] = 9; widths[i++] = 9;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 9; widths[i++] = 9; widths[i++] = 9;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 9; widths[i++] = 9;
widths[i++] = 9; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 9; widths[i++] = 9; width
s[i++] = 9; widths[i++] = 4; widths[i++] = 4; widths[i++] = 4; widths[i++]
= 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++]
= 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; w
idths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 12; widths[i++] = 12; widths[i++] = 12; widths[i++] = 8;
widths[i++] = 8; widths[i++] = 8; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 3; widths[i++] = 3; widths[i++] = 3;
widths[i++] = 3; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 2;
widths[i++] = 2; widths[i++] = 2; widths[i++] = 2; widths[i++] = 40;
- ss = stream_fwf_create(ss, 376, widths, ' ');
+ if (fixed_widths) {
+ size_t ncol = 0, current_width_entry = 0, i;
+ size_t *widths;
+ char* val_start = fixed_widths;
+ size_t width_len = strlen(fixed_widths);
+ for (i = 0; i < width_len; i++) {
+ if (fixed_widths[i] == '|') {
+ ncol++;
+ }
+ }
+ widths = malloc(sizeof(size_t) * ncol);
+ if (!widths) {
+ // TODO: free other stuff
+ throw(MAL, "sql.copy_from", MAL_MALLOC_FAIL);
+ }
+ for (i = 0; i < width_len; i++) {
+ if (fixed_widths[i] == '|') {
+ fixed_widths[i] = '\0';
+ widths[current_width_entry++] =
(size_t) atoll(val_start);
+ val_start = fixed_widths + i + 1;
+ }
+ }
+ ss = stream_fwf_create(ss, ncol, widths, ' ');
}
#if SIZEOF_VOID_P == 4
s = bstream_create(ss, 0x20000);
diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -1760,9 +1760,9 @@ sqltypeinit( sql_allocator *sa)
sres, FALSE, F_FUNC, SCALE_FIX);
}
sres = create_arg(sa, NULL, sql_create_subtype(sa, TABLE, 0, 0),
ARG_OUT);
- /* copyfrom fname (arg 9) */
+ /* copyfrom fname (arg 10) */
f=sql_create_func_(sa, "copyfrom", "sql", "copy_from",
- list_append( list_append( list_append( list_append(
list_append(list_append (list_append (list_append(list_append(sa_list(sa),
+ list_append( list_append( list_append( list_append(
list_append(list_append (list_append
(list_append(list_append(list_append(sa_list(sa),
create_arg(sa, NULL, sql_create_subtype(sa, STR, 0, 0),
ARG_IN)),
create_arg(sa, NULL, sql_create_subtype(sa, STR, 0, 0),
ARG_IN)),
create_arg(sa, NULL, sql_create_subtype(sa, STR, 0, 0),
ARG_IN)),
@@ -1771,7 +1771,8 @@ sqltypeinit( sql_allocator *sa)
create_arg(sa, NULL, sql_create_subtype(sa, STR, 0, 0),
ARG_IN)),
create_arg(sa, NULL, sql_create_subtype(sa, LNG, 0, 0),
ARG_IN)),
create_arg(sa, NULL, sql_create_subtype(sa, LNG, 0, 0),
ARG_IN)),
- create_arg(sa, NULL, sql_create_subtype(sa, INT, 0, 0),
ARG_IN)), sres, FALSE, F_UNION, SCALE_FIX);
+ create_arg(sa, NULL, sql_create_subtype(sa, INT, 0, 0),
ARG_IN)),
+ create_arg(sa, NULL, sql_create_subtype(sa, STR, 0, 0),
ARG_IN)), sres, FALSE, F_UNION, SCALE_FIX);
f->varres = 1;
/* bincopyfrom */
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -1136,7 +1136,7 @@ table_column_types(sql_allocator *sa, sq
}
static sql_rel *
-rel_import(mvc *sql, sql_table *t, char *tsep, char *rsep, char *ssep, char
*ns, char *filename, lng nr, lng offset, int locked, int best_effort)
+rel_import(mvc *sql, sql_table *t, char *tsep, char *rsep, char *ssep, char
*ns, char *filename, lng nr, lng offset, int locked, int best_effort, dlist
*fwf_widths)
{
sql_rel *res;
list *exps, *args;
@@ -1144,7 +1144,8 @@ rel_import(mvc *sql, sql_table *t, char
sql_subtype tpe;
sql_exp *import;
sql_schema *sys = mvc_bind_schema(sql, "sys");
- sql_subfunc *f = sql_find_func(sql->sa, sys, "copyfrom", 9, F_UNION,
NULL);
+ sql_subfunc *f = sql_find_func(sql->sa, sys, "copyfrom", 10, F_UNION,
NULL);
+ char* fwf_string = NULL;
if (!f) /* we do expect copyfrom to be there */
return NULL;
@@ -1157,16 +1158,37 @@ rel_import(mvc *sql, sql_table *t, char
exp_atom_str(sql->sa, ssep, &tpe)),
exp_atom_str(sql->sa, ns, &tpe));
+ if (fwf_widths && dlist_length(fwf_widths) > 0) {
+ dnode *dn;
+ int ncol = 0;
+ fwf_string = GDKmalloc(20 * dlist_length(fwf_widths) + 1); // a
64 bit int needs 19 characters in decimal representation plus the separator
+ if (!fwf_string) {
+ return NULL;
+ }
+ char* fwf_string_cur = fwf_string;
+ for (dn = fwf_widths->h; dn; dn = dn->next) {
+ fwf_string_cur += sprintf(fwf_string_cur, LLFMT"|",
dn->data.l_val);
+ ncol++;
+ }
+ if(list_length(f->res) != ncol) {
+ (void) sql_error(sql, 02, "3F000!COPY INTO: fixed width
import for %d columns but %d widths given.", list_length(f->res), ncol);
+ return NULL;
+ }
+ *fwf_string_cur = '\0';
+ }
+
append( args, exp_atom_str(sql->sa, filename, &tpe));
import = exp_op(sql->sa,
append(
append(
append(
- append( args,
- exp_atom_lng(sql->sa, nr)),
- exp_atom_lng(sql->sa, offset)),
- exp_atom_int(sql->sa, locked)),
- exp_atom_int(sql->sa, best_effort)),
f);
+ append(
+ append( args,
+ exp_atom_lng(sql->sa, nr)),
+ exp_atom_lng(sql->sa, offset)),
+ exp_atom_int(sql->sa, locked)),
+ exp_atom_int(sql->sa,
best_effort)),
+ exp_atom_str(sql->sa,
fwf_string, &tpe)), f);
exps = new_exp_list(sql->sa);
for (n = t->columns.set->h; n; n = n->next) {
@@ -1179,7 +1201,7 @@ rel_import(mvc *sql, sql_table *t, char
}
static sql_rel *
-copyfrom(mvc *sql, dlist *qname, dlist *columns, dlist *files, dlist *headers,
dlist *seps, dlist *nr_offset, str null_string, int locked, int best_effort,
int constraint)
+copyfrom(mvc *sql, dlist *qname, dlist *columns, dlist *files, dlist *headers,
dlist *seps, dlist *nr_offset, str null_string, int locked, int best_effort,
int constraint, dlist *fwf_widths)
{
sql_rel *rel = NULL;
char *sname = qname_schema(qname);
@@ -1194,7 +1216,6 @@ copyfrom(mvc *sql, dlist *qname, dlist *
lng offset = (nr_offset)?nr_offset->h->next->data.l_val:0;
list *collist;
int reorder = 0;
-
assert(!nr_offset || nr_offset->h->type == type_lng);
assert(!nr_offset || nr_offset->h->next->type == type_lng);
if (sname && !(s=mvc_bind_schema(sql, sname))) {
@@ -1296,7 +1317,7 @@ copyfrom(mvc *sql, dlist *qname, dlist *
return sql_error(sql, 02, "COPY INTO: filename
must "
"have absolute path: %s",
fname);
- nrel = rel_import(sql, nt, tsep, rsep, ssep, ns, fname,
nr, offset, locked, best_effort);
+ nrel = rel_import(sql, nt, tsep, rsep, ssep, ns, fname,
nr, offset, locked, best_effort, fwf_widths);
if (!rel)
rel = nrel;
@@ -1306,7 +1327,7 @@ copyfrom(mvc *sql, dlist *qname, dlist *
return rel;
}
} else {
- rel = rel_import(sql, nt, tsep, rsep, ssep, ns, NULL, nr,
offset, locked, best_effort);
+ rel = rel_import(sql, nt, tsep, rsep, ssep, ns, NULL, nr,
offset, locked, best_effort, NULL);
}
if (headers) {
dnode *n;
@@ -1581,7 +1602,8 @@ rel_updates(mvc *sql, symbol *s)
l->h->next->next->next->next->next->next->data.sval,
l->h->next->next->next->next->next->next->next->data.i_val,
l->h->next->next->next->next->next->next->next->next->data.i_val,
-
l->h->next->next->next->next->next->next->next->next->next->data.i_val);
+
l->h->next->next->next->next->next->next->next->next->next->data.i_val,
+
l->h->next->next->next->next->next->next->next->next->next->next->data.lval);
sql->type = Q_UPDATE;
}
break;
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -342,6 +342,8 @@ int yydebug=1;
assignment_commalist
opt_column_list
column_commalist_parens
+ opt_fwf_widths
+ fwf_widthlist
opt_header_list
header_list
header
@@ -599,7 +601,7 @@ SQLCODE SQLERROR UNDER WHENEVER
%token CASE WHEN THEN ELSE NULLIF COALESCE IF ELSEIF WHILE DO
%token ATOMIC BEGIN END
-%token COPY RECORDS DELIMITERS STDIN STDOUT
+%token COPY RECORDS DELIMITERS STDIN STDOUT FWF
%token INDEX
%token AS TRIGGER OF BEFORE AFTER ROW STATEMENT sqlNEW OLD EACH REFERENCING
@@ -2481,7 +2483,7 @@ opt_to_savepoint:
;
copyfrom_stmt:
- COPY opt_nr INTO qname opt_column_list FROM string_commalist
opt_header_list opt_seps opt_null_string opt_locked opt_best_effort
opt_constraint
+ COPY opt_nr INTO qname opt_column_list FROM string_commalist
opt_header_list opt_seps opt_null_string opt_locked opt_best_effort
opt_constraint opt_fwf_widths
{ dlist *l = L();
append_list(l, $4);
append_list(l, $5);
@@ -2493,6 +2495,7 @@ copyfrom_stmt:
append_int(l, $11);
append_int(l, $12);
append_int(l, $13);
+ append_list(l, $14);
$$ = _symbol_create_list( SQL_COPYFROM, l ); }
| COPY opt_nr INTO qname opt_column_list FROM STDIN opt_header_list
opt_seps opt_null_string opt_locked opt_best_effort opt_constraint
{ dlist *l = L();
@@ -2532,7 +2535,22 @@ copyfrom_stmt:
append_string(l, $6);
$$ = _symbol_create_list( SQL_COPYTO, l ); }
;
-
+
+
+
+opt_fwf_widths:
+ /* empty */ { $$ = NULL; }
+| FWF '(' fwf_widthlist ')' { $$ = $3; }
+
+ ;
+
+ fwf_widthlist:
+ poslng { $$ = append_lng(L(), $1); }
+ | fwf_widthlist ',' poslng
+ { $$ = append_lng($1, $3); }
+ ;
+
+
opt_header_list:
/* empty */ { $$ = NULL; }
| '(' header_list ')' { $$ = $2; }
diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c
--- a/sql/server/sql_scan.c
+++ b/sql/server/sql_scan.c
@@ -176,6 +176,8 @@ scanner_init_keywords(void)
keywords_insert("FOR", FOR);
keywords_insert("FOREIGN", FOREIGN);
keywords_insert("FROM", FROM);
+ keywords_insert("FWF", FWF);
+
keywords_insert("REFERENCES", REFERENCES);
keywords_insert("MATCH", MATCH);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list