Changeset: a5c7346f5424 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a5c7346f5424
Branch: default
Log Message:

Merged manti branch into default.


diffs (truncated from 1903 to 300 lines):

diff --git a/clients/Tests/MAL-signatures-hge.test 
b/clients/Tests/MAL-signatures-hge.test
--- a/clients/Tests/MAL-signatures-hge.test
+++ b/clients/Tests/MAL-signatures-hge.test
@@ -729,6 +729,7 @@ algebra     select  command algebra.select(X_
 algebra        select  command algebra.select(X_0:bat[:any_1], X_1:any_1, 
X_2:any_1, X_3:bit, X_4:bit, X_5:bit, X_6:bit):bat[:oid]     ALGselect1nil   
With unknown set, each nil != nil
 algebra        select  command algebra.select(X_0:bat[:any_1], X_1:bat[:oid], 
X_2:any_1, X_3:any_1, X_4:bit, X_5:bit, X_6:bit):bat[:oid]       ALGselect2     
 Select all head values of the first input BAT for which the tail value is in 
range and for which the head value occurs in the tail of the second input BAT. 
The first input is a dense-headed BAT, the second input is a dense-headed BAT 
with sorted tail, output is a dense-headed BAT with in the tail the head value 
of the input BAT for which the tail value is between the values low and high 
(inclusive if li respectively hi is set).  The output BAT is sorted on the tail 
value.  If low or high is nil, the boundary is not considered (effectively - 
and + infinity).  If anti is set, the result is the complement.  Nil values in 
the tail are never matched, unless low=nil, high=nil, li=1, hi=1, anti=0.  All 
non-nil values are returned if low=nil, high=nil, and li, hi are not both 1, or 
anti=1. Note that the output is suitable as second input for this functi
 on.
 algebra        select  command algebra.select(X_0:bat[:any_1], X_1:bat[:oid], 
X_2:any_1, X_3:any_1, X_4:bit, X_5:bit, X_6:bit, X_7:bit):bat[:oid]      
ALGselect2nil   With unknown set, each nil != nil
+algebra        selectNotFalse  command algebra.selectNotFalse(X_0:bat[:oid], 
X_1:bat[:bit], X_2:bat[:bit], X_3:bit) (X_4:bat[:oid], X_5:bat[:bit])     
ALGselectNotFalse       Return (gid, mark&&pred), if mark&&pred != FALSE. If 
'aggr', group on gid, return aggregated (gid, mark&&pred)
 algebra        selectNotNil    command 
algebra.selectNotNil(X_0:bat[:any_1]):bat[:any_1]       ALGselectNotNil Select 
all not-nil values
 algebra        semijoin        command algebra.semijoin(X_0:bat[:any_1], 
X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bit, X_5:bit, X_6:lng) 
(X_7:bat[:oid], X_8:bat[:oid])      ALGsemijoin     Semi join with candidate 
lists
 algebra        single  command algebra.single(X_0:bat[:oid], 
X_1:bat[:oid]):bat[:oid]  ALGsingle       Check for single result ids.
@@ -10108,6 +10109,7 @@ oahash  combined_probe  command oahash.com
 oahash combined_probe  command oahash.combined_probe(X_0:bat[:any_1], 
X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:lng], X_5:bit, X_6:bit) 
(X_7:bat[:oid], X_8:bat[:oid])   OAHASHprobe_cmbd_single Probe the selected 
`key`-s in the hash table. For a matched item, return its OID in the 'key' 
column and the slot ID in the hash table
 oahash empty   command oahash.empty(X_0:bat[:any_1]):bit       OAHASHempty     
