Changeset: 6e2ee08d11ca for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6e2ee08d11ca
Modified Files:
        monetdb5/modules/mal/pp_algebra.c
        monetdb5/modules/mal/pp_hash.c
        sql/server/rel_distribute.c
        sql/server/rel_unnest.c
        
sql/test/BugTracker-2010/Tests/ORDER_BY_over_UNION_EXCEPT_INTERSECT.Bug-2606.test
        
sql/test/BugTracker-2026/Tests/7968-optimize-distinct-from-q1-except-q2.test
        
sql/test/BugTracker-2026/Tests/7969-optimize-distinct-from-q1-intersect-q2.test
        sql/test/prepare/Tests/All
Branch: default
Log Message:

handle disinct intercept and except via semi/anti joins


diffs (truncated from 912 to 300 lines):

diff --git a/monetdb5/modules/mal/pp_algebra.c 
b/monetdb5/modules/mal/pp_algebra.c
--- a/monetdb5/modules/mal/pp_algebra.c
+++ b/monetdb5/modules/mal/pp_algebra.c
@@ -1448,49 +1448,7 @@ LALGgroup_unique_keepnil(Client ctx, bat
 
 #define vgroup()                                                               
                                \
        if (tt == TYPE_void) {                                                  
                        \
-               if (!BATtdense(b)) {                                            
                        \
-                       assert(cnt);                                            
                                \
-                       int slots = 0;                                          
                                \
-                       gid slot = 0;                                           
                                \
-                       oid bpi = b->tseqbase;                                  
                        \
-                       oid *vals = h->vals;                                    
                        \
-                                                                               
                                                \
-                       bool fnd = 0;                                           
                                \
-                       gid g = 0;                                              
                                        \
-                       for(; !fnd; ) {                                         
                                \
-                               gid k = (gid)oidHash(&oid_nil)&h->mask;         
        \
-                               g = ATOMIC_GET_GID(h->gids+k);                  
                \
-                               for(;g && vals[g] != bpi;) {                    
                \
-                                       k++;                                    
                                        \
-                                       k &= h->mask;                           
                                \
-                                       g = ATOMIC_GET_GID(h->gids+k);          
                \
-                               }                                               
                                                \
-                               if (!g) {                                       
                                        \
-                                       if (slots == 0) {                       
                                \
-                                               slots = ht_preclaim(private);   
                \
-                                               slot = ATOMIC_ADD_GID(&h->last, 
slots); \
-                                               if (((slot*100)/70) >= 
(gid)h->size) {  \
-                                                       hash_rehash(h, p, err); 
                        \
-                                                       vals = h->vals;         
                                \
-                                                       continue;               
                                        \
-                                               }                               
                                                \
-                                       }                                       
                                                \
-                                       slots--;                                
                                        \
-                                       g = ++slot;                             
                                        \
-                                       vals[g] = bpi;                          
                                \
-                                       if (!ATOMIC_CAS(h->gids+k, &expected, 
g)) { \
-                                               slot--;                         
                                        \
-                                               slots++;                        
                                        \
-                                               continue;                       
                                        \
-                                       }                                       
                                                \
-                               }                                               
                                                \
-                               fnd = 1;                                        
                                        \
-                       }                                                       
                                                \
-                       for(BUN i = 0; i<cnt; i++) {                            
                \
-                               gp[i] = g-1;                                    
                                \
-                       }                                                       
                                                \
-               } else {                                                        
                                        \
-                       assert(BATtdense(b));                                   
                        \
+               if (BATtdense(b)) {                                             
                                \
                        group_(oid,                                             
                                        \
                                   ,                                            
                                        \
                                   oid bp = b->tseqbase,                        
                        \
@@ -1501,7 +1459,18 @@ LALGgroup_unique_keepnil(Client ctx, bat
                                   ,                                            
                                        \
                                   nextk                                        
                                        \
                                )                                               
                                                \
-                               }                                               
                                                \
+               } else {                                                        
                                        \
+                       group_(oid,                                             
                                        \
+                                  ,                                            
                                        \
+                                  ,                                            
                                        \
+                                  oid bpi = oid_nil,                           
                        \
+                                  (gid)oidHash(&bpi),                          
                        \
+                                  vals[g] != bpi,                              
                                \
+                                  vals[g] = bpi,                               
                                \
+                                  ,                                            
                                        \
+                                  nextk                                        
                                        \
+                               )                                               
                                                \
+               }                                                               
                                                \
        }
 
 #define agroup_(Type,P)                                                        
                                                \
@@ -1769,8 +1738,8 @@ error:
 
 #define vderive()                                                              
\
        if (tt == TYPE_void) {                                          \
-               assert(BATtdense(b));                                   \
-               derive_(oid,                                                    
\
+               if (BATtdense(b)) {                                             
\
+                   derive_(oid,                                                
\
                                ,                                               
                \
                                oid bp = b->tseqbase,                   \
                                oid bpi = bp+i,                                 
\
@@ -1780,7 +1749,19 @@ error:
                                ,                                               
                \
                                nextk                                           
        \
                        )                                                       
                \
-                       }
+               } else {                                                        
        \
+                   derive_(oid,                                                
\
+                               ,                                               
                \
+                               ,                                               
                \
+                               oid bpi = oid_nil,                              
\
+                               (gid)oidHash(&bpi),                             
\
+                               vals[g] != bpi,                                 
\
+                               vals[g] = bpi,                                  
\
+                               ,                                               
                \
+                               nextk                                           
        \
+                       )                                                       
                \
+               }                                                               
                \
+       }
 
 #define aderive_(Type, P)                                                      
                                        \
        if (ATOMstorage(tt) == TYPE_str) {                                      
                                \
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
@@ -834,46 +834,86 @@ UHASHext(Client cntxt, MalBlkPtr m, MalS
 
 #define vgroup() \
        do { \
-               oid *vals = h->vals; \
-               struct canditer ci; \
-               canditer_init(&ci, NULL, b); \
-               cnt = ci.ncand; \
-               \
-               TIMEOUT_LOOP_IDX_DECL(i, cnt, qry_ctx) { \
-                       bool fnd = 0; \
-                       oid bpi = canditer_next(&ci); \
-                       assert(bpi != oid_nil); \
-                       gid g = 0; \
-                       while (!fnd) { \
-                               gid k = (gid)oidHash(&bpi)&h->mask; \
-                               g = ATOMIC_GET_GID(h->gids+k); \
-                               while (g && vals[g] != bpi) { \
-                                       k++; \
-                                       k &= h->mask; \
+               if (BATtdense(b)) { \
+                       oid *vals = h->vals; \
+                       struct canditer ci; \
+                       canditer_init(&ci, NULL, b); \
+                       cnt = ci.ncand; \
+                       \
+                       TIMEOUT_LOOP_IDX_DECL(i, cnt, qry_ctx) { \
+                               bool fnd = 0; \
+                               oid bpi = canditer_next(&ci); \
+                               gid g = 0; \
+                               while (!fnd) { \
+                                       gid k = (gid)oidHash(&bpi)&h->mask; \
                                        g = ATOMIC_GET_GID(h->gids+k); \
+                                       while (g && vals[g] != bpi) { \
+                                               k++; \
+                                               k &= h->mask; \
+                                               g = ATOMIC_GET_GID(h->gids+k); \
+                                       } \
+                                       if (!g) { \
+                                               if (slots == 0) { \
+                                                       slots = 
ht_preclaim(private); \
+                                                       slot = 
ATOMIC_ADD_GID(&h->last, slots); \
+                                                       if (((slot*100)/70) >= 
(gid)h->size) { \
+                                                               hash_rehash(h, 
pl, err); \
+                                                               vals = h->vals; 
\
+                                                               continue; \
+                                                       } \
+                                               } \
+                                               slots--; \
+                                               g = ++slot; \
+                                               vals[g] = bpi; \
+                                               if (!ATOMIC_CAS(h->gids+k, 
&expected, g)) { \
+                                                       slots++; \
+                                                       slot--; \
+                                                       continue; \
+                                               }\
+                                       } \
+                                       fnd = 1; \
                                } \
-                               if (!g) { \
-                                       if (slots == 0) { \
-                                               slots = ht_preclaim(private); \
-                                               slot = ATOMIC_ADD_GID(&h->last, 
slots); \
-                                               if (((slot*100)/70) >= 
(gid)h->size) { \
-                                                       hash_rehash(h, pl, 
err); \
-                                                       vals = h->vals; \
-                                                       continue; \
-                                               } \
+                               gp[i] = g-1; \
+                       } \
+               } else { \
+                       oid *vals = h->vals; \
+                       cnt = BATcount(b); \
+                       oid bpi = oid_nil; \
+                       \
+                       TIMEOUT_LOOP_IDX_DECL(i, cnt, qry_ctx) { \
+                               bool fnd = 0; \
+                               gid g = 0; \
+                               while (!fnd) { \
+                                       gid k = (gid)oidHash(&bpi)&h->mask; \
+                                       g = ATOMIC_GET_GID(h->gids+k); \
+                                       while (g && vals[g] != bpi) { \
+                                               k++; \
+                                               k &= h->mask; \
+                                               g = ATOMIC_GET_GID(h->gids+k); \
                                        } \
-                                       slots--; \
-                                       g = ++slot; \
-                                       vals[g] = bpi; \
-                                       if (!ATOMIC_CAS(h->gids+k, &expected, 
g)) { \
-                                               slots++; \
-                                               slot--; \
-                                               continue; \
-                                       }\
+                                       if (!g) { \
+                                               if (slots == 0) { \
+                                                       slots = 
ht_preclaim(private); \
+                                                       slot = 
ATOMIC_ADD_GID(&h->last, slots); \
+                                                       if (((slot*100)/70) >= 
(gid)h->size) { \
+                                                               hash_rehash(h, 
pl, err); \
+                                                               vals = h->vals; 
\
+                                                               continue; \
+                                                       } \
+                                               } \
+                                               slots--; \
+                                               g = ++slot; \
+                                               vals[g] = bpi; \
+                                               if (!ATOMIC_CAS(h->gids+k, 
&expected, g)) { \
+                                                       slots++; \
+                                                       slot--; \
+                                                       continue; \
+                                               }\
+                                       } \
+                                       fnd = 1; \
                                } \
-                               fnd = 1; \
+                               gp[i] = g-1; \
                        } \
-                       gp[i] = g-1; \
                } \
        } while (0)
 
@@ -1104,49 +1144,92 @@ UHASHext(Client cntxt, MalBlkPtr m, MalS
 
 #define vderive() \
        do { \
-               oid *vals = h->vals; \
-               struct canditer ci; \
-               canditer_init(&ci, NULL, b); \
-               cnt = ci.ncand; \
-               \
-               TIMEOUT_LOOP_IDX_DECL(i, cnt, qry_ctx) { \
-                       bool fnd = 0; \
-                       oid bpi = canditer_next(&ci); \
-                       assert(bpi != oid_nil); \
-                       gid g = 0; \
-                       while (!fnd) { \
-                               gid k = (gid)combine(gi[i], oidHash(&bpi), 
prime)&h->mask; \
-                               g = ATOMIC_GET_GID(h->gids+k); \
-                               while (g && (pgids[g] != gi[i] || vals[g] != 
bpi)) { \
-                                       k++; \
-                                       k &= h->mask; \
+               if (BATtdense(b)) { \
+                       oid *vals = h->vals; \
+                       struct canditer ci; \
+                       canditer_init(&ci, NULL, b); \
+                       cnt = ci.ncand; \
+                       \
+                       TIMEOUT_LOOP_IDX_DECL(i, cnt, qry_ctx) { \
+                               bool fnd = 0; \
+                               oid bpi = canditer_next(&ci); \
+                               gid g = 0; \
+                               while (!fnd) { \
+                                       gid k = (gid)combine(gi[i], 
oidHash(&bpi), prime)&h->mask; \
                                        g = ATOMIC_GET_GID(h->gids+k); \
-                               } \
-                               if (!g) { \
-                                       if (slots == 0) { \
-                                               slots = ht_preclaim(private); \
-                                               slot = ATOMIC_ADD_GID(&h->last, 
slots); \
-                                               if (((slot*100)/70) >= 
(gid)h->size) { \
-                                                       hash_rehash(h, pl, 
err); \
-                                                       vals = h->vals; \
-                                                       pgids = h->pgids; \
-                                                       prime = 
hash_prime_nr[h->bits-5]; \
+                                       while (g && (pgids[g] != gi[i] || 
vals[g] != bpi)) { \
+                                               k++; \
+                                               k &= h->mask; \
+                                               g = ATOMIC_GET_GID(h->gids+k); \
+                                       } \
+                                       if (!g) { \
+                                               if (slots == 0) { \
+                                                       slots = 
ht_preclaim(private); \
+                                                       slot = 
ATOMIC_ADD_GID(&h->last, slots); \
+                                                       if (((slot*100)/70) >= 
(gid)h->size) { \
+                                                               hash_rehash(h, 
pl, err); \
+                                                               vals = h->vals; 
\
+                                                               pgids = 
h->pgids; \
+                                                               prime = 
hash_prime_nr[h->bits-5]; \
+                                                               continue; \
+                                                       } \
+                                               } \
+                                               slots--; \
+                                               g = ++slot; \
+                                               vals[g] = bpi; \
+                                               pgids[g] = gi[i]; \
+                                               if (!ATOMIC_CAS(h->gids+k, 
&expected, g)) { \
+                                                       slots++; \
+                                                       slot--; \
                                                        continue; \
                                                } \
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to