Changeset: b4f69dc5dca5 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b4f69dc5dca5
Modified Files:
        configure.ag
        monetdb5/modules/mal/pcre.c
        sql/backends/monet5/wlr.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        sql/server/rel_rel.h
        sql/server/rel_select.c
        sql/server/sql_mvc.c
        sql/server/sql_mvc.h
        sql/test/emptydb/Tests/check.stable.out
        sql/test/emptydb/Tests/check.stable.out.32bit
        sql/test/emptydb/Tests/check.stable.out.int128
        sql/test/subquery/Tests/subquery3.sql
Branch: default
Log Message:

Merge with Nov2019 branch.


diffs (truncated from 598 to 300 lines):

diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -1666,12 +1666,22 @@ AS_VAR_IF([enable_rintegration], [no], [
                         enable_rintegration=no
                         why_not_rintegration="(libR library not found)"])],
                [AS_IF([RHOME=`$RCMD RHOME` && libr_CFLAGS=`$RCMD CMD config 
--cppflags` && libr_LIBS=`$RCMD CMD config --ldflags | sed -e 's|-fopenmp 
|-fopenmp=libgomp |'`],
-                       [have_libr=yes
-                        AC_DEFINE([HAVE_LIBR], 1, [Define if you have libR 
installed])
-                        AC_SUBST([libr_CFLAGS], [$libr_CFLAGS])
-                        AC_SUBST([libr_LIBS], [$libr_LIBS])
-                        AC_SUBST([RHOME], [$RHOME])
-                        AC_DEFINE_UNQUOTED([RHOME], ["$RHOME"], [The home of 
R])])])])
+                       [save_CPPFLAGS="$CPPFLAGS"
+                        CPPFLAGS="$CPPFLAGS $libr_CFLAGS"
+                        AC_CHECK_HEADER([Rembedded.h],
+                               [have_libr=yes
+                                AC_DEFINE([HAVE_LIBR], 1, [Define if you have 
libR installed])
+                                AC_SUBST([libr_CFLAGS], [$libr_CFLAGS])
+                                AC_SUBST([libr_LIBS], [$libr_LIBS])
+                                AC_SUBST([RHOME], [$RHOME])
+                                AC_DEFINE_UNQUOTED([RHOME], ["$RHOME"], [The 
home of R])],
+                               [AS_VAR_IF([enable_rintegration], [yes],
+                                       [AC_MSG_ERROR([libR library required 
for R integration support])],
+                                       [have_libr=no
+                                        why_not_libr="(Rembedded.h not found)"
+                                        enable_rintegration=no
+                                        why_not_rintegration="(Rembedded.h not 
found)"])])
+                        CPPFLAGS="$save_CPPFLAGS"])])])
 AM_CONDITIONAL([HAVE_LIBR], [test x"$have_libr" != xno])
 
 # Python API (Python UDFs)
diff --git a/monetdb5/modules/mal/pcre.c b/monetdb5/modules/mal/pcre.c
--- a/monetdb5/modules/mal/pcre.c
+++ b/monetdb5/modules/mal/pcre.c
@@ -32,7 +32,9 @@
 #ifndef PCRE_STUDY_JIT_COMPILE
 /* old library version on e.g. EPEL 6 */
 #define pcre_free_study(x)             pcre_free(x)
+#define PCRE_STUDY_JIT_COMPILE 0
 #endif
+#define JIT_COMPILE_MIN        1024    /* when to try JIT compilation of 
patterns */
 
 #else
 
@@ -221,17 +223,6 @@ utf8stoucs(const char *src)
        return dest;
 }
 
