Changeset: 6edf3edd7f66 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6edf3edd7f66
Modified Files:
clients/Tests/MAL-signatures.stable.out
clients/Tests/MAL-signatures.stable.out.int128
clients/Tests/exports.stable.out
configure.ag
gdk/ChangeLog.Jun2020
gdk/gdk.h
gdk/gdk_firstn.c
gdk/gdk_join.c
monetdb5/ChangeLog.Jun2020
monetdb5/modules/kernel/algebra.c
monetdb5/modules/kernel/algebra.h
monetdb5/modules/kernel/algebra.mal
sql/backends/monet5/sql.c
sql/backends/monet5/sql_statement.c
sql/server/rel_distribute.c
sql/server/rel_exp.c
sql/server/rel_optimizer.c
sql/server/rel_partition.c
sql/server/rel_propagate.c
sql/server/rel_rel.c
sql/server/sql_env.c
sql/server/sql_env.h
sql/server/sql_partition.c
sql/storage/bat/bat_logger.c
sql/test/BugTracker-2009/Tests/copy_multiple_files.SF-2902320.stable.out
sql/test/BugTracker-2009/Tests/copy_multiple_files.SF-2902320.stable.out.Windows
sql/test/Dependencies/Tests/Dependencies.stable.out
sql/test/Dependencies/Tests/Dependencies.stable.out.int128
sql/test/Tests/truncate-statements-extra.stable.out
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/mapi/Tests/sql_int128.stable.out.int128
sql/test/miscellaneous/Tests/simple_selects.sql
sql/test/miscellaneous/Tests/simple_selects.stable.err
sql/test/scoping/Tests/scoping02.stable.err
sql/test/sys-schema/Tests/systemfunctions.stable.out
sql/test/sys-schema/Tests/systemfunctions.stable.out.int128
Branch: scoping
Log Message:
Merged with default
diffs (truncated from 2185 to 300 lines):
diff --git a/clients/Tests/MAL-signatures.stable.out
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -591,7 +591,7 @@ stdout of test 'MAL-signatures` in direc
[ "algebra", "ilikejoin", "command algebra.ilikejoin(l:bat[:str],
r:bat[:str], esc:str, sl:bat[:oid], sr:bat[:oid], nil_matches:bit,
estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ILIKEjoin;", "Join the
string bat L with the pattern bat R\nwith optional candidate lists SL and SR
using pattern escape string ESC\nand doing a case insensitive match.\nThe
result is two aligned bats with oids of matching rows." ]
[ "algebra", "ilikeselect", "command algebra.ilikeselect(b:bat[:str],
cand:bat[:oid], pat:str, esc:str, anti:bit):bat[:oid] ",
"PCRElikeselect1;", "" ]
[ "algebra", "ilikeselect", "command algebra.ilikeselect(b:bat[:str],
cand:bat[:oid], pat:str, anti:bit):bat[:oid] ", "PCRElikeselect4;",
"" ]
-[ "algebra", "intersect", "command algebra.intersect(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit,
estimate:lng):bat[:oid] ", "ALGintersect;", "Intersection of l
and r with candidate lists (i.e. half of semi-join)" ]
+[ "algebra", "intersect", "command algebra.intersect(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, max_one:bit,
estimate:lng):bat[:oid] ", "ALGintersect;", "Intersection of l and r
with candidate lists (i.e. half of semi-join)" ]
[ "algebra", "join", "command algebra.join(l:bat[:any_1], r:bat[:any_1],
sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng):bat[:oid] ",
"ALGjoin1;", "Join; only produce left output" ]
[ "algebra", "join", "command algebra.join(l:bat[:any_1], r:bat[:any_1],
sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) (X_0:bat[:oid],
X_1:bat[:oid]) ", "ALGjoin;", "Join" ]
[ "algebra", "leftjoin", "command algebra.leftjoin(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit,
estimate:lng):bat[:oid] ", "ALGleftjoin1;", "Left join with candidate
lists; only produce left output" ]
@@ -620,7 +620,7 @@ stdout of test 'MAL-signatures` in direc
[ "algebra", "select", "command algebra.select(b:bat[:any_1],
s:bat[:oid], low:any_1, high:any_1, li:bit, hi:bit, anti:bit):bat[:oid] ",
"ALGselect2;", "Select all head values of the first input BAT for which the
tail value\n\tis in range and for which the head value occurs in the tail of
the\n\tsecond input BAT.\n\tThe first input is a dense-headed BAT, the second
input is a\n\tdense-headed BAT with sorted tail, output is a dense-headed
BAT\n\twith in the tail the head value of the input BAT for which the\n\ttail
value is between the values low and high (inclusive if li\n\trespectively hi is
set). The output BAT is sorted on the tail\n\tvalue. If low or high is nil,
the boundary is not considered\n\t(effectively - and + infinity). If anti is
set, the result is the\n\tcomplement. Nil values in the tail are never
matched, unless\n\tlow=nil, high=nil, li=1, hi=1, anti=0. All non-nil values
are\n\treturned if low=nil, high=nil, and li, hi are not both 1, or
anti=1.\n\tNote that th
e output is suitable as second input for this\n\tfunction." ]
[ "algebra", "select", "command algebra.select(b:bat[:any_1],
s:bat[:oid], low:any_1, high:any_1, li:bit, hi:bit, anti:bit,
unknown:bit):bat[:oid] ", "ALGselect2nil;", "With unknown set, each nil
!= nil" ]
[ "algebra", "selectNotNil", "command
algebra.selectNotNil(b:bat[:any_2]):bat[:any_2] ", "ALGselectNotNil;",
"Select all not-nil values" ]
-[ "algebra", "semijoin", "command algebra.semijoin(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng)
(X_0:bat[:oid], X_1:bat[:oid]) ", "ALGsemijoin;", "Semi join with candidate
lists" ]
+[ "algebra", "semijoin", "command algebra.semijoin(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, max_one:bit,
estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGsemijoin;", "Semi
join with candidate lists" ]
[ "algebra", "slice", "command algebra.slice(b:bat[:any_1], x:lng,
y:lng):bat[:any_1] ", "ALGslice;", "Return the slice with the BUNs at
position x till y." ]
[ "algebra", "slice", "command algebra.slice(b:bat[:any_1], x:int,
y:int):bat[:any_1] ", "ALGslice_int;", "Return the slice with the
BUNs at position x till y." ]
[ "algebra", "slice", "command algebra.slice(b:bat[:any_1], x:lng,
y:lng):bat[:any_1] ", "ALGslice_lng;", "Return the slice with the
BUNs at position x till y." ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -700,7 +700,7 @@ stdout of test 'MAL-signatures` in direc
[ "algebra", "ilikejoin", "command algebra.ilikejoin(l:bat[:str],
r:bat[:str], esc:str, sl:bat[:oid], sr:bat[:oid], nil_matches:bit,
estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ILIKEjoin;", "Join the
string bat L with the pattern bat R\nwith optional candidate lists SL and SR
using pattern escape string ESC\nand doing a case insensitive match.\nThe
result is two aligned bats with oids of matching rows." ]
[ "algebra", "ilikeselect", "command algebra.ilikeselect(b:bat[:str],
cand:bat[:oid], pat:str, esc:str, anti:bit):bat[:oid] ",
"PCRElikeselect1;", "" ]
[ "algebra", "ilikeselect", "command algebra.ilikeselect(b:bat[:str],
cand:bat[:oid], pat:str, anti:bit):bat[:oid] ", "PCRElikeselect4;",
"" ]
-[ "algebra", "intersect", "command algebra.intersect(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit,
estimate:lng):bat[:oid] ", "ALGintersect;", "Intersection of l
and r with candidate lists (i.e. half of semi-join)" ]
+[ "algebra", "intersect", "command algebra.intersect(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, max_one:bit,
estimate:lng):bat[:oid] ", "ALGintersect;", "Intersection of l and r
with candidate lists (i.e. half of semi-join)" ]
[ "algebra", "join", "command algebra.join(l:bat[:any_1], r:bat[:any_1],
sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng):bat[:oid] ",
"ALGjoin1;", "Join; only produce left output" ]
[ "algebra", "join", "command algebra.join(l:bat[:any_1], r:bat[:any_1],
sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) (X_0:bat[:oid],
X_1:bat[:oid]) ", "ALGjoin;", "Join" ]
[ "algebra", "leftjoin", "command algebra.leftjoin(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit,
estimate:lng):bat[:oid] ", "ALGleftjoin1;", "Left join with candidate
lists; only produce left output" ]
@@ -729,7 +729,7 @@ stdout of test 'MAL-signatures` in direc
[ "algebra", "select", "command algebra.select(b:bat[:any_1],
s:bat[:oid], low:any_1, high:any_1, li:bit, hi:bit, anti:bit):bat[:oid] ",
"ALGselect2;", "Select all head values of the first input BAT for which the
tail value\n\tis in range and for which the head value occurs in the tail of
the\n\tsecond input BAT.\n\tThe first input is a dense-headed BAT, the second
input is a\n\tdense-headed BAT with sorted tail, output is a dense-headed
BAT\n\twith in the tail the head value of the input BAT for which the\n\ttail
value is between the values low and high (inclusive if li\n\trespectively hi is
set). The output BAT is sorted on the tail\n\tvalue. If low or high is nil,
the boundary is not considered\n\t(effectively - and + infinity). If anti is
set, the result is the\n\tcomplement. Nil values in the tail are never
matched, unless\n\tlow=nil, high=nil, li=1, hi=1, anti=0. All non-nil values
are\n\treturned if low=nil, high=nil, and li, hi are not both 1, or
anti=1.\n\tNote that th
e output is suitable as second input for this\n\tfunction." ]
[ "algebra", "select", "command algebra.select(b:bat[:any_1],
s:bat[:oid], low:any_1, high:any_1, li:bit, hi:bit, anti:bit,
unknown:bit):bat[:oid] ", "ALGselect2nil;", "With unknown set, each nil
!= nil" ]
[ "algebra", "selectNotNil", "command
algebra.selectNotNil(b:bat[:any_2]):bat[:any_2] ", "ALGselectNotNil;",
"Select all not-nil values" ]
-[ "algebra", "semijoin", "command algebra.semijoin(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng)
(X_0:bat[:oid], X_1:bat[:oid]) ", "ALGsemijoin;", "Semi join with candidate
lists" ]
+[ "algebra", "semijoin", "command algebra.semijoin(l:bat[:any_1],
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, max_one:bit,
estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGsemijoin;", "Semi
join with candidate lists" ]
[ "algebra", "slice", "command algebra.slice(b:bat[:any_1], x:lng,
y:lng):bat[:any_1] ", "ALGslice;", "Return the slice with the BUNs at
position x till y." ]
[ "algebra", "slice", "command algebra.slice(b:bat[:any_1], x:int,
y:int):bat[:any_1] ", "ALGslice_int;", "Return the slice with the
BUNs at position x till y." ]
[ "algebra", "slice", "command algebra.slice(b:bat[:any_1], x:lng,
y:lng):bat[:any_1] ", "ALGslice_lng;", "Return the slice with the
BUNs at position x till y." ]
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -148,7 +148,7 @@ BUN BATgrows(BAT *b);
gdk_return BAThash(BAT *b);
void BAThseqbase(BAT *b, oid o);
gdk_return BATimprints(BAT *b);
-BAT *BATintersect(BAT *l, BAT *r, BAT *sl, BAT *sr, bool nil_matches, BUN
estimate);
+BAT *BATintersect(BAT *l, BAT *r, BAT *sl, BAT *sr, bool nil_matches, bool
max_one, BUN estimate);
BAT *BATintersectcand(BAT *a, BAT *b);
gdk_return BATjoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr,
bool nil_matches, BUN estimate) __attribute__((__warn_unused_result__));
gdk_return BATkey(BAT *b, bool onoff);
@@ -179,7 +179,7 @@ BAT *BATsample(BAT *b, BUN n);
BAT *BATsample_with_seed(BAT *b, BUN n, unsigned seed);
gdk_return BATsave(BAT *b) __attribute__((__warn_unused_result__));
BAT *BATselect(BAT *b, BAT *s, const void *tl, const void *th, bool li, bool
hi, bool anti);
-gdk_return BATsemijoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr,
bool nil_matches, BUN estimate) __attribute__((__warn_unused_result__));
+gdk_return BATsemijoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr,
bool nil_matches, bool max_one, BUN estimate)
__attribute__((__warn_unused_result__));
gdk_return BATsetaccess(BAT *b, restrict_t mode);
void BATsetcapacity(BAT *b, BUN cnt);
void BATsetcount(BAT *b, BUN cnt);
@@ -810,7 +810,7 @@ str ALGfetchoid(ptr ret, const bat *bid,
str ALGfind(oid *ret, const bat *bid, ptr val);
str ALGfirstn(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
str ALGgroupby(bat *res, const bat *gids, const bat *cnts);
-str ALGintersect(bat *r1, const bat *lid, const bat *rid, const bat *slid,
const bat *srid, const bit *nil_matches, const lng *estimate);
+str ALGintersect(bat *r1, const bat *lid, const bat *rid, const bat *slid,
const bat *srid, const bit *nil_matches, const bit *max_one, const lng
*estimate);
str ALGjoin(bat *r1, bat *r2, const bat *l, const bat *r, const bat *sl, const
bat *sr, const bit *nil_matches, const lng *estimate);
str ALGjoin1(bat *r1, const bat *l, const bat *r, const bat *sl, const bat
*sr, const bit *nil_matches, const lng *estimate);
str ALGleftjoin(bat *r1, bat *r2, const bat *l, const bat *r, const bat *sl,
const bat *sr, const bit *nil_matches, const lng *estimate);
@@ -831,7 +831,7 @@ str ALGselect1nil(bat *result, const bat
str ALGselect2(bat *result, const bat *bid, const bat *sid, const void *low,
const void *high, const bit *li, const bit *hi, const bit *anti);
str ALGselect2nil(bat *result, const bat *bid, const bat *sid, const void
*low, const void *high, const bit *li, const bit *hi, const bit *anti, const
bit *unknown);
str ALGselectNotNil(bat *result, const bat *bid);
-str ALGsemijoin(bat *r1, bat *r2, const bat *l, const bat *r, const bat *sl,
const bat *sr, const bit *nil_matches, const lng *estimate);
+str ALGsemijoin(bat *r1, bat *r2, const bat *l, const bat *r, const bat *sl,
const bat *sr, const bit *nil_matches, const bit *max_one, const lng *estimate);
str ALGslice(bat *ret, const bat *bid, const lng *start, const lng *end);
str ALGslice_int(bat *ret, const bat *bid, const int *start, const int *end);
str ALGslice_lng(bat *ret, const bat *bid, const lng *start, const lng *end);
diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -1561,19 +1561,19 @@ AS_VAR_IF([have_zlib], [yes], [
AC_DEFINE([HAVE_LIBZ], 1, [Define if you have the z library])])
AM_CONDITIONAL([HAVE_LIBZ], [test x"$have_zlib" != xno])
-org_have_lzma=yes
-have_lzma=$org_have_lzma
+org_have_liblzma=yes
+have_liblzma=$org_have_liblzma
AC_ARG_WITH([lzma],
[AS_HELP_STRING([--with-lzma],
[include lzma support (default=yes)])],
- [have_lzma=$withval])
-AS_VAR_IF([have_lzma], [no], [], [
- PKG_CHECK_MODULES([liblzma], [liblzma], [have_lzma=yes], [have_lzma=no;
why_not_liblzma="(liblzma not found, install xz-libs and xz-devel)"])
- AS_VAR_IF([have_lzma], [yes], [
+ [have_liblzma=$withval])
+AS_VAR_IF([have_liblzma], [no], [], [
+ PKG_CHECK_MODULES([liblzma], [liblzma], [have_liblzma=yes],
[have_liblzma=no; why_not_liblzma="(liblzma not found, install xz-libs and
xz-devel)"])
+ AS_VAR_IF([have_liblzma], [yes], [
AC_SUBST([PKG_LIBLZMA], [liblzma])])
- AS_VAR_IF([have_lzma], [yes], [
+ AS_VAR_IF([have_liblzma], [yes], [
AC_DEFINE([HAVE_LIBLZMA], 1, [Define if you have the lzma
library])])])
-AM_CONDITIONAL([HAVE_LIBLZMA], [test x"$have_lzma" != xno])
+AM_CONDITIONAL([HAVE_LIBLZMA], [test x"$have_liblzma" != xno])
org_have_valgrind=no
have_valgrind=$org_have_valgrind
diff --git a/gdk/ChangeLog.Jun2020 b/gdk/ChangeLog.Jun2020
--- a/gdk/ChangeLog.Jun2020
+++ b/gdk/ChangeLog.Jun2020
@@ -1,6 +1,11 @@
# ChangeLog file for GDK
# This file is updated with Maddlog
+* Tue Apr 28 2020 Sjoerd Mullender <[email protected]>
+- The functions BATintersect and BATsemijoin have an extra argument,
+ bool max_one, which indicates that there must be no more than one
+ match in the join.
+
* Mon Apr 20 2020 Sjoerd Mullender <[email protected]>
- The "unique" property on BATs was removed. The property indicated
that all values in a BAT *had* to be distinct, but this was not
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -2056,9 +2056,9 @@ gdk_export gdk_return BATouterjoin(BAT *
__attribute__((__warn_unused_result__));
gdk_export gdk_return BATthetajoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT
*sl, BAT *sr, int op, bool nil_matches, BUN estimate)
__attribute__((__warn_unused_result__));
-gdk_export gdk_return BATsemijoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT
*sl, BAT *sr, bool nil_matches, BUN estimate)
+gdk_export gdk_return BATsemijoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT
*sl, BAT *sr, bool nil_matches, bool max_one, BUN estimate)
__attribute__((__warn_unused_result__));
-gdk_export BAT *BATintersect(BAT *l, BAT *r, BAT *sl, BAT *sr, bool
nil_matches, BUN estimate);
+gdk_export BAT *BATintersect(BAT *l, BAT *r, BAT *sl, BAT *sr, bool
nil_matches, bool max_one, BUN estimate);
gdk_export BAT *BATdiff(BAT *l, BAT *r, BAT *sl, BAT *sr, bool nil_matches,
bool not_in, BUN estimate);
gdk_export gdk_return BATjoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl,
BAT *sr, bool nil_matches, BUN estimate)
__attribute__((__warn_unused_result__));
diff --git a/gdk/gdk_firstn.c b/gdk/gdk_firstn.c
--- a/gdk/gdk_firstn.c
+++ b/gdk/gdk_firstn.c
@@ -1048,7 +1048,7 @@ BATfirstn_grouped(BAT **topn, BAT **gids
bn1 = bn;
BBPunfix(s->batCacheid);
- bn = BATintersect(b, b, su, bn1, true, BUN_NONE);
+ bn = BATintersect(b, b, su, bn1, true, false, BUN_NONE);
BBPunfix(bn1->batCacheid);
if (bn == NULL)
return GDK_FAIL;
@@ -1125,7 +1125,7 @@ BATfirstn_grouped_with_groups(BAT **topn
BBPunfix(bn2->batCacheid);
return GDK_FAIL;
}
- bn4 = BATintersect(s, bn2, NULL, NULL, false, BUN_NONE);
+ bn4 = BATintersect(s, bn2, NULL, NULL, false, false, BUN_NONE);
BBPunfix(bn2->batCacheid);
if (bn4 == NULL) {
BBPunfix(bn1->batCacheid);
@@ -1207,7 +1207,7 @@ BATfirstn_grouped_with_groups(BAT **topn
if (gids) {
BAT *bn1, *bn2, *bn3, *bn4, *bn5, *bn6, *bn7, *bn8;
- if ((bn1 = BATintersect(s, bn, NULL, NULL, false, BUN_NONE)) ==
NULL) {
+ if ((bn1 = BATintersect(s, bn, NULL, NULL, false, false,
BUN_NONE)) == NULL) {
BBPunfix(bn->batCacheid);
return GDK_FAIL;
}
diff --git a/gdk/gdk_join.c b/gdk/gdk_join.c
--- a/gdk/gdk_join.c
+++ b/gdk/gdk_join.c
@@ -1644,13 +1644,17 @@ mergejoin_cand(BAT **r1p, BAT **r2p, BAT
* there is a match of l in r, no matter how many matches there are in
* r; otherwise all matches are returned.
*
+ * If max_one is set, only a single match is allowed. This is like
+ * semi, but enforces the single match.
+ *
* t0 and swapped are only for debugging (ALGOMASK set in GDKdebug).
*/
static gdk_return
mergejoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r,
struct canditer *restrict lci, struct canditer *restrict rci,
bool nil_matches, bool nil_on_miss, bool semi, bool only_misses,
- bool not_in, BUN estimate, lng t0, bool swapped, const char *reason)
+ bool not_in, bool max_one, BUN estimate, lng t0, bool swapped,
+ const char *reason)
{
/* [lr]scan determine how far we look ahead in l/r in order to
* decide whether we want to do a binary search or a scan */
@@ -1681,7 +1685,7 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
if (lci->tpe == cand_dense && lci->ncand == BATcount(l) &&
rci->tpe == cand_dense && rci->ncand == BATcount(r) &&
- !nil_on_miss && !semi && !only_misses && !not_in &&
+ !nil_on_miss && !semi && !max_one && !only_misses && !not_in &&
l->tsorted && r->tsorted) {
/* special cases with far fewer options */
if (r->ttype == TYPE_void && r->tvheap)
@@ -1756,8 +1760,8 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
}
BUN maxsize = joininitresults(r1p, r2p, lci->ncand, rci->ncand,
- l->tkey, r->tkey, semi, nil_on_miss,
- only_misses, estimate);
+ l->tkey, r->tkey, semi | max_one,
+ nil_on_miss, only_misses, estimate);
if (maxsize == BUN_NONE)
return GDK_FAIL;
BAT *r1 = *r1p;
@@ -2159,6 +2163,9 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
r2->tseqbase = oid_nil;
r2->tkey = false;
}
+ } else if (nr > 1 && max_one) {
+ GDKerror("more than one match");
+ goto bailout;
} else if (only_misses) {
/* we had a match, so we're not interested */
lskipped = BATcount(r1) > 0;
@@ -2394,7 +2401,7 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
break; \
} \
HASHLOOPBODY(); \
- if (semi) \
+ if (semi && !max_one) \
break; \
} \
} else if (rci->tpe != cand_dense) { \
@@ -2409,7 +2416,7 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
break; \
} \
HASHLOOPBODY(); \
- if (semi) \
+ if (semi && !max_one) \
break; \
} \
} \
@@ -2425,7 +2432,7 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
} \
ro = (oid) (rb - roff + rseq); \
HASHLOOPBODY(); \
- if (semi) \
+ if (semi && !max_one) \
break; \
} \
} \
@@ -2434,7 +2441,7 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
if (only_misses) { \
nr = 1; \
if (maybeextend(r1, r2, 1, lci->next,
lci->ncand, maxsize) != GDK_SUCCEED) \
- goto bailout;
\
+ goto bailout; \
APPEND(r1, lo); \
if (lskipped) \
r1->tseqbase = oid_nil; \
@@ -2444,12 +2451,15 @@ mergejoin(BAT **r1p, BAT **r2p, BAT *l,
r2->tnonil = false; \
r2->tkey = false; \
if (maybeextend(r1, r2, 1, lci->next,
lci->ncand, maxsize) != GDK_SUCCEED) \
- goto bailout;
\
+ goto bailout; \
APPEND(r1, lo); \
APPEND(r2, oid_nil); \
} else { \
lskipped = BATcount(r1) > 0; \
} \
+ } else if (nr > 1 && max_one) { \
+ GDKerror("more than one match"); \
+ goto bailout; \
} else if (only_misses) { \
lskipped = BATcount(r1) > 0; \
} else { \
@@ -2476,7 +2486,7 @@ static gdk_return
hashjoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r,
struct canditer *restrict lci, struct canditer *restrict rci,
bool nil_matches, bool nil_on_miss, bool semi, bool only_misses,
- bool not_in,
+ bool not_in, bool max_one,
BUN estimate, lng t0, bool swapped, bool hash, bool phash,
const char *reason)
{
@@ -2522,8 +2532,8 @@ hashjoin(BAT **r1p, BAT **r2p, BAT *l, B
nil_on_miss, only_misses, __func__, t0);
BUN maxsize = joininitresults(r1p, r2p, lci->ncand, rci->ncand,
- l->tkey, r->tkey, semi, nil_on_miss,
- only_misses, estimate);
+ l->tkey, r->tkey, semi | max_one,
+ nil_on_miss, only_misses, estimate);
if (maxsize == BUN_NONE)
return GDK_FAIL;
@@ -2661,7 +2671,7 @@ hashjoin(BAT **r1p, BAT **r2p, BAT *l, B
break;
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list