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