-static uint32_t *
-myucschr(const uint32_t *ucs, uint32_t uc)
-{
-       while (*ucs) {
-               if (*ucs == uc)
-                       return (uint32_t *) ucs;
-               ucs++;
-       }
-       return NULL;
-}
-
 static size_t
 myucslen(const uint32_t *ucs)
 {
@@ -364,32 +355,43 @@ mywstrcasestr(const char *restrict hayst
        return NULL;
 }
 
-static int
-re_simple(const char *pat)
+/* returns true if the pattern does not contain unescaped `_' (single
+ * character match) and ends with unescaped `%' (any sequence
+ * match) */
+static bool
+re_simple(const char *pat, unsigned char esc)
 {
-       int nr = 0;
+       bool escaped = false;
+       bool percatend = false;
 
        if (pat == 0)
                return 0;
-       if (*pat == '%')
+       if (*pat == '%') {
+               percatend = true;
                pat++;
+       }
        while (*pat) {
-               if (*pat == '_')
+               percatend = false;
+               if (escaped) {
+                       escaped = false;
+               } else if ((unsigned char) *pat == esc) {
+                       escaped = true;
+               } else if (*pat == '_') {
                        return 0;
-               if (*pat++ == '%')
-                       nr++;
+               } else if (*pat == '%') {
+                       percatend = true;
+               }
+               pat++;
        }
-       if (*(pat-1) != '%')
-               return 0;
-       return nr;
+       return percatend;
 }
 
 static bool
-is_strcmpable(const char *pat, const str esc)
+is_strcmpable(const char *pat, const char *esc)
 {
        if (pat[strcspn(pat, "%_")])
                return false;
-       return strlen(esc) == 0 || strstr(pat, esc) == NULL;
+       return strlen(esc) == 0 || strcmp(esc, str_nil) == 0 || strstr(pat, 
esc) == NULL;
 }
 
 static bool
@@ -398,6 +400,8 @@ re_match_ignore(const char *s, RE *patte
        RE *r;
 
        for (r = pattern; r; r = r->n) {
+               if (*r->w == 0 && (r->search || *s == 0))
+                       return true;
                if (!*s ||
                        (r->search ? (s = mywstrcasestr(s, r->w)) == NULL : 
mywstrncasecmp(s, r->w, r->len) != 0))
                        return false;
@@ -412,6 +416,8 @@ re_match_no_ignore(const char *s, RE *pa
        RE *r;
 
        for (r = pattern; r; r = r->n) {
+               if (*r->k == 0 && (r->search || *s == 0))
+                       return true;
                if (!*s ||
                        (r->search ? (s = strstr(s, r->k)) == NULL : strncmp(s, 
r->k, r->len) != 0))
                        return false;
@@ -441,18 +447,16 @@ re_destroy(RE *p)
  * subsequent structures the fields point into the allocated buffer of
  * the first. */
 static RE *
-re_create(const char *pat, int nr, bool caseignore)
+re_create(const char *pat, bool caseignore, uint32_t esc)
 {
        RE *r = (RE*)GDKmalloc(sizeof(RE)), *n = r;
+       bool escaped = false;
 
        if (r == NULL)
                return NULL;
-       r->n = NULL;
-       r->search = 0;
-       r->k = NULL;
-       r->w = NULL;
+       *r = (struct RE) {.search = false};
 
-       if (*pat == '%') {
+       while (esc != '%' && *pat == '%') {
                pat++; /* skip % */
                r->search = true;
        }
@@ -465,20 +469,28 @@ re_create(const char *pat, int nr, bool 
                        return NULL;
                }
                r->w = wp;
-               while ((wq = myucschr(wp, '%')) != NULL) {
-                       *wq = 0;
-                       n->w = wp;
-                       n->len = (size_t) (wq - wp);
-                       if (--nr > 0) {
-                               n = n->n = (RE*)GDKmalloc(sizeof(RE));
-                               if (n == NULL)
-                                       goto bailout;
-                               n->search = true;
-                               n->n = NULL;
-                               n->k = NULL;
-                               n->w = NULL;
+               wq = wp;
+               while (*wp) {
+                       if (escaped) {
+                               *wq++ = *wp;
+                               escaped = false;
+                       } else if (*wp == esc) {
+                               escaped = true;
+                       } else if (*wp == '%') {
+                               n->len = (size_t) (wq - r->w);
+                               while (wp[1] == '%')
+                                       wp++;
+                               if (wp[1]) {
+                                       n = n->n = GDKmalloc(sizeof(RE));
+                                       if (n == NULL)
+                                               goto bailout;
+                                       *n = (struct RE) {.search = true, .w = 
wp + 1};
+                               }
+                               *wq++ = 0;
+                       } else {
+                               *wq++ = *wp;
                        }
-                       wp = wq + 1;
+                       wp++;
                }
        } else {
                char *p, *q;
@@ -486,20 +498,29 @@ re_create(const char *pat, int nr, bool 
                        GDKfree(r);
                        return NULL;
                }
-               while ((q = strchr(p, '%')) != NULL) {
-                       *q = 0;
-                       n->k = p;
-                       n->len = (size_t) (q - p);
-                       if (--nr > 0) {
-                               n = n->n = (RE*)GDKmalloc(sizeof(RE));
-                               if (n == NULL)
-                                       goto bailout;
-                               n->search = true;
-                               n->n = NULL;
-                               n->k = NULL;
-                               n->w = NULL;
+               r->k = p;
+               q = p;
+               while (*p) {
+                       if (escaped) {
+                               *q++ = *p;
+                               escaped = false;
+                       } else if ((unsigned char) *p == esc) {
+                               escaped = true;
+                       } else if (*p == '%') {
+                               n->len = (size_t) (q - r->k);
+                               while (p[1] == '%')
+                                       p++;
+                               if (p[1]) {
+                                       n = n->n = GDKmalloc(sizeof(RE));
+                                       if (n == NULL)
+                                               goto bailout;
+                                       *n = (struct RE) {.search = true, .k = 
p + 1};
+                               }
+                               *q++ = 0;
+                       } else {
+                               *q++ = *p;
                        }
-                       p = q + 1;
+                       p++;
                }
        }
        return r;
@@ -601,7 +622,7 @@ pcre_likeselect(BAT **bnp, BAT *b, BAT *
        if ((re = pcre_compile(pat, options, &error, &errpos, NULL)) == NULL)
                throw(MAL, "pcre.likeselect",
                          OPERATION_FAILED ": compilation of pattern \"%s\" 
failed\n", pat);
-       pe = pcre_study(re, 0, &error);
+       pe = pcre_study(re, (s ? BATcount(s) : BATcount(b)) > JIT_COMPILE_MIN ? 
PCRE_STUDY_JIT_COMPILE : 0, &error);
        if (error != NULL) {
                pcre_free(re);
                throw(MAL, "pcre.likeselect",
@@ -683,14 +704,13 @@ pcre_likeselect(BAT **bnp, BAT *b, BAT *
 }
 
 static str
-re_likeselect(BAT **bnp, BAT *b, BAT *s, const char *pat, bool caseignore, 
bool anti, bool use_strcmp)
+re_likeselect(BAT **bnp, BAT *b, BAT *s, const char *pat, bool caseignore, 
bool anti, bool use_strcmp, uint32_t esc)
 {
        BATiter bi = bat_iterator(b);
        BAT *bn;
        BUN p, q;
        oid o, off;
        const char *v;
-       int nr;
        RE *re = NULL;
 
        assert(ATOMstorage(b->ttype) == TYPE_str);
@@ -701,8 +721,7 @@ re_likeselect(BAT **bnp, BAT *b, BAT *s,
        off = b->hseqbase;
 
        if (!use_strcmp) {
-               nr = re_simple(pat);
-               re = re_create(pat, nr, caseignore);
+               re = re_create(pat, caseignore, esc);
                if (!re)
                        throw(MAL, "pcre.likeselect", SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
        }
@@ -1133,7 +1152,7 @@ pcre_replace_bat(BAT **res, BAT *origin_
         * it is worth spending more time analyzing it in order to speed
         * up the time taken for matching.
         */
-       extra = pcre_study(pcre_code, 0, &err_p);
+       extra = pcre_study(pcre_code, BATcount(origin_strs) > JIT_COMPILE_MIN ? 
PCRE_STUDY_JIT_COMPILE : 0, &err_p);
        if (err_p != NULL) {
                pcre_free(pcre_code);
                throw(MAL, global ? "batpcre.replace" : "batpcre.replace_first",
@@ -1314,7 +1333,7 @@ sql2pcre(str *r, const char *pat, const 
        int escaped = 0;
        int hasWildcard = 0;
        char *ppat;
-       int esc = esc_str[0]; /* should change to utf8_convert() */
+       int esc = esc_str[0] == '\200' ? 0 : esc_str[0]; /* should change to 
utf8_convert() */
        int specials;
        int c;
 
@@ -1331,7 +1350,7 @@ sql2pcre(str *r, const char *pat, const 
         * expression.  If the user used the "+" char as escape and has "++"
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to