Hash empty.
 oahash expand  pattern oahash.expand(X_0:bat[:oid], X_1:bat[:oid], 
X_2:bat[:lng], X_3:bit):bat[:oid]   OAHASHexpand    Expand the probe-side OIDs 
according to their matching hash-side GIDs and frequencies. If 'leftouter' is 
true, include the not matched OIDs
+oahash expand  pattern oahash.expand(X_0:bat[:oid], X_1:bat[:oid], 
X_2:bat[:bit], X_3:bat[:any], X_4:bat[:lng]) (X_5:bat[:oid], X_6:bat[:oid], 
X_7:bat[:bit])  OAHASHexpand3   Expand the probe-side OIDs, hash-side GIDs and 
the marks where NULL matches all
 oahash expand_cartesian        command 
oahash.expand_cartesian(X_0:bat[:any_1], X_1:bat[:any_2], X_2:bit):bat[:oid]    
OAHASHexpand_cart       Duplicate each value in 'col' the number of times as 
the count of 'rowrepeat'. For a left/right-outer join, if 'rowrepeat' is empty, 
output the values in 'col' once.
 oahash explode command oahash.explode(X_0:bat[:oid], X_1:bat[:lng], 
X_2:bat[:any_2], X_3:bit):bat[:oid]        OAHASHexplode   Explode the result 
vector 'frequency' times and return payload heap slot ids. If 'left_outer' is 
true, fill the not 'selected' slot with oid_nil
 oahash explode_cartesian       command 
oahash.explode_cartesian(X_0:bat[:any_1], X_1:bat[:2], X_2:bit):bat[:oid]       
OAHASHexplode_cart      Duplicate the whole 'col' the number of times as the 
count of 'setrepeat'.  For a left/right-ourter join, if 'col' is empty, output 
NULLs.
@@ -10116,8 +10118,8 @@ oahash  frequency       pattern oahash.frequenc
 oahash frequency       pattern oahash.frequency(X_0:bat[:oid]):bat[:lng]       
OAHASHadd_freq  Add `slot_id` to the shared `frequencies` BAT. Returns the 
updated `frequencies`
 oahash hash    pattern oahash.hash(X_0:any_1):lng      OAHASHhash      Compute 
hash.
 oahash hashmark_init   command oahash.hashmark_init(X_0:bat[:any_1], 
X_1:bat[:any_2]):bat[:bit]        OAHASHhashmark_init     (empty)
-oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bit, X_3:bit) (X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:bit]) OAHASHmprobe    
Probe the `key`-s in the hash table. For a matched key, return its OID in the 
'key' column and the slot ID in the hash table
-oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bat[:lng], X_3:bit, X_4:bit) (X_5:bat[:oid], X_6:bat[:oid], X_7:bat[:bit])  
OAHASHmprobe_single     Probe the `key`-s in the hash table. For a matched key, 
return its OID in the 'key' column and the slot ID in the hash table
+oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bit, X_3:bit, X_4:bit) (X_5:bat[:oid], X_6:bat[:oid], X_7:bat[:bit])        
OAHASHmprobe    Probe the `key`-s in the hash table. For a matched key, return 
its OID in the 'key' column and the slot ID in the hash table
+oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bat[:lng], X_3:bit, X_4:bit, X_5:bit) (X_6:bat[:oid], X_7:bat[:oid], 
X_8:bat[:bit]) OAHASHmprobe_single     Probe the `key`-s in the hash table. For 
a matched key, return its OID in the 'key' column and the slot ID in the hash 
table
 oahash new     pattern oahash.new(X_0:any_1, X_1:lng):bat[:any_1]      
