Improve INSERT column parsing and diagnostics.

This commit is contained in:
Jeff Garzik 2019-01-05 11:18:25 -05:00
parent 6546207fe2
commit a5e6e0715c
4 changed files with 32 additions and 7 deletions

3
exec.c
View File

@ -462,12 +462,13 @@ void sqlp_ins_dup_update(struct psql_state *pstate, int n_assn)
intout("INSERT DUP-ONUPDATE", n_assn);
}
void sqlp_insert(struct psql_state *pstate, int opts, int n_vals, const char *tbl_name)
void sqlp_insert(struct psql_state *pstate, int opts, int n_vals, int n_cols, const char *tbl_name)
{
json_t *obj = json_object();
json_object_set_new(obj, "op", json_string("INSERT"));
json_object_set_new(obj, "opts", json_integer(opts));
json_object_set_new(obj, "n_vals", json_integer(n_vals));
json_object_set_new(obj, "n_cols", json_integer(n_cols));
json_object_set_new(obj, "tbl_name", json_string(tbl_name));
print_and_free(obj);
}

View File

@ -90,6 +90,7 @@ function parseRecordStream(recs)
tbl_name: current.tbl_name,
opts: current.opts,
values: [],
columns: [],
};
var wantVals = current.n_vals;
@ -97,11 +98,34 @@ function parseRecordStream(recs)
const val = stk.pop();
assert(val !== undefined);
objInsert.values.push(val);
objInsert.values.unshift(val.values);
}
var wantCols = current.n_cols;
assert(wantCols <= 1);
if (wantCols > 0) {
const val = stk.pop();
assert(val !== undefined);
objInsert.columns = val;
}
stk.push(objInsert);
} else if ('INSERT-COLS' in current) {
var arrCols = [];
var wantVals = current['INSERT-COLS'];
while (wantVals-- > 0) {
const val = stk.pop();
assert(val !== undefined);
arrCols.unshift(val['COLUMN']);
}
stk.push(arrCols);
} else if (current.op && current.op == 'CREATE-DB') {
var objDb = {
verb: 'CREATE_DATABASE',

View File

@ -106,7 +106,7 @@ extern void sqlp_index_hint(struct psql_state *pstate, int n_indexed, int opts);
extern void sqlp_ins_cols(struct psql_state *pstate, int n_cols);
extern void sqlp_ins_default(struct psql_state *pstate);
extern void sqlp_ins_dup_update(struct psql_state *pstate, int n_assn);
extern void sqlp_insert(struct psql_state *pstate, int opts, int n_vals, const char *tbl_name);
extern void sqlp_insert(struct psql_state *pstate, int opts, int n_vals, int n_cols, const char *tbl_name);
extern void sqlp_insert_assn(struct psql_state *pstate, int opts, int n_assn, const char *tbl_name);
extern void sqlp_insert_sel(struct psql_state *pstate, int opts, const char *tbl_name);
extern void sqlp_into(struct psql_state *pstate, int n_cols);

8
sql.y
View File

@ -346,7 +346,7 @@ struct psql_state;
%type <intval> delete_opts delete_list
%type <intval> insert_opts insert_vals insert_vals_list
%type <intval> insert_asgn_list opt_if_not_exists update_opts update_asgn_list
%type <intval> opt_if_exists table_list
%type <intval> opt_if_exists table_list opt_col_names
%type <intval> opt_temporary opt_length opt_binary opt_uz enum_list
%type <intval> column_atts data_type opt_ignore_replace create_col_list
@ -569,7 +569,7 @@ stmt: insert_stmt { sqlp_stmt(pstate); }
insert_stmt: INSERT insert_opts opt_into NAME
opt_col_names
VALUES insert_vals_list
opt_ondupupdate { sqlp_insert(pstate, $2, $7, $4); free($4); }
opt_ondupupdate { sqlp_insert(pstate, $2, $7, $5, $4); free($4); }
;
opt_ondupupdate: /* nil */
@ -586,8 +586,8 @@ insert_opts: /* nil */ { $$ = 0; }
opt_into: INTO | /* nil */
;
opt_col_names: /* nil */
| '(' column_list ')' { sqlp_ins_cols(pstate, $2); }
opt_col_names: /* nil */ { $$ = 0; }
| '(' column_list ')' { sqlp_ins_cols(pstate, $2); $$ = 1; }
;
insert_vals_list: '(' insert_vals ')' { sqlp_values(pstate, $2); $$ = 1; }