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, NULL, 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) { if (rel) return sql_error(sql, 02, "IF THEN ELSE: No SELECT statements allowed within the IF condition"); return NULL; } return exp_if( sql->sa, cond, ifstmts, elsestmts); } return NULL; }
static sql_exp * rel_psm_if_then_else( mvc *sql, sql_subtype *res, list *restypelist, 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, restypelist, n->data.lval, NULL, is_func); n = n->next; elsestmts = psm_if_then_else( sql, res, restypelist, n, is_func); if (sql->session->status || !cond || !ifstmts) return NULL; if (rel) { sql_exp *er = exp_rel(sql, rel); list *b = sa_list(sql->sa); append(b, er); append(b, exp_if(sql->sa, cond, ifstmts, elsestmts)); return exp_rel(sql, rel_psm_block(sql->sa, b)); } return exp_if( sql->sa, cond, ifstmts, elsestmts); } return NULL; }
/* [ 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, list *restypelist, 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, restypelist, n->data.lval, n->next->data.sval, is_func); if (sql->session->status || !cond || !whilestmts) return NULL; if (rel) { sql_exp *er = exp_rel(sql, rel); list *b = sa_list(sql->sa); append(b, er); append(b, exp_while( sql->sa, cond, whilestmts )); return exp_rel(sql, rel_psm_block(sql->sa, b)); } 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, list *restypelist, dnode *elseif, int is_func) { if (!elseif) return NULL; assert(elseif->type == type_symbol); if (elseif->data.sym && elseif->data.sym->token == SQL_IF) { sql_exp *cond; list *ifstmts, *elsestmts; dnode *n = elseif->data.sym->data.lval->h; sql_rel *rel = NULL; cond = rel_logical_value_exp(sql, &rel, n->data.sym, sql_sel); n = n->next; ifstmts = sequential_block(sql, res, restypelist, n->data.lval, NULL, is_func); n = n->next; elsestmts = psm_if_then_else( sql, res, restypelist, n, is_func); if (sql->session->status || !cond || !ifstmts) return NULL; if (rel) { sql_exp *er = exp_rel(sql, rel); list *b = sa_list(sql->sa); append(b, er); append(b, exp_if(sql->sa, cond, ifstmts, elsestmts)); return b; } 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, restypelist, e->data.lval, NULL, is_func); } }
/* 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}; sql_exp *v = rel_value_exp(sql, &rel, case_value, sql_sel, ek); if (!v) return NULL; if (rel) return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition"); if (else_statements) { else_stmt = sequential_block( sql, res, NULL, else_statements, NULL, is_func); if (!else_stmt) return NULL; } n = when_statements->h; while(n) { dnode *m = n->data.sym->data.lval->h; sql_exp *cond=0, *when_value = rel_value_exp(sql, &rel, m->data.sym, sql_sel, ek); list *if_stmts = NULL; sql_exp *case_stmt = NULL; if (!when_value || rel || (cond = rel_binop_(sql, v, when_value, NULL, "=", card_value)) == NULL || (if_stmts = sequential_block( sql, res, NULL, m->next->data.lval, NULL, is_func)) == NULL ) { if (rel) return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition"); return NULL; } case_stmt = exp_if(sql->sa, cond, if_stmts, NULL); list_append(case_stmts, case_stmt); n = n->next; } if (else_stmt) list_merge(case_stmts, else_stmt, NULL); return case_stmts; } else { /* case 2 */ dnode *n = case_when; dlist *whenlist = n->data.lval; dlist *else_statements = n->next->data.lval; list *else_stmt = NULL; if (else_statements) { else_stmt = sequential_block( sql, res, NULL, else_statements, NULL, is_func); if (!else_stmt) return NULL; } n = whenlist->h; while(n) { dnode *m = n->data.sym->data.lval->h; sql_rel *rel = NULL; sql_exp *cond = rel_logical_value_exp(sql, &rel, m->data.sym, sql_sel); list *if_stmts = NULL; sql_exp *case_stmt = NULL; if (!cond || rel || (if_stmts = sequential_block( sql, res, NULL, m->next->data.lval, NULL, is_func)) == NULL ) { if (rel) return sql_error(sql, 02, "CASE: No SELECT statements allowed within the CASE condition"); return NULL; } case_stmt = exp_if(sql->sa, cond, if_stmts, NULL); list_append(case_stmts, case_stmt); n = n->next; } if (else_stmt) list_merge(case_stmts, else_stmt, NULL); return case_stmts; } }