OAHASHnew       (empty)
 oahash new     pattern oahash.new(X_0:any_1, X_1:lng, 
X_2:bat[:any_2]):bat[:any_1]     OAHASHnew       (empty)
 oahash new     pattern oahash.new(X_0:any_1, X_1:lng, X_2:bat[:any_2], 
X_3:int):bat[:any_1]    OAHASHnew       (empty)
diff --git a/clients/Tests/MAL-signatures.test 
b/clients/Tests/MAL-signatures.test
--- a/clients/Tests/MAL-signatures.test
+++ b/clients/Tests/MAL-signatures.test
@@ -616,6 +616,7 @@ algebra     select  command algebra.select(X_
 algebra        select  command algebra.select(X_0:bat[:any_1], X_1:any_1, 
X_2:any_1, X_3:bit, X_4:bit, X_5:bit, X_6:bit):bat[:oid]     ALGselect1nil   
With unknown set, each nil != nil
 algebra        select  command algebra.select(X_0:bat[:any_1], X_1:bat[:oid], 
X_2:any_1, X_3:any_1, X_4:bit, X_5:bit, X_6:bit):bat[:oid]       ALGselect2     
 Select all head values of the first input BAT for which the tail value is in 
range and for which the head value occurs in the tail of the second input BAT. 
The first input is a dense-headed BAT, the second input is a dense-headed BAT 
with sorted tail, output is a dense-headed BAT with in the tail the head value 
of the input BAT for which the tail value is between the values low and high 
(inclusive if li respectively hi is set).  The output BAT is sorted on the tail 
value.  If low or high is nil, the boundary is not considered (effectively - 
and + infinity).  If anti is set, the result is the complement.  Nil values in 
the tail are never matched, unless low=nil, high=nil, li=1, hi=1, anti=0.  All 
non-nil values are returned if low=nil, high=nil, and li, hi are not both 1, or 
anti=1. Note that the output is suitable as second input for this functi
 on.
 algebra        select  command algebra.select(X_0:bat[:any_1], X_1:bat[:oid], 
X_2:any_1, X_3:any_1, X_4:bit, X_5:bit, X_6:bit, X_7:bit):bat[:oid]      
ALGselect2nil   With unknown set, each nil != nil
+algebra        selectNotFalse  command algebra.selectNotFalse(X_0:bat[:oid], 
X_1:bat[:bit], X_2:bat[:bit], X_3:bit) (X_4:bat[:oid], X_5:bat[:bit])     
ALGselectNotFalse       Return (gid, mark&&pred), if mark&&pred != FALSE. If 
'aggr', group on gid, return aggregated (gid, mark&&pred)
 algebra        selectNotNil    command 
algebra.selectNotNil(X_0:bat[:any_1]):bat[:any_1]       ALGselectNotNil Select 
all not-nil values
 algebra        semijoin        command algebra.semijoin(X_0:bat[:any_1], 
X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bit, X_5:bit, X_6:lng) 
(X_7:bat[:oid], X_8:bat[:oid])      ALGsemijoin     Semi join with candidate 
lists
 algebra        single  command algebra.single(X_0:bat[:oid], 
X_1:bat[:oid]):bat[:oid]  ALGsingle       Check for single result ids.
@@ -7745,6 +7746,7 @@ oahash    combined_probe  command oahash.com
 oahash combined_probe  command oahash.combined_probe(X_0:bat[:any_1], 
X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:lng], X_5:bit, X_6:bit) 
(X_7:bat[:oid], X_8:bat[:oid])   OAHASHprobe_cmbd_single Probe the selected 
`key`-s in the hash table. For a matched item, return its OID in the 'key' 
column and the slot ID in the hash table
 oahash empty   command oahash.empty(X_0:bat[:any_1]):bit       OAHASHempty     
Hash empty.
 oahash expand  pattern oahash.expand(X_0:bat[:oid], X_1:bat[:oid], 
X_2:bat[:lng], X_3:bit):bat[:oid]   OAHASHexpand    Expand the probe-side OIDs 
according to their matching hash-side GIDs and frequencies. If 'leftouter' is 
true, include the not matched OIDs
+oahash expand  pattern oahash.expand(X_0:bat[:oid], X_1:bat[:oid], 
X_2:bat[:bit], X_3:bat[:any], X_4:bat[:lng]) (X_5:bat[:oid], X_6:bat[:oid], 
X_7:bat[:bit])  OAHASHexpand3   Expand the probe-side OIDs, hash-side GIDs and 
the marks where NULL matches all
 oahash expand_cartesian        command 
