Changeset: e03fa66a96b5 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e03fa66a96b5 Modified Files: sql/server/rel_graph.c sql/server/sql_scan.c Branch: graph1 Log Message:
Semantic: support for CHEAPEST SUM(e: expr) Explicitly bind the edge table from the argument of CHEAPEST SUM, identified by the string preceding the colon (:). diffs (192 lines): diff --git a/sql/server/rel_graph.c b/sql/server/rel_graph.c --- a/sql/server/rel_graph.c +++ b/sql/server/rel_graph.c @@ -109,7 +109,6 @@ sql_rel* rel_graph_reaches(mvc *sql, sql static bool error_reported(mvc* sql){ return (sql->session->status < 0); } - static sql_exp* bindg_ret(mvc *sql, sql_exp* bind1, sql_exp* bind2){ if (error_reported(sql)){ // an error already occurred return NULL; @@ -122,60 +121,71 @@ static sql_exp* bindg_ret(mvc *sql, sql_ } } -static sql_exp* bindg_exp(mvc *sql, sql_exp *exp, dlist *parse_tree){ - graph_join *g =NULL; - sql_exp* e =NULL; - exp_kind exp_kind_value = {type_value, card_column, TRUE}; +static sql_exp* bindg_filter_graph(mvc *sql, sql_exp *exp, dlist *parse_tree){ const char* table_ref = NULL; // the table referred (optional) symbol* expr_weight = NULL; // the expression inside CHEAPEST SUM ( ... ); + graph_join* g = NULL; + sql_exp* e = NULL; + exp_kind exp_kind_value = {type_value, card_column, TRUE}; assert(exp && "Expected an expression"); + assert(exp->type == e_cmp && get_cmp(exp) == cmp_filter_graph && "Expected a graph filter exp~"); assert(parse_tree && "The input argument parse_tree is NULL"); assert(parse_tree->cnt == 2 && "Expected two nodes in the root of the parse tree"); - if(exp->type != e_cmp || get_cmp(exp) != cmp_filter_graph){ - // this is not a graph join, move along - return NULL; - } - - (void) sql; - (void) g; - (void) e; - (void) exp_kind_value; - (void) table_ref; - (void) expr_weight; + g = exp->f; table_ref = parse_tree->h->data.sval; expr_weight = parse_tree->h->next->data.sym; + if (table_ref){ // use the table name to refer to the edge table + const char* tname = rel_name(g->edges); - return NULL; + // TODO shall we consider the schema as well? + assert(tname != NULL); + if(strcmp(tname, table_ref) == 0){ + // force the binding against this relation + e = rel_value_exp(sql, &(g->edges), expr_weight, sql_sel, exp_kind_value); + if(!e){ return sql_error(sql, 02, "Cannot bind the cheapest sum expression in the subquery `%s'", tname); } + } + } else { // table name not given + // try to bind the expression a la `best effort' + e = rel_value_exp(sql, &(g->edges), expr_weight, sql_sel, exp_kind_value); + } -// g = exp->f; -// -// // try to bind the expression -// e = rel_value_exp(sql, &(g->edges), sym, sql_sel, exp_kind_value); -// if(!e){ return NULL; } -// -// // an expression has already been bound -// if(g->cost){ -// return sql_error(sql, 02, "TODO: At the moment you cannot bind multiple CHEAPEST SUM expression against the same join"); -// } -// -// // found it! -// g->cost = exp_label(sql->sa, e, ++sql->label); -// return g->cost; + // did we bind our parse tree? + if(e){ + if(g->cost){ // existing limitation, an expression has already been bound + return sql_error(sql, 02, "TODO: At the moment you cannot bind multiple CHEAPEST SUM expression against the same join"); + } + + // found it! + g->cost = exp_label(sql->sa, e, ++sql->label); + return g->cost; + + } else { // no, we didn't bind it + return NULL; + } } +static sql_exp* bindg_exp(mvc *sql, sql_exp *exp, dlist *parse_tree){ + if(exp->type == e_cmp && get_cmp(exp) == cmp_filter_graph){ + // ok this is a graph join + return bindg_filter_graph(sql, exp, parse_tree); + } else { + // this is not a graph join, move along + return NULL; + } +} -static sql_exp* bindg_exps(mvc *sql, list *exps, dlist *sym){ +static sql_exp* bindg_exps(mvc *sql, list *exps, dlist *parse_tree){ sql_exp *result = NULL; // edge case if(!exps || error_reported(sql)) return NULL; for(node* n = exps->h; n; n = n->next){ - sql_exp *bound = bindg_exp(sql, n->data, sym); + sql_exp *bound = bindg_exp(sql, n->data, parse_tree); result = bindg_ret(sql, result, bound); if(error_reported(sql)) return NULL; // ERROR! => stop processing } @@ -183,7 +193,7 @@ static sql_exp* bindg_exps(mvc *sql, lis return result; } -static sql_exp* bindg_rel(mvc *sql, sql_rel* relation, dlist *sym){ +static sql_exp* bindg_rel(mvc *sql, sql_rel* relation, dlist *parse_tree){ // edge case if(!relation || error_reported(sql)) return NULL; @@ -197,20 +207,20 @@ static sql_exp* bindg_rel(mvc *sql, sql_ case op_join: { sql_exp *exp1 = NULL, *exp2 = NULL, *exp3 = NULL, *ret = NULL; - exp1 = bindg_rel(sql, relation->l, sym); - exp2 = bindg_rel(sql, relation->r, sym); + exp1 = bindg_rel(sql, relation->l, parse_tree); + exp2 = bindg_rel(sql, relation->r, parse_tree); ret = bindg_ret(sql, exp1, exp2); - exp3 = bindg_exps(sql, relation->exps, sym); + exp3 = bindg_exps(sql, relation->exps, parse_tree); return bindg_ret(sql, ret, exp3); } break; case op_select: { - sql_exp* exp1 = bindg_exps(sql, relation->exps, sym); - sql_exp* exp2 = bindg_rel(sql, relation->l, sym); + sql_exp* exp1 = bindg_exps(sql, relation->exps, parse_tree); + sql_exp* exp2 = bindg_rel(sql, relation->l, parse_tree); return bindg_ret(sql, exp1, exp2); } break; case op_groupby: - // move up the tree - return bindg_rel(sql, relation->l, sym); + // move up in the tree + return bindg_rel(sql, relation->l, parse_tree); default: return NULL; } @@ -218,23 +228,15 @@ static sql_exp* bindg_rel(mvc *sql, sql_ return NULL; // silent the warning } - sql_exp* rel_graph_cheapest_sum(mvc *sql, sql_rel **rel, symbol *sym, int context){ sql_exp* exp_bound = NULL; sql_exp* result = NULL; + assert(sym->data.lval != NULL && "CHEAPEST SUM: empty parse tree"); + // Check the context is the SELECT clause if(context != sql_sel){ - sql_error(sql, 02, "CHEAPEST SUM is only allowed inside the SELECT clause"); - return NULL; - } - - // Check whether an argument has been specified - if(!sym->data.lval){ - // TODO: actually this case is not part of the parser language, i.e. it never occurs - // perhaps it should be implicitly treated as CHEAPEST SUM (1) ? - sql_error(sql, 02, "Empty argument for CHEAPEST SUM"); - return NULL; + return sql_error(sql, 02, "CHEAPEST SUM is only allowed inside the SELECT clause"); } // Find the relation where the sub the expression binds to diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c --- a/sql/server/sql_scan.c +++ b/sql/server/sql_scan.c @@ -1097,6 +1097,9 @@ int scanner_symbol(mvc * c, int cur) utf8_putchar(lc, cur); return scanner_token(lc, '|'); } + case ':': /* CHEAPEST SUM (e: expr) */ + lc->started = 1; + return scanner_token(lc, ':'); } (void)sql_error( c, 3, "unexpected symbol (%lc)", (wint_t) cur); return LEX_ERROR; _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list