Changeset: 03df27701cf7 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=03df27701cf7 Modified Files: sql/server/rel_psm.c sql/server/rel_psm.h Branch: default Log Message:
add missing files diffs (truncated from 1174 to 300 lines): diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c new file mode 100644 --- /dev/null +++ b/sql/server/rel_psm.c @@ -0,0 +1,1120 @@ +/* + * The contents of this file are subject to the MonetDB Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.monetdb.org/Legal/MonetDBLicense + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + * License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is the MonetDB Database System. + * + * The Initial Developer of the Original Code is CWI. + * Portions created by CWI are Copyright (C) 1997-July 2008 CWI. + * Copyright August 2008-2012 MonetDB B.V. + * All Rights Reserved. + */ + + +#include "monetdb_config.h" +#include "rel_psm.h" +#include "rel_bin.h" +#include "rel_semantic.h" +#include "rel_schema.h" +#include "rel_select.h" +#include "rel_exp.h" +#include "rel_updates.h" +#include "sql_privileges.h" + +static sql_rel * +rel_psm_block(sql_allocator *sa, list *l) +{ + if (l) { + sql_rel *r = rel_create(sa); + + r->op = op_ddl; + r->flag = DDL_PSM; + r->exps = l; + return r; + } + return NULL; +} + +static sql_rel * +rel_psm_stmt(sql_allocator *sa, sql_exp *e) +{ + if (e) { + list *l = sa_list(sa); + + list_append(l, e); + return rel_psm_block(sa, l); + } + return NULL; +} + +/* SET variable = value */ +static sql_exp * +psm_set_exp(mvc *sql, dnode *n) +{ + exp_kind ek = {type_value, card_value, FALSE}; + char *name = n->data.sval; + symbol *val = n->next->data.sym; + sql_exp *e = NULL; + int level = 0, is_last = 0; + sql_subtype *tpe = NULL; + sql_rel *rel = NULL; + sql_exp *res = NULL; + + /* name can be + 'parameter of the function' (ie in the param list) + or a local or global variable, declared earlier + */ + + /* check if variable is known from the stack */ + if (!stack_find_var(sql, name)) { + sql_arg *a = sql_bind_param(sql, name); + + if (!a) /* not parameter, ie local var ? */ + return sql_error(sql, 01, "Variable %s unknown", name); + tpe = &a->type; + } else { + tpe = stack_find_type(sql, name); + } + + e = rel_value_exp2(sql, &rel, val, sql_sel, ek, &is_last); + if (!e || (rel && e->card > CARD_AGGR)) + return NULL; + + level = stack_find_frame(sql, name); + e = rel_check_type(sql, tpe, e, type_cast); + if (!e) + return NULL; + if (rel) { + sql_exp *er = exp_rel(sql->sa, rel); + list *b = sa_list(sql->sa); + + append(b, er); + append(b, exp_set(sql->sa, name, e, level)); + res = exp_rel(sql->sa, rel_psm_block(sql->sa, b)); + } else { + res = exp_set(sql->sa, name, e, level); + } + return res; +} + +static sql_exp* +rel_psm_call(mvc * sql, symbol *se) +{ + sql_subtype *t; + sql_exp *res = NULL; + exp_kind ek = {type_value, card_none, FALSE}; + sql_rel *rel = NULL; + + res = rel_value_exp(sql, &rel, se, sql_sel, ek); + if (!res || rel || ((t=exp_subtype(res)) && t->type)) /* only procedures */ + return sql_error(sql, 01, "function calls are ignored"); + return res; +} + +static list * +rel_psm_declare(mvc *sql, dnode *n) +{ + list *l = sa_list(sql->sa); + + while(n) { /* list of 'identfiers with type' */ + dnode *ids = n->data.sym->data.lval->h->data.lval->h; + sql_subtype *ctype = &n->data.sym->data.lval->h->next->data.typeval; + while(ids) { + char *name = ids->data.sval; + sql_exp *r = NULL; + + /* check if we overwrite a scope local variable declare x; declare x; */ + if (frame_find_var(sql, name)) { + return sql_error(sql, 01, + "Variable '%s' allready declared", name); + } + /* variables are put on stack, + * TODO make sure on plan/explain etc they only + * exist during plan phase */ + stack_push_var(sql, name, ctype); + r = exp_var(sql->sa, sa_strdup(sql->sa, name), ctype, sql->frame); + append(l, r); + ids = ids->next; + } + n = n->next; + } + return l; +} + +static sql_exp * +rel_psm_declare_table(mvc *sql, dnode *n) +{ + sql_rel *rel = NULL; + dlist *qname = n->next->data.lval; + char *name = qname_table(qname); + char *sname = qname_schema(qname); + sql_subtype ctype = *sql_bind_localtype("bat"); + + if (sname) /* not allowed here */ + return sql_error(sql, 02, "DECLARE TABLE: qualified name allowed"); + if (frame_find_var(sql, name)) + return sql_error(sql, 01, "Variable '%s' allready declared", name); + + assert(n->next->next->next->type == type_int); + + rel = rel_create_table(sql, cur_schema(sql), SQL_DECLARED_TABLE, NULL, name, n->next->next->data.sym, n->next->next->next->data.i_val, NULL); + + if (!rel || rel->op != op_ddl || rel->flag != DDL_CREATE_TABLE) + return NULL; + + ctype.comp_type = (sql_table*)((atom*)((sql_exp*)rel->exps->t->data)->l)->data.val.pval; + stack_push_rel_var(sql, name, rel_dup(rel), &ctype); + return exp_var(sql->sa, sa_strdup(sql->sa, name), &ctype, sql->frame); +} + +/* [ label: ] + while (cond) do + statement_list + end [ label ] + currently we only parse the labels, they cannot be used as there is no + + support for LEAVE and ITERATE (sql multi-level break and continue) + */ +static sql_exp * +rel_psm_while_do( mvc *sql, sql_subtype *res, dnode *w, int is_func ) +{ + if (!w) + return NULL; + if (w->type == type_symbol) { + sql_exp *cond; + list *whilestmts; + dnode *n = w; + sql_rel *rel = NULL; + + cond = rel_logical_value_exp(sql, &rel, n->data.sym, sql_sel); + n = n->next; + whilestmts = sequential_block(sql, res, n->data.lval, n->next->data.sval, is_func); + + if (sql->session->status || !cond || !whilestmts || rel) + return NULL; + return exp_while( sql->sa, cond, whilestmts ); + } + return NULL; +} + + +/* if (cond) then statement_list + [ elseif (cond) then statement_list ]* + [ else statement_list ] + end if + */ +static list * +psm_if_then_else( mvc *sql, sql_subtype *res, dnode *elseif, int is_func) +{ + if (!elseif) + return NULL; + if (elseif->next && elseif->type == type_symbol) { /* if or elseif */ + sql_exp *cond; + list *ifstmts, *elsestmts; + dnode *n = elseif; + sql_rel *rel = NULL; + + cond = rel_logical_value_exp(sql, &rel, n->data.sym, sql_sel); + n = n->next; + ifstmts = sequential_block(sql, res, n->data.lval, NULL, is_func); + n = n->next; + elsestmts = psm_if_then_else( sql, res, n, is_func); + + if (sql->session->status || !cond || !ifstmts || rel) + return NULL; + return append(sa_list(sql->sa), exp_if( sql->sa, cond, ifstmts, elsestmts)); + } else { /* else */ + symbol *e = elseif->data.sym; + + if (e==NULL || (e->token != SQL_ELSE)) + return NULL; + return sequential_block( sql, res, e->data.lval, NULL, is_func); + } +} + +static sql_exp * +rel_psm_if_then_else( mvc *sql, sql_subtype *res, dnode *elseif, int is_func) +{ + if (!elseif) + return NULL; + if (elseif->next && elseif->type == type_symbol) { /* if or elseif */ + sql_exp *cond; + list *ifstmts, *elsestmts; + dnode *n = elseif; + sql_rel *rel = NULL; + + cond = rel_logical_value_exp(sql, &rel, n->data.sym, sql_sel); + n = n->next; + ifstmts = sequential_block(sql, res, n->data.lval, NULL, is_func); + n = n->next; + elsestmts = psm_if_then_else( sql, res, n, is_func); + if (sql->session->status || !cond || !ifstmts || rel) + return NULL; + return exp_if( sql->sa, cond, ifstmts, elsestmts); + } + return NULL; +} + +/* 1 + CASE + WHEN search_condition THEN statements + [ WHEN search_condition THEN statements ] + [ ELSE statements ] + END CASE + + 2 + CASE case_value + WHEN when_value THEN statements + [ WHEN when_value THEN statements ] + [ ELSE statements ] + END CASE + */ +static list * +rel_psm_case( mvc *sql, sql_subtype *res, dnode *case_when, int is_func ) +{ + list *case_stmts = sa_list(sql->sa); + + if (!case_when) + return NULL; + + /* case 1 */ + if (case_when->type == type_symbol) { + dnode *n = case_when; + symbol *case_value = n->data.sym; + dlist *when_statements = n->next->data.lval; + dlist *else_statements = n->next->next->data.lval; + list *else_stmt = NULL; + sql_rel *rel = NULL; + exp_kind ek = {type_value, card_value, FALSE}; _______________________________________________ Checkin-list mailing list Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list