Changeset: 64c3f5fda4dc for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=64c3f5fda4dc
Added Files:
        sql/test/BugTracker-2015/Tests/string_split.Bug-3564.sql
        sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.err
        sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.out
Modified Files:
        monetdb5/modules/atoms/str.c
        monetdb5/modules/atoms/str.h
        monetdb5/modules/atoms/str.mal
        sql/backends/monet5/sql.mal
        sql/common/sql_types.c
        sql/server/sql_parser.y
        sql/server/sql_scan.c
        sql/storage/bat/bat_utils.c
Branch: pyapi
Log Message:

Merge newlines.


diffs (truncated from 388 to 300 lines):

diff --git a/monetdb5/modules/atoms/str.c b/monetdb5/modules/atoms/str.c
--- a/monetdb5/modules/atoms/str.c
+++ b/monetdb5/modules/atoms/str.c
@@ -1895,6 +1895,66 @@ STRReverseStrSearch(int *res, const str 
 }
 
 str
+STRsplitpart(str *res, str *haystack, str *needle, int *field)
+{
+       size_t slen;
+       int len, f = *field;
+       char *p;
+       const char *s = *haystack;
+       const char *s2 = *needle;
+
+       if (strNil(s) || *field == int_nil) {
+               *res = GDKstrdup("");
+               if (*res == NULL)
+                       throw(MAL, "str.splitpart", "Allocation failed");
+               return MAL_SUCCEED;
+       }
+
+       if (*field <= 0) {
+               throw(MAL, "str.splitpart", "field position must be greater 
than zero");
+               *res = GDKstrdup("");
+               if (*res == NULL)
+                       throw(MAL, "str.splitpart", "field position must be 
greater than zero");
+               return MAL_SUCCEED;
+       }
+
+       slen = strlen(s2);
+
+       while ((p = strstr(s, s2)) != 0 && f > 1) {
+               s = p + slen;
+               f--;
+       }
+
+       if (f != 1) {
+               *res = GDKstrdup("");
+               if (*res == NULL)
+                       throw(MAL, "str.splitpart", "Allocation failed");
+               return MAL_SUCCEED;
+       }
+   
+       if (p == 0) {
+               len = UTF8_strlen(s);
+       } else if ((p = strstr(s, s2)) != 0) {
+               len = (int) (p - s);
+       } else {
+               len = UTF8_strlen(s);
+       }
+
+       if (len == int_nil || len == 0) {
+               *res = GDKstrdup("");
+               if (*res == NULL)
+                       throw(MAL, "str.splitpart", "Allocation failed");
+               return MAL_SUCCEED;
+       }
+       *res = GDKmalloc(len + 1);
+       if (*res == NULL)
+               throw(MAL, "str.splitpart", "Allocation failed");
+       strncpy(*res, s, len);
+       (*res)[len] = 0;
+       return MAL_SUCCEED;
+}
+
+str
 STRStrip(str *res, const str *arg1)
 {
        const char *start = *arg1;
diff --git a/monetdb5/modules/atoms/str.h b/monetdb5/modules/atoms/str.h
--- a/monetdb5/modules/atoms/str.h
+++ b/monetdb5/modules/atoms/str.h
@@ -43,6 +43,7 @@ str_export str STRLower(str *res, const 
 str_export str STRUpper(str *res, const str *arg1);
 str_export str STRstrSearch(int *res, const str *arg1, const str *arg2);
 str_export str STRReverseStrSearch(int *res, const str *arg1, const str *arg2);
+str_export str STRsplitpart(str *res, str *haystack, str *needle, int *field);
 str_export str STRStrip(str *res, const str *arg1);
 str_export str STRLtrim(str *res, const str *arg1);
 str_export str STRRtrim(str *res, const str *arg1);
diff --git a/monetdb5/modules/atoms/str.mal b/monetdb5/modules/atoms/str.mal
--- a/monetdb5/modules/atoms/str.mal
+++ b/monetdb5/modules/atoms/str.mal
@@ -70,6 +70,11 @@ address STRReverseStrSearch
 comment "Reverse search for a substring. Returns
         position, -1 if not found.";
 
+command splitpart( s:str, needle:str, field:int ) :str
+address STRsplitpart
+comment "Split string on delimiter. Returns
+        given field (counting from one.)";
+
 command trim( s:str ) :str
 address STRStrip
 comment "Strip whitespaces around a string.";
diff --git a/sql/backends/monet5/sql.mal b/sql/backends/monet5/sql.mal
--- a/sql/backends/monet5/sql.mal
+++ b/sql/backends/monet5/sql.mal
@@ -961,6 +961,9 @@ address STRsubstringTail;
 command calc.substring(s:str,offset:int,count:int):str
 address STRsubstring;
 
+command calc.splitstring(s:str,needle:str,field:int):str
+address STRsplitstring;
+
 command calc.month_interval( v:str, ek:int, sk:int ) :int
 address month_interval_str
 comment "cast str to a month_interval and check for overflow";
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
@@ -1573,6 +1573,7 @@ sqltypeinit( sql_allocator *sa)
 
                sql_create_func(sa, "locate", "str", "locate", *t, *t, INT, 
SCALE_NONE);
                sql_create_func3(sa, "locate", "str", "locate", *t, *t, INT, 
INT, SCALE_NONE);
+               sql_create_func3(sa, "splitpart", "str", "splitpart", *t, *t, 
INT, *t, INOUT);
                sql_create_func(sa, "substring", "str", "substring", *t, INT, 
*t, INOUT);
                sql_create_func3(sa, "substring", "str", "substring", *t, INT, 
INT, *t, INOUT);
                sql_create_func(sa, "like", "algebra", "like", *t, *t, BIT, 
SCALE_NONE);
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -526,7 +526,7 @@ int yydebug=1;
 %left <operation> AND
 %left <operation> NOT
 %left <sval> COMPARISON /* <> < > <= >= */
-%left <operation> '+' '-' '&' '|' '^' LEFT_SHIFT RIGHT_SHIFT LEFT_SHIFT_ASSIGN 
RIGHT_SHIFT_ASSIGN CONCATSTRING SUBSTRING POSITION
+%left <operation> '+' '-' '&' '|' '^' LEFT_SHIFT RIGHT_SHIFT LEFT_SHIFT_ASSIGN 
RIGHT_SHIFT_ASSIGN CONCATSTRING SUBSTRING POSITION SPLIT_PART
 %right UMINUS
 %left <operation> '*' '/'
 %left <operation> '%'
@@ -3891,6 +3891,16 @@ string_funcs:
                          append_symbol(l, $1);
                          append_symbol(l, $3);
                          $$ = _symbol_create_list( SQL_BINOP, l ); }
+  | SPLIT_PART '(' scalar_exp ',' scalar_exp ',' scalar_exp ')'
+                       { dlist *l = L();
+                         dlist *ops = L();
+                         append_list(l,
+                               append_string(L(), sa_strdup(SA, "splitpart")));
+                         append_symbol(ops, $3);
+                         append_symbol(ops, $5);
+                         append_symbol(ops, $7);
+                         append_list(l, ops);
+                         $$ = _symbol_create_list( SQL_NOP, l ); }
  ;
 
 column_exp_commalist:
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
@@ -233,6 +233,7 @@ scanner_init_keywords(void)
 
        keywords_insert("POSITION", POSITION);
        keywords_insert("SUBSTRING", SUBSTRING);
+       keywords_insert("SPLIT_PART", SPLIT_PART);
 
        keywords_insert("CASE", CASE);
        keywords_insert("WHEN", WHEN);
diff --git a/sql/storage/bat/bat_utils.c b/sql/storage/bat/bat_utils.c
--- a/sql/storage/bat/bat_utils.c
+++ b/sql/storage/bat/bat_utils.c
@@ -241,7 +241,11 @@ tr_find_table( sql_trans *tr, sql_table 
        while ((!nt || !nt->data) && tr) {
                sql_schema *s = tr_find_schema( tr, t->s);
 
-               nt = find_sql_table_id(s, t->base.id);
+               if (list_length(s->tables.set) < HASH_MIN_SIZE)
+                       nt = find_sql_table_id(s, t->base.id);
+               else
+                       nt = find_sql_table(s, t->base.name);
+               assert(nt->base.id == t->base.id);
                tr = tr->parent;
        }
        return nt;
@@ -253,8 +257,7 @@ tr_find_column( sql_trans *tr, sql_colum
        sql_column *nc = NULL;
 
        while ((!nc || !nc->data) && tr) {
-               sql_schema *s = tr_find_schema( tr, c->t->s);
-               sql_table *t =  find_sql_table_id(s, c->t->base.id);
+               sql_table *t =  tr_find_table(tr, c->t);
                node *n = cs_find_id(&t->columns, c->base.id);
                if (n)
                        nc = n->data;
@@ -269,8 +272,7 @@ tr_find_idx( sql_trans *tr, sql_idx *i)
        sql_idx *ni = NULL;
 
        while ((!ni || !ni->data) && tr) {
-               sql_schema *s = tr_find_schema( tr, i->t->s);
-               sql_table *t =  find_sql_table_id(s, i->t->base.id);
+               sql_table *t =  tr_find_table(tr, i->t);
                node *n = cs_find_id(&t->idxs, i->base.id);
                if (n)
                        ni = n->data;
diff --git a/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.sql 
b/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.sql
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.sql
@@ -0,0 +1,16 @@
+
+select split_part('joeuser@mydatabase','@',0) AS "an error";
+select split_part('joeuser@mydatabase','@',1) AS "joeuser";
+select split_part('joeuser@mydatabase','@',2) AS "mydatabase";
+select split_part('joeuser@mydatabase','@',3) AS "empty string";
+select split_part('','@',3) AS "error";
+
+start transaction;
+
+create table somestrings(a string);
+insert into somestrings values(''),(' '),('joeuser@mydatabase'), ('a@'), 
('@b'), ('a@@@b'), ('@@b');
+select * from somestrings;
+select split_part(a,'@',1), split_part(a,'@',2) from somestrings;
+drop table somestrings;
+
+rollback;
diff --git a/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.err 
b/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.err
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.err
@@ -0,0 +1,40 @@
+stderr of test 'string_split.Bug-3564` in directory 'sql/test/BugTracker-2015` 
itself:
+
+
+# 15:17:35 >  
+# 15:17:35 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"mapi_open=true" "--set" "mapi_port=38988" "--set" 
"mapi_usock=/var/tmp/mtest-61161/.s.monetdb.38988" "--set" "monet_prompt=" 
"--forcemito" "--set" "mal_listing=2" 
"--dbpath=/Users/hannes/monetdb-install/var/MonetDB/mTests_sql_test_BugTracker-2015"
 "--set" "mal_listing=0" "--set" "embedded_r=yes"
+# 15:17:35 >  
+
+# builtin opt  gdk_dbpath = 
/Users/hannes/monetdb-install/var/monetdb5/dbfarm/demo
+# builtin opt  gdk_debug = 0
+# builtin opt  gdk_vmtrim = no
+# builtin opt  monet_prompt = >
+# builtin opt  monet_daemon = no
+# builtin opt  mapi_port = 50000
+# builtin opt  mapi_open = false
+# builtin opt  mapi_autosense = false
+# builtin opt  sql_optimizer = default_pipe
+# builtin opt  sql_debug = 0
+# cmdline opt  gdk_nr_threads = 0
+# cmdline opt  mapi_open = true
+# cmdline opt  mapi_port = 38988
+# cmdline opt  mapi_usock = /var/tmp/mtest-61161/.s.monetdb.38988
+# cmdline opt  monet_prompt = 
+# cmdline opt  mal_listing = 2
+# cmdline opt  gdk_dbpath = 
/Users/hannes/monetdb-install/var/MonetDB/mTests_sql_test_BugTracker-2015
+# cmdline opt  mal_listing = 0
+# cmdline opt  embedded_r = yes
+# cmdline opt  gdk_debug = 536870922
+
+# 15:17:35 >  
+# 15:17:35 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-61161" "--port=38988"
+# 15:17:35 >  
+
+MAPI  = (monetdb) /var/tmp/mtest-61161/.s.monetdb.38988
+QUERY = select split_part('joeuser@mydatabase','@',0) AS "an error";
+ERROR = !field position must be greater than zero
+
+# 15:17:36 >  
+# 15:17:36 >  "Done."
+# 15:17:36 >  
+
diff --git a/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.out 
b/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.out
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2015/Tests/string_split.Bug-3564.stable.out
@@ -0,0 +1,121 @@
+stdout of test 'string_split.Bug-3564` in directory 'sql/test/BugTracker-2015` 
itself:
+
+
+# 15:17:35 >  
+# 15:17:35 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"mapi_open=true" "--set" "mapi_port=38988" "--set" 
"mapi_usock=/var/tmp/mtest-61161/.s.monetdb.38988" "--set" "monet_prompt=" 
"--forcemito" "--set" "mal_listing=2" 
"--dbpath=/Users/hannes/monetdb-install/var/MonetDB/mTests_sql_test_BugTracker-2015"
 "--set" "mal_listing=0" "--set" "embedded_r=yes"
+# 15:17:35 >  
+
+# MonetDB 5 server v11.20.0
+# This is an unreleased version
+# Serving database 'mTests_sql_test_BugTracker-2015', using 4 threads
+# Compiled for x86_64-apple-darwin14.3.0/64bit with 64bit OIDs and 128bit 
integers dynamically linked
+# Found 16.000 GiB available main-memory.
+# Copyright (c) 1993-July 2008 CWI.
+# Copyright (c) August 2008-2015 MonetDB B.V., all rights reserved
+# Visit http://www.monetdb.org/ for further information
+# Listening for connection requests on mapi:monetdb://dakar.da.cwi.nl:38988/
+# Listening for UNIX domain connection requests on 
mapi:monetdb:///var/tmp/mtest-61161/.s.monetdb.38988
+# MonetDB/GIS module loaded
+# Start processing logs sql/sql_logs version 52200
+# Finished processing logs sql/sql_logs
+# MonetDB/SQL module loaded
+# MonetDB/R   module loaded
+
+Ready.
+# SQL catalog created, loading sql scripts once
+# loading sql script: 09_like.sql
+# loading sql script: 10_math.sql
+# loading sql script: 11_times.sql
+# loading sql script: 12_url.sql
+# loading sql script: 13_date.sql
+# loading sql script: 14_inet.sql
+# loading sql script: 15_querylog.sql
+# loading sql script: 16_tracelog.sql
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to