Changeset: 61797774eded for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=61797774eded Modified Files: gdk/gdk_aggr.c sql/backends/monet5/sql_upgrades.c sql/common/sql_types.c sql/scripts/51_sys_schema_extension.sql sql/server/sql_scan.c Branch: default Log Message:
Move group_concat definition, memory leak fix, remove keyword from sql scanner and avoid extra allocation in an empty group. diffs (268 lines): diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c --- a/gdk/gdk_aggr.c +++ b/gdk/gdk_aggr.c @@ -3272,9 +3272,9 @@ concat_strings(void *res, int what, BAT* BUN i, p, q, nils = 0; const oid *aux; const char *separator = ","; - size_t *lengths = NULL, separator_length = strlen(separator), next_length, to_allocate; + size_t* lengths = NULL, separator_length = strlen(separator), next_length; oid *lastoid = NULL; - str* astrings = NULL, s; + str* astrings = NULL, s, single_str = NULL; BATiter bi; BAT *bn = NULL; gdk_return rres = GDK_SUCCEED; @@ -3291,7 +3291,6 @@ concat_strings(void *res, int what, BAT* if (ngrp == 1) { size_t offset = 0, single_length = 0; oid single_oid = 0; - str single_str = NULL; if (cand == NULL) { if(nonil) { BATloop(b,p,q) { @@ -3319,13 +3318,12 @@ concat_strings(void *res, int what, BAT* } } if(!nils) { - to_allocate = single_length > 0 ? single_length + 1 - separator_length : 1; - if((single_str = GDKmalloc(to_allocate * sizeof(str))) == NULL) { - GDKerror("%s: malloc failure\n", func); - rres = GDK_FAIL; - goto finish; - } - if(to_allocate > 1) { + if(single_length > 0) { + if ((single_str = GDKmalloc((single_length + 1 - separator_length) * sizeof(str))) == NULL) { + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; + } BATloop(b,p,q){ s = BUNtail(bi, p); next_length = strlen(s); @@ -3338,25 +3336,43 @@ concat_strings(void *res, int what, BAT* } } } - } - single_str[offset] = '\0'; - if(what == IS_A_BAT && BUNappend(bn, single_str, FALSE) != GDK_SUCCEED) { - GDKerror("%s: malloc failure\n", func); - rres = GDK_FAIL; - goto finish; + single_str[offset] = '\0'; + if(what == IS_A_BAT) { + if(BUNappend(bn, single_str, FALSE) != GDK_SUCCEED) { + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; + } + } else { + ValPtr pt = (ValPtr) res; + pt->len = single_str[offset]; + if((pt->val.sval = GDKstrdup(single_str)) == NULL) { + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; + } + } + } else if(what == IS_A_BAT) { + if(BUNappend(bn, "", FALSE) != GDK_SUCCEED) { + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; + } } else { ValPtr pt = (ValPtr) res; - pt->len = single_str[offset]; - if((pt->val.sval = GDKstrdup(single_str)) == NULL) { + pt->len = 0; + if((pt->val.sval = GDKstrdup("")) == NULL) { GDKerror("%s: malloc failure\n", func); rres = GDK_FAIL; goto finish; } } - } else if(what == IS_A_BAT && BUNappend(bn, str_nil, FALSE) != GDK_SUCCEED) { - GDKerror("%s: malloc failure\n", func); - rres = GDK_FAIL; - goto finish; + } else if(what == IS_A_BAT) { + if(BUNappend(bn, str_nil, FALSE) != GDK_SUCCEED) { + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; + } } else { ValPtr pt = (ValPtr) res; pt->len = 0; @@ -3400,13 +3416,12 @@ concat_strings(void *res, int what, BAT* } } if (!nils) { - to_allocate = single_length > 0 ? single_length + 1 - separator_length : 1; - if ((single_str = GDKmalloc(to_allocate * sizeof(str))) == NULL) { - GDKerror("%s: malloc failure\n", func); - rres = GDK_FAIL; - goto finish; - } - if(to_allocate > 1) { + if(single_length > 0) { + if ((single_str = GDKmalloc((single_length + 1 - separator_length) * sizeof(str))) == NULL) { + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; + } cand = aux; while (cand < candend) { i = *cand++ - seqb; @@ -3423,9 +3438,13 @@ concat_strings(void *res, int what, BAT* } } } - } - single_str[offset] = '\0'; - if (BUNappend(bn, single_str, FALSE) != GDK_SUCCEED) { + single_str[offset] = '\0'; + if (BUNappend(bn, single_str, FALSE) != GDK_SUCCEED) { + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; + } + } else if (BUNappend(bn, "", FALSE) != GDK_SUCCEED) { GDKerror("%s: malloc failure\n", func); rres = GDK_FAIL; goto finish; @@ -3470,14 +3489,13 @@ concat_strings(void *res, int what, BAT* } for (i = 0; i < ngrp; i++) { if(lastoid[i] != BUN_NONE) { - to_allocate = lengths[i] > 0 ? lengths[i] + 1 - separator_length : 1; - if((astrings[i] = GDKmalloc(to_allocate * sizeof(str))) == NULL) { + if(lengths[i] == 0) { + lastoid[i] = BUN_NONE - 1; + } else if((astrings[i] = GDKmalloc((lengths[i] + 1 - separator_length) * sizeof(str))) == NULL) { GDKerror("%s: malloc failure\n", func); rres = GDK_FAIL; goto finish; } - if(to_allocate == 1) - lastoid[i] = BUN_NONE - 1; lengths[i] = 0; } } @@ -3513,9 +3531,9 @@ concat_strings(void *res, int what, BAT* goto finish; } } else if(BUNappend(bn, str_nil, FALSE) != GDK_SUCCEED) { - GDKerror("%s: malloc failure\n", func); - rres = GDK_FAIL; - goto finish; + GDKerror("%s: malloc failure\n", func); + rres = GDK_FAIL; + goto finish; } } } else { @@ -3543,14 +3561,13 @@ concat_strings(void *res, int what, BAT* } for (i = 0; i < ngrp; i++) { if(lastoid[i] != BUN_NONE) { - to_allocate = lengths[i] > 0 ? lengths[i] + 1 - separator_length : 1; - if((astrings[i] = GDKmalloc(to_allocate * sizeof(str))) == NULL) { + if(lengths[i] == 0) { + lastoid[i] = BUN_NONE - 1; + } else if((astrings[i] = GDKmalloc((lengths[i] + 1 - separator_length) * sizeof(str))) == NULL) { GDKerror("%s: malloc failure\n", func); rres = GDK_FAIL; goto finish; } - if(to_allocate == 1) - lastoid[i] = BUN_NONE - 1; lengths[i] = 0; } } @@ -3610,6 +3627,8 @@ finish: } GDKfree(astrings); } + if(single_str) + GDKfree(single_str); if(lastoid) GDKfree(lastoid); if(rres == GDK_FAIL) { diff --git a/sql/backends/monet5/sql_upgrades.c b/sql/backends/monet5/sql_upgrades.c --- a/sql/backends/monet5/sql_upgrades.c +++ b/sql/backends/monet5/sql_upgrades.c @@ -1514,12 +1514,12 @@ sql_group_concat_upgrade(Client c, mvc * pos += snprintf(buf + pos, bufsize - pos, "set schema sys;\n"); pos += snprintf(buf + pos, bufsize - pos, - "create aggregate group_concat(a clob) returns clob external name \"aggr\".\"str_group_concat\";\n" - "create aggregate group_concat(a char) returns clob external name \"aggr\".\"str_group_concat\";\n" - "create aggregate group_concat(a varchar) returns clob external name \"aggr\".\"str_group_concat\";\n"); + "create aggregate group_concat(str string) returns string external name \"aggr\".\"str_group_concat\";\n" + "grant execute on aggregate group_concat(string) to public;\n"); if (schema) pos += snprintf(buf + pos, bufsize - pos, "set schema \"%s\";\n", schema); + pos += snprintf(buf + pos, bufsize - pos, "commit;\n"); assert(pos < bufsize); printf("Running database upgrade commands:\n%s\n", buf); diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c --- a/sql/common/sql_types.c +++ b/sql/common/sql_types.c @@ -1339,7 +1339,6 @@ sqltypeinit( sql_allocator *sa) #ifdef HAVE_HGE sql_type *HGE = NULL; #endif - sql_type *CHAR, *VARCHAR, *CLOB; sql_type *SECINT, *MONINT, *DTE; sql_type *TME, *TMETZ, *TMESTAMP, *TMESTAMPTZ; sql_type *ANY, *TABLE; @@ -1358,9 +1357,9 @@ sqltypeinit( sql_allocator *sa) sql_create_alias(sa, BIT->sqlname, "BOOL"); strings = t; - CHAR = *t++ = sql_create_type(sa, "CHAR", 0, 0, 0, EC_CHAR, "str"); - VARCHAR = STR = *t++ = sql_create_type(sa, "VARCHAR", 0, 0, 0, EC_STRING, "str"); - CLOB = *t++ = sql_create_type(sa, "CLOB", 0, 0, 0, EC_STRING, "str"); + *t++ = sql_create_type(sa, "CHAR", 0, 0, 0, EC_CHAR, "str"); + STR = *t++ = sql_create_type(sa, "VARCHAR", 0, 0, 0, EC_STRING, "str"); + *t++ = sql_create_type(sa, "CLOB", 0, 0, 0, EC_STRING, "str"); numerical = t; #if SIZEOF_OID == SIZEOF_INT @@ -1576,10 +1575,6 @@ sqltypeinit( sql_allocator *sa) sql_create_aggr(sa, "count_no_nil", "aggr", "count_no_nil", NULL, LNG); sql_create_aggr(sa, "count", "aggr", "count", NULL, LNG); - sql_create_aggr(sa, "group_concat", "aggr", "str_group_concat", CHAR, CLOB); - sql_create_aggr(sa, "group_concat", "aggr", "str_group_concat", VARCHAR, CLOB); - sql_create_aggr(sa, "group_concat", "aggr", "str_group_concat", CLOB, CLOB); - /* order based operators */ sql_create_analytic(sa, "diff", "sql", "diff", ANY, NULL, NULL, BIT, SCALE_NONE); sql_create_analytic(sa, "diff", "sql", "diff", BIT, ANY, NULL, BIT, SCALE_NONE); diff --git a/sql/scripts/51_sys_schema_extension.sql b/sql/scripts/51_sys_schema_extension.sql --- a/sql/scripts/51_sys_schema_extension.sql +++ b/sql/scripts/51_sys_schema_extension.sql @@ -420,3 +420,5 @@ SELECT 'pi', pi() UNION ALL SELECT 'rowcnt', rowcnt; GRANT SELECT ON sys.var_values TO PUBLIC; +CREATE AGGREGATE sys.group_concat(str string) RETURNS string EXTERNAL NAME "aggr"."str_group_concat"; +GRANT EXECUTE ON AGGREGATE sys.group_concat(string) TO PUBLIC; 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 @@ -106,7 +106,6 @@ scanner_init_keywords(void) failed += keywords_insert("SUM", AGGR); failed += keywords_insert("PROD", AGGR); failed += keywords_insert("COUNT", AGGR); - failed += keywords_insert("GROUP_CONCAT", AGGR); failed += keywords_insert("LAG", AGGR2); failed += keywords_insert("LEAD", AGGR2); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list