oahash.expand_cartesian(X_0:bat[:any_1], X_1:bat[:any_2], X_2:bit):bat[:oid]    
OAHASHexpand_cart       Duplicate each value in 'col' the number of times as 
the count of 'rowrepeat'. For a left/right-outer join, if 'rowrepeat' is empty, 
output the values in 'col' once.
 oahash explode command oahash.explode(X_0:bat[:oid], X_1:bat[:lng], 
X_2:bat[:any_2], X_3:bit):bat[:oid]        OAHASHexplode   Explode the result 
vector 'frequency' times and return payload heap slot ids. If 'left_outer' is 
true, fill the not 'selected' slot with oid_nil
 oahash explode_cartesian       command 
oahash.explode_cartesian(X_0:bat[:any_1], X_1:bat[:2], X_2:bit):bat[:oid]       
OAHASHexplode_cart      Duplicate the whole 'col' the number of times as the 
count of 'setrepeat'.  For a left/right-ourter join, if 'col' is empty, output 
NULLs.
@@ -7753,8 +7755,8 @@ oahash    frequency       pattern oahash.frequenc
 oahash frequency       pattern oahash.frequency(X_0:bat[:oid]):bat[:lng]       
OAHASHadd_freq  Add `slot_id` to the shared `frequencies` BAT. Returns the 
updated `frequencies`
 oahash hash    pattern oahash.hash(X_0:any_1):lng      OAHASHhash      Compute 
hash.
 oahash hashmark_init   command oahash.hashmark_init(X_0:bat[:any_1], 
X_1:bat[:any_2]):bat[:bit]        OAHASHhashmark_init     (empty)
-oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bit, X_3:bit) (X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:bit]) OAHASHmprobe    
Probe the `key`-s in the hash table. For a matched key, return its OID in the 
'key' column and the slot ID in the hash table
-oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bat[:lng], X_3:bit, X_4:bit) (X_5:bat[:oid], X_6:bat[:oid], X_7:bat[:bit])  
OAHASHmprobe_single     Probe the `key`-s in the hash table. For a matched key, 
return its OID in the 'key' column and the slot ID in the hash table
+oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bit, X_3:bit, X_4:bit) (X_5:bat[:oid], X_6:bat[:oid], X_7:bat[:bit])        
OAHASHmprobe    Probe the `key`-s in the hash table. For a matched key, return 
its OID in the 'key' column and the slot ID in the hash table
+oahash mprobe  command oahash.mprobe(X_0:bat[:any_1], X_1:bat[:any_1], 
X_2:bat[:lng], X_3:bit, X_4:bit, X_5:bit) (X_6:bat[:oid], X_7:bat[:oid], 
X_8:bat[:bit]) OAHASHmprobe_single     Probe the `key`-s in the hash table. For 
a matched key, return its OID in the 'key' column and the slot ID in the hash 
table
 oahash new     pattern oahash.new(X_0:any_1, X_1:lng):bat[:any_1]      
OAHASHnew       (empty)
 oahash new     pattern oahash.new(X_0:any_1, X_1:lng, 
X_2:bat[:any_2]):bat[:any_1]     OAHASHnew       (empty)
 oahash new     pattern oahash.new(X_0:any_1, X_1:lng, X_2:bat[:any_2], 
X_3:int):bat[:any_1]    OAHASHnew       (empty)
diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c
--- a/monetdb5/mal/mal_client.c
+++ b/monetdb5/mal/mal_client.c
@@ -54,7 +54,7 @@
 
 int MAL_MAXCLIENTS = 0;
 ClientRec *mal_clients = NULL;
-bool default_pipeline_mode = false;
+bool default_pipeline_mode = true;
 
 void
 mal_client_reset(void)
diff --git a/monetdb5/modules/kernel/algebra.c 
b/monetdb5/modules/kernel/algebra.c
--- a/monetdb5/modules/kernel/algebra.c
+++ b/monetdb5/modules/kernel/algebra.c
@@ -478,6 +478,91 @@ ALGmarkselect(Client ctx, bat *r1, bat *
 }
 
 static str
