Changeset: 242cc2e0c7e5 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=242cc2e0c7e5 Modified Files: monetdb5/modules/mal/mal_weld.c sql/backends/monet5/rel_weld.c Branch: rel-weld Log Message:
rel_weld: check for nil in aggregations diffs (116 lines): diff --git a/monetdb5/modules/mal/mal_weld.c b/monetdb5/modules/mal/mal_weld.c --- a/monetdb5/modules/mal/mal_weld.c +++ b/monetdb5/modules/mal/mal_weld.c @@ -26,6 +26,15 @@ *(TYPE *)(*ADDR) = *(TYPE *)VALUE; /* set */ \ *ADDR += sizeof(TYPE); /* increase */ +struct weldMinMax { + char i8min, i8max; + int i32min, i32max; + long i64min, i64max; + float f32min, f32max; + double f64min, f64max; +} weldMinMaxInst = {SCHAR_MIN, SCHAR_MAX, INT_MIN, INT_MAX, LLONG_MIN, + LLONG_MAX, FLT_MIN, FLT_MAX, DBL_MIN, DBL_MAX}; + void getOrSetStructMember(char **addr, int type, const void *value, int op) { if (type == TYPE_bte) { getOrSetStructMemberImpl(addr, char, value, op); @@ -201,6 +210,9 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS } } headerLen += sprintf(program + headerLen, + "i8MIN:i8, i8MAX:i8, i32MIN:i32, i32MAX:i32, i64MIN:i64, i64MAX:i64, " + "f32MIN:f32, f32MAX:f32, f64MIN:f64, f64MAX:f64,"); + headerLen += sprintf(program + headerLen, "i8nil:i8, i32nil:i32, oidnil:i64, i64nil:i64, f32nil:f32, f64nil:f64,"); program[0] = '|'; @@ -258,6 +270,16 @@ WeldRun(Client cntxt, MalBlkPtr mb, MalS } } } + getOrSetStructMember(&inputPtr, TYPE_bte, &weldMinMaxInst.i8min, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_bte, &weldMinMaxInst.i8max, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_int, &weldMinMaxInst.i32min, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_int, &weldMinMaxInst.i32max, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_lng, &weldMinMaxInst.i64min, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_lng, &weldMinMaxInst.i64max, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_flt, &weldMinMaxInst.f32min, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_flt, &weldMinMaxInst.f32max, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_dbl, &weldMinMaxInst.f64min, OP_SET); + getOrSetStructMember(&inputPtr, TYPE_dbl, &weldMinMaxInst.f64max, OP_SET); getOrSetStructMember(&inputPtr, TYPE_bte, &bte_nil, OP_SET); getOrSetStructMember(&inputPtr, TYPE_int, &int_nil, OP_SET); getOrSetStructMember(&inputPtr, TYPE_lng, &lng_nil, OP_SET); diff --git a/sql/backends/monet5/rel_weld.c b/sql/backends/monet5/rel_weld.c --- a/sql/backends/monet5/rel_weld.c +++ b/sql/backends/monet5/rel_weld.c @@ -178,6 +178,32 @@ get_weld_func(sql_subfunc *f) { } static str +get_identity(sql_allocator *sa, str weld_func, str weld_type, int type) { + char identity[64]; + int len = 0; + if (strcmp(weld_func, "+") == 0) { + len += sprintf(identity + len, "0"); + if (strcmp(weld_type, "f32") == 0 || strcmp(weld_type, "f64") == 0) { + len += sprintf(identity + len, ".0"); + } + len += sprintf(identity + len, "%s", getWeldTypeSuffix(type)); + } else if (strcmp(weld_func, "*") == 0) { + len += sprintf(identity + len, "1"); + if (strcmp(weld_type, "f32") == 0 || strcmp(weld_type, "f64") == 0) { + len += sprintf(identity + len, ".0"); + } + len += sprintf(identity + len, "%s", getWeldTypeSuffix(type)); + } else if (strcmp(weld_func, "min") == 0) { + len += sprintf(identity, "MAX%s", weld_type); + } else if (strcmp(weld_func, "max") == 0) { + len += sprintf(identity + len, "MIN%s", weld_type); + } else { + return NULL; + } + return sa_strdup(sa, identity); +} + +static str get_col_name(sql_allocator *sa, sql_exp *exp, int name_type) { char col_name[256]; size_t i; @@ -882,12 +908,31 @@ groupby_produce(backend *be, sql_rel *re for (en = aggr_exps->h; en; en = en->next) { exp = en->data; /* We might have different types when doing the aggregation so we need to cast */ - str weld_type = getWeldType(exp_subtype(exp)->type->localtype); + int type = exp_subtype(exp)->type->localtype; + str weld_type = getWeldType(type); + if (has_nil(exp) && need_no_nil(exp)) { + wprintf(wstate, "if("); + } wprintf(wstate, "%s(", weld_type); exp_to_weld(be, wstate, exp); wprintf(wstate, ")"); + if (has_nil(exp) && need_no_nil(exp)) { + /* if (x == TYPEnil, identity, x) */ + wprintf(wstate, " == %snil, %s, ", weld_type, get_identity(wstate->sa, aggr_func, weld_type, type)); + wprintf(wstate, "%s(", weld_type); + exp_to_weld(be, wstate, exp); + wprintf(wstate, "))"); + } if (strcmp(get_func_name(exp->f), "avg") == 0) { - wprintf(wstate, ", 1L"); + if (has_nil(exp) && need_no_nil(exp)) { + wprintf(wstate, ", if("); + wprintf(wstate, "%s(", weld_type); + exp_to_weld(be, wstate, exp); + wprintf(wstate, ")"); + wprintf(wstate, " == %snil, 0L, 1L)", weld_type); + } else { + wprintf(wstate, ", 1L"); + } } if (en->next != NULL) { wprintf(wstate, ", "); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list