seqbulk *seqbulk_create(sql_sequence *seq, BUN cnt) { seqbulk *sb = MNEW(seqbulk); store_sequence *s; node *n = NULL; if (!sb) return NULL; store_lock(); sb->seq = seq; sb->cnt = cnt; sb->save = 0; for ( n = sql_seqs->h; n; n = n ->next ) { s = n->data; if (s->seqid == seq->base.id) break; } if (!n) { s = sql_create_sequence(seq); if (!s) { _DELETE(sb); store_unlock(); return NULL; } list_append(sql_seqs, s); } else { s = n->data; } sb->internal_seq = s; return sb; }
static node * node_create(sql_allocator *sa, void *data) { node *n = (sa)?SA_NEW(sa, node):MNEW(node); n->next = NULL; n->data = data; return n; }
list * list_create(fdestroy destroy) { list *l = MNEW(list); l->sa = NULL; l->destroy = destroy; l->h = l->t = NULL; l->cnt = 0; l->expected_cnt = 0; l->ht = NULL; MT_lock_init(&l->ht_lock, "sa_ht_lock"); return l; }
/* lock is held */ static store_sequence * sql_create_sequence(sql_sequence *seq ) { lng id = 0; store_sequence *s = NULL; s = MNEW(store_sequence); s -> seqid = seq->base.id; s -> called = 0; s -> cur = seq->start; s -> cached = seq->start; if (seq->base.flag == TR_OLD && logger_funcs.get_sequence(seq->base.id, &id )) s->cached = id; s -> cur = s->cached; return s; }
static void bc_escape_analysis_init(bc_escape_analysis_t *be, methodinfo *m, bool verbose, int depth) { u2 p; int l; int a; u1 *ite; u1 t; unsigned n; int ret_val_is_adr; be->method = m; be->stack = DNEW(op_stack_t); op_stack_init(be->stack, m->maxstack, &(be->fatal_error)); be->basicblocks = DNEW(basicblock_work_list_t); basicblock_work_list_init(be->basicblocks); be->local_to_adr_param_size = m->parseddesc->paramslots; be->local_to_adr_param = DMNEW(op_stack_slot_t, m->parseddesc->paramslots); /* Count number of address parameters a. */ for (p = 0, l = 0, a = 0; p < m->parseddesc->paramcount; ++p) { t = m->parseddesc->paramtypes[p].type; if (t == TYPE_ADR) { be->local_to_adr_param[l] = op_stack_slot_create_param(a); a += 1; l += 1; } else if (IS_2_WORD_TYPE(t)) { be->local_to_adr_param[l] = OP_STACK_SLOT_UNKNOWN; be->local_to_adr_param[l + 1] = OP_STACK_SLOT_UNKNOWN; l += 2; } else { be->local_to_adr_param[l] = OP_STACK_SLOT_UNKNOWN; l += 1; } } assert(l == be->local_to_adr_param_size); ret_val_is_adr = m->parseddesc->returntype.type == TYPE_ADR ? 1 : 0; /* Allocate param_escape on heap. */ be->param_escape_size = a; n = a + ret_val_is_adr; if (n == 0) { /* Use some non-NULL value. */ be->param_escape = (u1 *)1; } else { be->param_escape = MNEW(u1, n); be->param_escape += ret_val_is_adr; } for (ite = be->param_escape; ite != be->param_escape + n; ++ite) { *ite = escape_state_to_u1(ESCAPE_NONE); } if (ret_val_is_adr) { be->param_escape[-1] = escape_state_to_u1(ESCAPE_NONE); } be->adr_param_dirty = DNEW(bit_vector_t); bit_vector_init(be->adr_param_dirty, a); be->adr_param_returned= DNEW(bit_vector_t); bit_vector_init(be->adr_param_returned, a); be->non_escaping_adr_params = be->param_escape_size; #if BC_ESCAPE_VERBOSE be->verbose = verbose; #endif be->depth = depth; be->fatal_error = false; }
/* * BEWARE: SQLstatementIntern only commits after all statements found * in expr are executed, when autocommit mode is enabled. * * The tricky part for this statement is to ensure that the SQL statement * is executed within the client context specified. This leads to context juggling. */ str SQLstatementIntern(Client c, str *expr, str nme, int execute, bit output, res_table **result) { int status = 0; int err = 0; mvc *o, *m; int ac, sizevars, topvars; sql_var *vars; int oldvtop, oldstop = 1; buffer *b; char *n; stream *buf; str msg = MAL_SUCCEED; backend *be, *sql = (backend *) c->sqlcontext; size_t len = strlen(*expr); #ifdef _SQL_COMPILE mnstr_printf(c->fdout, "#SQLstatement:%s\n", *expr); #endif if (!sql) { msg = SQLinitEnvironment(c, NULL, NULL, NULL); sql = (backend *) c->sqlcontext; } if (msg){ GDKfree(msg); throw(SQL, "SQLstatement", "Catalogue not available"); } initSQLreferences(); m = sql->mvc; ac = m->session->auto_commit; o = MNEW(mvc); if (!o) throw(SQL, "SQLstatement", "Out of memory"); *o = *m; /* create private allocator */ m->sa = NULL; SQLtrans(m); status = m->session->status; m->type = Q_PARSE; be = sql; sql = backend_create(m, c); sql->output_format = be->output_format; m->qc = NULL; m->caching = 0; m->user_id = m->role_id = USER_MONETDB; if (result) m->reply_size = -2; /* do not cleanup, result tables */ /* mimick a client channel on which the query text is received */ b = (buffer *) GDKmalloc(sizeof(buffer)); n = GDKmalloc(len + 1 + 1); strncpy(n, *expr, len); n[len] = '\n'; n[len + 1] = 0; len++; buffer_init(b, n, len); buf = buffer_rastream(b, "sqlstatement"); scanner_init(&m->scanner, bstream_create(buf, b->len), NULL); m->scanner.mode = LINE_N; bstream_next(m->scanner.rs); m->params = NULL; m->argc = 0; m->session->auto_commit = 0; if (!m->sa) m->sa = sa_create(); /* * System has been prepared to parse it and generate code. * Scan the complete string for SQL statements, stop at the first error. */ c->sqlcontext = sql; while (msg == MAL_SUCCEED && m->scanner.rs->pos < m->scanner.rs->len) { sql_rel *r; stmt *s; MalStkPtr oldglb = c->glb; if (!m->sa) m->sa = sa_create(); m->sym = NULL; if ((err = sqlparse(m)) || /* Only forget old errors on transaction boundaries */ (mvc_status(m) && m->type != Q_TRANS) || !m->sym) { if (!err) err = mvc_status(m); if (*m->errstr) msg = createException(PARSE, "SQLparser", "%s", m->errstr); *m->errstr = 0; sqlcleanup(m, err); execute = 0; if (!err) continue; assert(c->glb == 0 || c->glb == oldglb); /* detect leak */ c->glb = oldglb; goto endofcompile; } /* * We have dealt with the first parsing step and advanced the input reader * to the next statement (if any). * Now is the time to also perform the semantic analysis, * optimize and produce code. * We don't search the cache for a previous incarnation yet. */ MSinitClientPrg(c, "user", nme); oldvtop = c->curprg->def->vtop; oldstop = c->curprg->def->stop; r = sql_symbol2relation(m, m->sym); s = sql_relation2stmt(m, r); #ifdef _SQL_COMPILE mnstr_printf(c->fdout, "#SQLstatement:\n"); #endif scanner_query_processed(&(m->scanner)); if (s == 0 || (err = mvc_status(m))) { msg = createException(PARSE, "SQLparser", "%s", m->errstr); handle_error(m, c->fdout, status); sqlcleanup(m, err); /* restore the state */ MSresetInstructions(c->curprg->def, oldstop); freeVariables(c, c->curprg->def, c->glb, oldvtop); c->curprg->def->errors = 0; assert(c->glb == 0 || c->glb == oldglb); /* detect leak */ c->glb = oldglb; goto endofcompile; } /* generate MAL code */ if (backend_callinline(sql, c, s, 1) == 0) addQueryToCache(c); else err = 1; if (err ||c->curprg->def->errors) { /* restore the state */ MSresetInstructions(c->curprg->def, oldstop); freeVariables(c, c->curprg->def, c->glb, oldvtop); c->curprg->def->errors = 0; msg = createException(SQL, "SQLparser", "Errors encountered in query"); assert(c->glb == 0 || c->glb == oldglb); /* detect leak */ c->glb = oldglb; goto endofcompile; } #ifdef _SQL_COMPILE mnstr_printf(c->fdout, "#result of sql.eval()\n"); printFunction(c->fdout, c->curprg->def, 0, c->listing); #endif if (execute) { MalBlkPtr mb = c->curprg->def; if (!output) sql->out = NULL; /* no output */ msg = runMAL(c, mb, 0, 0); MSresetInstructions(mb, oldstop); freeVariables(c, mb, NULL, oldvtop); } sqlcleanup(m, 0); if (!execute) { assert(c->glb == 0 || c->glb == oldglb); /* detect leak */ c->glb = oldglb; goto endofcompile; } #ifdef _SQL_COMPILE mnstr_printf(c->fdout, "#parse/execute result %d\n", err); #endif assert(c->glb == 0 || c->glb == oldglb); /* detect leak */ c->glb = oldglb; } if (m->results && result) { /* return all results sets */ *result = m->results; m->results = NULL; } /* * We are done; a MAL procedure resides in the cache. */ endofcompile: if (execute) MSresetInstructions(c->curprg->def, 1); c->sqlcontext = be; backend_destroy(sql); GDKfree(n); GDKfree(b); bstream_destroy(m->scanner.rs); if (m->sa) sa_destroy(m->sa); m->sa = NULL; m->sym = NULL; /* variable stack maybe resized, ie we need to keep the new stack */ status = m->session->status; sizevars = m->sizevars; topvars = m->topvars; vars = m->vars; *m = *o; _DELETE(o); m->sizevars = sizevars; m->topvars = topvars; m->vars = vars; m->session->status = status; m->session->auto_commit = ac; return msg; }