+ALGselectNotFalse(Client ctx, bat *r1, bat *r2, const bat *gid, const bat 
*mark, const bat *pred, const bit *Aggr)
+{
+       (void) ctx;
+       BAT *g = BATdescriptor(*gid); /* oid */
+       BAT *m = BATdescriptor(*mark); /* bit */
+       BAT *p = BATdescriptor(*pred); /* bit */
+       BAT *res1 = NULL, *res2 = NULL;
+       bit aggr = *Aggr;
+
+       if (!g || !m || !p)
+               goto error;
+       BUN nr = BATcount(g), q = 0;
+       assert (nr == BATcount(m) && nr == BATcount(p));
+
+       if ((res1 = COLnew(0, TYPE_oid, nr, TRANSIENT)) == NULL || (res2 = 
COLnew(0, TYPE_bit, nr, TRANSIENT)) == NULL)
+               goto error;
+       assert(g->tsorted);
+       oid *ri1 = Tloc(res1, 0);
+       bit *ri2 = Tloc(res2, 0);
+       bit *mi = Tloc(m, 0);
+       bit *pi = Tloc(p, 0);
+       oid c = g->hseqbase;
+
+       if (nr) {
+               if (!aggr || g->ttype == TYPE_void) { /* void case ? */
+                       for (BUN n = 0; n < nr; n++, c++) {
+                               ri1[q] = c;
+                               ri2[q] = (mi[n] == FALSE || pi[n] == 
FALSE)?FALSE:(mi[n] == bit_nil || pi[n] == bit_nil)?bit_nil:TRUE;
+                               q += (ri2[q] != FALSE); /* filter out the rows 
that are surely FALSE */
+                       }
+               } else { /* the aggregated variant */
+                       oid *gi = Tloc(g, 0);
+                       oid cur = gi[0];
+                       bit m = (mi[0] == FALSE || pi[0] == FALSE)?FALSE:(mi[0] 
== bit_nil || pi[0] == bit_nil)?bit_nil:TRUE;
+                       bool all_unequal = (m == FALSE)?TRUE:FALSE;
+                       for (BUN n = 1; n < nr; n++, c++) {
+                               if (cur != gi[n] && !all_unequal) {
+                                       ri1[q] = c;
+                                       ri2[q] = m;
+                                       q++;
+                                       cur = gi[n];
+                                       m = (mi[n] == FALSE || pi[n] == 
FALSE)?FALSE:(mi[n] == bit_nil || pi[n] == bit_nil)?bit_nil:TRUE;
+                                       all_unequal = (m == FALSE)?TRUE:FALSE;
+                               }
+                               m = (m == FALSE && (mi[n] == FALSE || pi[n] == 
FALSE))?FALSE:(m == bit_nil || mi[n] == bit_nil || pi[n] == 
bit_nil)?bit_nil:TRUE;
+                               all_unequal = all_unequal & (m == FALSE);
+                       }
+                       if (!all_unequal) {
+                               ri1[q] = c;
+                               ri2[q] = m;
+                               q++;
+                       }
+               }
+       }
+       BATsetcount(res1, q);
+       BATsetcount(res2, q);
+       res1->tsorted = true;
+       res1->tkey = true;
+       res1->trevsorted = false;
+       res2->tsorted = false;
+       res2->trevsorted = false;
+       res1->tnil = false;
+       res1->tnonil = true;
+       res2->tnonil = false;
+       res2->tkey = false;
+
+       BBPreclaim(g);
+       BBPreclaim(m);
+       BBPreclaim(p);
+
+       BBPkeepref(res1);
+       BBPkeepref(res2);
+       *r1 = res1->batCacheid;
+       *r2 = res2->batCacheid;
+       return MAL_SUCCEED;
+error:
+       BBPreclaim(g);
+       BBPreclaim(m);
+       BBPreclaim(p);
+       BBPreclaim(res1);
+       BBPreclaim(res2);
+       throw(MAL, "algebra.selectNotFalse", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+}
+
+static str
 ALGsingle(Client ctx, bat *r, bat *cands, bat *ids)
 {
        (void)ctx;
@@ -515,9 +600,9 @@ ALGouterselect(Client ctx, bat *r1, bat 
        bit any = *Any, single = *Single; /* any or normal comparison semantics 
*/
 
        if (!g || !m || !p) {
-               if (g) BBPreclaim(g);
-               if (m) BBPreclaim(m);
-               if (p) BBPreclaim(p);
+               BBPreclaim(g);
+               BBPreclaim(m);
+               BBPreclaim(p);
                throw(MAL, "algebra.outerselect", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
        }
        BUN nr = BATcount(g), q = 0;
@@ -526,7 +611,7 @@ ALGouterselect(Client ctx, bat *r1, bat 
                BBPreclaim(g);
                BBPreclaim(m);
                BBPreclaim(p);
-               if (res1) BBPreclaim(res1);
+               BBPreclaim(res1);
                throw(MAL, "algebra.outerselect", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
        }
        assert(g->tsorted);
@@ -534,10 +619,9 @@ ALGouterselect(Client ctx, bat *r1, bat 
        bit *ri2 = Tloc(res2, 0);
        bit *mi = Tloc(m, 0);
        bit *pi = Tloc(p, 0);
-       oid cur = oid_nil;
+       oid c = g->hseqbase;
 
        if (g->ttype == TYPE_void) { /* void case ? */
-               oid c = g->hseqbase;
                for (BUN n = 0; n < nr; n++, c++) {
                        ri1[q] = c;
                        ri2[q] = (any && (mi[n] == bit_nil || pi[n] == 
bit_nil))?bit_nil:(mi[n] == TRUE && pi[n] == TRUE)?TRUE:FALSE;
@@ -545,7 +629,7 @@ ALGouterselect(Client ctx, bat *r1, bat 
                }
        } else {
                oid *gi = Tloc(g, 0);
-               oid c = g->hseqbase;
+               oid cur = oid_nil;
                if (nr)
                        cur = gi[0];
                bool used = false;
@@ -618,7 +702,6 @@ error:
        throw(MAL, "algebra.outerselect", SQLSTATE(HY002) "more than one 
match");
 }
 
-
 static str
 ALGselectNotNil(Client ctx, bat *result, const bat *bid)
 {
@@ -2009,6 +2092,7 @@ static mel_func algebra_init_funcs[] = {
  command("algebra", "markselect", ALGmarkselect, false, "Group on group-ids, 
return aggregated anyequal or allnotequal", args(2,6, batarg("",oid), 
batarg("", bit), batarg("gid",oid), batarg("m", bit), batarg("p", bit), 
arg("any", bit))),
  command("algebra", "single", ALGsingle, false, "Check for single result 
ids.", args(1,3, batarg("r",oid), batarg("cands", oid), batarg("i", oid))),
  command("algebra", "outerselect", ALGouterselect, false, "Per input lid 
return at least one row, if none of the predicates (p) hold, return a nil, else 
'all' true cases.", args(2,7, batarg("",oid), batarg("", bit), batarg("lid", 
oid), batarg("rid", bit), batarg("predicate", bit), arg("any", bit), 
arg("single", bit))),
+ command("algebra", "selectNotFalse", ALGselectNotFalse, false, "Return (gid, 
mark&&pred), if mark&&pred != FALSE. If 'aggr', group on gid, return aggregated 
(gid, mark&&pred)", args(2,6, batarg("",oid), batarg("", bit), batarg("gid", 
oid), batarg("mark", bit), batarg("pred", bit), arg('aggr',bit))),
  command("algebra", "selectNotNil", ALGselectNotNil, false, "Select all 
not-nil values", args(1,2, batargany("",1),batargany("b",1))),
  command("algebra", "sort", ALGsort11, false, "Returns a copy of the BAT 
sorted on tail values. The order is descending if the reverse bit is set. This 
is a stable sort if the stable bit is set.", args(1,5, 
batargany("",1),batargany("b",1),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
  command("algebra", "sort", ALGsort12, false, "Returns a copy of the BAT 
sorted on tail values and a BAT that specifies how the input was reordered. The 
order is descending if the reverse bit is set. This is a stable sort if the 
stable bit is set.", args(2,6, 
batargany("",1),batarg("",oid),batargany("b",1),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
diff --git a/monetdb5/modules/mal/pp_hash.c b/monetdb5/modules/mal/pp_hash.c
--- a/monetdb5/modules/mal/pp_hash.c
+++ b/monetdb5/modules/mal/pp_hash.c
@@ -16,6 +16,7 @@
 #include "mal_instruction.h"
 #include "mal_exception.h"
 #include "mal_pipelines.h"
+#include "matomic.h"
 #include "pipeline.h"
 #include "stream.h"
 #include "pp_hash.h"
@@ -108,8 +109,9 @@ _ht_create( int type, size_t size, hash_
        h->type = type;
        h->width = ATOMsize(type);
        h->last = 0;
-       h->empty = true;
+       h->empty = 1;
        h->has_nil = 0;
+       h->gid_NULL = oid_nil;
        h->p = p;
        h->pinned = NULL;
        h->pinned_nr = 0; /* no more than 1024 */
@@ -888,8 +890,6 @@ UHASHext(Client cntxt, MalBlkPtr m, MalS
                Type *vals = h->vals; \
                \
                TIMEOUT_LOOP_IDX_DECL(i, cnt, qry_ctx) { \
-                       if (need_has_nil) \
-                               (void)ATOMIC_OR(&h->has_nil, 
is_##Type##_nil(bp[i])); \
                        bool fnd = 0; \
                        gid g = 0; \
                        while (!fnd) { \
@@ -923,6 +923,16 @@ UHASHext(Client cntxt, MalBlkPtr m, MalS
                                fnd = 1; \
                        } \
                        gp[i] = g-1; \
+                       if (need_has_nil) { \
+                               bit is_nil = is_##Type##_nil(bp[i]); \
+                               if (!h->has_nil && is_nil) {\
+                                       bit old_has_nil = (bit) 
ATOMIC_OR(&h->has_nil, is_nil); \
+                                       if (old_has_nil != (bit) h->has_nil) {\
+                                               assert(!old_has_nil && 
h->has_nil && is_oid_nil(h->gid_NULL)); \
+                                               ATOMIC_SET(&h->gid_NULL, 
gp[i]); \
+                                       } \
+                               } \
+                       } \
                } \
        } while (0)
 
@@ -1017,8 +1027,6 @@ UHASHext(Client cntxt, MalBlkPtr m, MalS
                Type *vals = h->vals; \
                \
                TIMEOUT_LOOP_IDX_DECL(i, cnt, qry_ctx) { \
-                       if (need_has_nil) \
-                               (void)ATOMIC_OR(&h->has_nil, 
is_##Type##_nil(bp[i])); \
                        bool fnd = 0; \
                        gid g = 0; \
                        while (!fnd) { \
@@ -1052,6 +1060,16 @@ UHASHext(Client cntxt, MalBlkPtr m, MalS
                                fnd = 1; \
                        } \
                        gp[i] = g-1; \
+                       if (need_has_nil) {\
+                               bit is_nil = is_##Type##_nil(bp[i]); \
+                               if (!h->has_nil && is_nil) {\
+                                       bit old_has_nil = (bit) 
ATOMIC_OR(&h->has_nil, is_nil); \
+                                       if (old_has_nil != (bit) h->has_nil) {\
+                                               assert(!old_has_nil && 
h->has_nil && is_oid_nil(h->gid_NULL)); \
+                                               ATOMIC_SET(&h->gid_NULL, 
gp[i]); \
+                                       } \
+                               } \
+                       } \
                } \
        } while (0)
 
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to