Changeset: 937ffd54b9c4 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=937ffd54b9c4 Modified Files: sql/backends/monet5/UDF/pyapi/connection.c sql/backends/monet5/UDF/pyapi/connection.h sql/backends/monet5/UDF/pyapi/pyloader.c sql/backends/monet5/sql.c sql/backends/monet5/sql.h sql/include/sql_catalog.h sql/server/rel_psm.c sql/server/rel_select.c sql/server/rel_select.h sql/server/rel_updates.c Branch: default Log Message:
Also work with copy from loader. diffs (truncated from 511 to 300 lines): diff --git a/sql/backends/monet5/UDF/pyapi/connection.c b/sql/backends/monet5/UDF/pyapi/connection.c --- a/sql/backends/monet5/UDF/pyapi/connection.c +++ b/sql/backends/monet5/UDF/pyapi/connection.c @@ -16,6 +16,7 @@ CREATE_SQL_FUNCTION_PTR(void, SQLdestroyResult); CREATE_SQL_FUNCTION_PTR(str, SQLstatementIntern); CREATE_SQL_FUNCTION_PTR(str, create_table_from_emit); +CREATE_SQL_FUNCTION_PTR(str, append_to_table_from_emit); static PyObject *_connection_execute(Py_ConnectionObject *self, PyObject *args) { @@ -189,6 +190,12 @@ str _connection_create_table(Client cntx return (*create_table_from_emit_ptr)(cntxt, sname, tname, columns, ncols); } +str _connection_append_to_table(Client cntxt, char *sname, char *tname, + sql_emit_col *columns, size_t ncols) +{ + return (*append_to_table_from_emit_ptr)(cntxt, sname, tname, columns, ncols); +} + PyObject *Py_Connection_Create(Client cntxt, bit mapped, QueryStruct *query_ptr, int query_sem) { @@ -217,6 +224,7 @@ str _connection_init(void) LOAD_SQL_FUNCTION_PTR(SQLdestroyResult); LOAD_SQL_FUNCTION_PTR(SQLstatementIntern); LOAD_SQL_FUNCTION_PTR(create_table_from_emit); + LOAD_SQL_FUNCTION_PTR(append_to_table_from_emit); if (msg != MAL_SUCCEED) { return msg; diff --git a/sql/backends/monet5/UDF/pyapi/connection.h b/sql/backends/monet5/UDF/pyapi/connection.h --- a/sql/backends/monet5/UDF/pyapi/connection.h +++ b/sql/backends/monet5/UDF/pyapi/connection.h @@ -51,6 +51,8 @@ str _connection_init(void); str _connection_query(Client cntxt, char *query, res_table **result); str _connection_create_table(Client cntxt, char *sname, char *tname, sql_emit_col *columns, size_t ncols); +str _connection_append_to_table(Client cntxt, char *sname, char *tname, + sql_emit_col *columns, size_t ncols); void _connection_cleanup_result(void *output); #endif /* _LOOPBACK_QUERY_ */ diff --git a/sql/backends/monet5/UDF/pyapi/pyloader.c b/sql/backends/monet5/UDF/pyapi/pyloader.c --- a/sql/backends/monet5/UDF/pyapi/pyloader.c +++ b/sql/backends/monet5/UDF/pyapi/pyloader.c @@ -46,7 +46,7 @@ PYFUNCNAME(PyAPIevalLoader)(Client cntxt char *pycall = NULL; str *args = NULL; char *msg = MAL_SUCCEED; - node *argnode, *n; + node *argnode, *n, *n2; PyObject *pArgs = NULL, *pEmit = NULL, *pConnection; // this is going to be the parameter tuple PyObject *code_object = NULL; @@ -54,9 +54,9 @@ PYFUNCNAME(PyAPIevalLoader)(Client cntxt bool gstate = 0; int unnamedArgs = 0; int argcount = pci->argc; - int retvals = pci->retc; bool create_table = false; BUN nval = 0; + int ncols = 0; char *loader_additional_args[] = {"_emit", "_conn"}; @@ -150,21 +150,31 @@ PYFUNCNAME(PyAPIevalLoader)(Client cntxt // TODO deal with sql types } + getArg(pci, 0) = TYPE_void; if (sqlmorefun->colnames) { n = sqlmorefun->colnames->h; - cols = GDKzalloc(sizeof(sql_emit_col) * pci->retc); + n2 = sqlmorefun->coltypes->h; + ncols = list_length(sqlmorefun->colnames); + if (ncols == 0) { + msg = createException(MAL, "pyapi.eval_loader", + "No columns supplied."); + goto wrapup; + } + cols = GDKzalloc(sizeof(sql_emit_col) * ncols); if (!cols) { msg = createException(MAL, "pyapi.eval_loader", MAL_MALLOC_FAIL "column list"); goto wrapup; } + assert(list_length(sqlmorefun->colnames) == list_length(sqlmorefun->coltypes)); i = 0; while (n) { - assert(i < pci->retc); + sql_subtype* tpe = (sql_subtype*) n2->data; cols[i].name = GDKstrdup(*((char **)n->data)); n = n->next; cols[i].b = - COLnew(0, getBatType(getArgType(mb, pci, i)), 0, TRANSIENT); + COLnew(0, tpe->type->localtype, 0, TRANSIENT); + n2 = n2->next; cols[i].b->tnil = 0; cols[i].b->tnonil = 0; i++; @@ -172,14 +182,13 @@ PYFUNCNAME(PyAPIevalLoader)(Client cntxt } else { // set the return value to the correct type to prevent MAL layers from // complaining - getArg(pci, 0) = TYPE_void; cols = NULL; - retvals = 0; + ncols = 0; create_table = true; } pConnection = Py_Connection_Create(cntxt, 0, 0, 0); - pEmit = PyEmit_Create(cols, retvals); + pEmit = PyEmit_Create(cols, ncols); if (!pConnection || !pEmit) { msg = createException(MAL, "pyapi.eval_loader", MAL_MALLOC_FAIL "python object"); @@ -255,12 +264,12 @@ PYFUNCNAME(PyAPIevalLoader)(Client cntxt cols = ((PyEmitObject *)pEmit)->cols; nval = ((PyEmitObject *)pEmit)->nvals; - retvals = (int)((PyEmitObject *)pEmit)->ncols; + ncols = (int)((PyEmitObject *)pEmit)->ncols; Py_DECREF(pFunc); Py_DECREF(pArgs); pArgs = NULL; - if (retvals == 0) { + if (ncols == 0) { msg = createException(MAL, "pyapi.eval_loader", "No elements emitted by the loader."); goto wrapup; @@ -269,34 +278,26 @@ PYFUNCNAME(PyAPIevalLoader)(Client cntxt gstate = Python_ReleaseGIL(gstate); + for (i = 0; i < ncols; i++) { + BAT *b = cols[i].b; + BATsetcount(b, nval); + b->tkey = 0; + b->tsorted = 0; + b->trevsorted = 0; + } if (!create_table) { - for (i = 0; i < retvals; i++) { - BAT *b = cols[i].b; - BATsetcount(b, nval); - b->tkey = 0; - b->tsorted = 0; - b->trevsorted = 0; - - *getArgReference_bat(stk, pci, i) = b->batCacheid; - cols[i].b = NULL; - BBPkeepref(b->batCacheid); - } + msg = _connection_append_to_table(cntxt, sqlmorefun->sname, + sqlmorefun->tname, cols, ncols); + goto wrapup; } else { - for (i = 0; i < retvals; i++) { - BAT *b = cols[i].b; - BATsetcount(b, nval); - b->tkey = 0; - b->tsorted = 0; - b->trevsorted = 0; - } msg = _connection_create_table(cntxt, sqlmorefun->sname, - sqlmorefun->tname, cols, retvals); + sqlmorefun->tname, cols, ncols); goto wrapup; } wrapup: if (cols) { - for (i = 0; i < retvals; i++) { + for (i = 0; i < ncols; i++) { if (cols[i].b) { BBPunfix(cols[i].b->batCacheid); } 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 @@ -365,21 +365,21 @@ create_table_or_view(mvc *sql, char *sna str create_table_from_emit(Client cntxt, char *sname, char *tname, sql_emit_col *columns, size_t ncols) { - size_t i; - sql_table *t; - sql_schema *s; - mvc *sql = NULL; - str msg = MAL_SUCCEED; + size_t i; + sql_table *t; + sql_schema *s; + mvc *sql = NULL; + str msg = MAL_SUCCEED; if ((msg = getSQLContext(cntxt, NULL, &sql, NULL)) != NULL) return msg; if ((msg = checkSQLContext(cntxt)) != NULL) return msg; - /* for some reason we don't have an allocator here so make one */ + /* for some reason we don't have an allocator here, so make one */ sql->sa = sa_create(); - if (!sname) + if (!sname) sname = "sys"; if (!(s = mvc_bind_schema(sql, sname))) { msg = sql_error(sql, 02, "3F000!CREATE TABLE: no such schema '%s'", sname); @@ -390,45 +390,94 @@ create_table_from_emit(Client cntxt, cha goto cleanup; } - for(i = 0; i < ncols; i++) { - BAT *b = columns[i].b; - sql_subtype *tpe = sql_bind_localtype(ATOMname(b->ttype)); - sql_column *col = NULL; - - if (!tpe) { - msg = sql_error(sql, 02, "3F000!CREATE TABLE: could not find type for column"); - goto cleanup; - } - - col = mvc_create_column(sql, t, columns[i].name, tpe); - if (!col) { - msg = sql_error(sql, 02, "3F000!CREATE TABLE: could not create column %s", columns[i].name); - goto cleanup; - } + for(i = 0; i < ncols; i++) { + BAT *b = columns[i].b; + sql_subtype *tpe = sql_bind_localtype(ATOMname(b->ttype)); + sql_column *col = NULL; + + if (!tpe) { + msg = sql_error(sql, 02, "3F000!CREATE TABLE: could not find type for column"); + goto cleanup; } - msg = create_table_or_view(sql, sname, t->base.name, t, 0); + + col = mvc_create_column(sql, t, columns[i].name, tpe); + if (!col) { + msg = sql_error(sql, 02, "3F000!CREATE TABLE: could not create column %s", columns[i].name); + goto cleanup; + } + } + msg = create_table_or_view(sql, sname, t->base.name, t, 0); + if (msg != MAL_SUCCEED) { + goto cleanup; + } + t = mvc_bind_table(sql, s, tname); + if (!t) { + msg = sql_error(sql, 02, "3F000!CREATE TABLE: could not bind table %s", tname); + goto cleanup; + } + for(i = 0; i < ncols; i++) { + BAT *b = columns[i].b; + sql_column *col = NULL; + + col = mvc_bind_column(sql,t, columns[i].name); + if (!col) { + msg = sql_error(sql, 02, "3F000!CREATE TABLE: could not bind column %s", columns[i].name); + goto cleanup; + } + msg = mvc_append_column(sql->session->tr, col, b); if (msg != MAL_SUCCEED) { goto cleanup; } - t = mvc_bind_table(sql, s, tname); - if (!t) { + } + +cleanup: + sa_destroy(sql->sa); + sql->sa = NULL; + return msg; +} + +str +append_to_table_from_emit(Client cntxt, char *sname, char *tname, sql_emit_col *columns, size_t ncols) +{ + size_t i; + sql_table *t; + sql_schema *s; + mvc *sql = NULL; + str msg = MAL_SUCCEED; + + if ((msg = getSQLContext(cntxt, NULL, &sql, NULL)) != NULL) + return msg; + if ((msg = checkSQLContext(cntxt)) != NULL) + return msg; + + /* for some reason we don't have an allocator here, so make one */ + sql->sa = sa_create(); + + if (!sname) + sname = "sys"; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list