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

Reply via email to