MonetDB: mosaic - String (de)compress

2014-09-07 Thread Martin Kersten
Changeset: 995a6d4f6cd1 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=995a6d4f6cd1
Modified Files:
monetdb5/modules/mal/Tests/mosaic_literal.mal
monetdb5/modules/mal/mosaic.c
monetdb5/modules/mal/mosaic.mal
monetdb5/modules/mal/mosaic_delta.c
monetdb5/modules/mal/mosaic_dictionary.c
monetdb5/modules/mal/mosaic_linear.c
monetdb5/modules/mal/mosaic_runlength.c
monetdb5/modules/mal/mosaic_variance.c
monetdb5/optimizer/opt_mosaic.c
Branch: mosaic
Log Message:

String (de)compress
-the estimate storage size of a compressed block should include
space for a possible header of the next literal block
- string (de)compress over their tail columns included.
(value based operations pending)


diffs (truncated from 893 to 300 lines):

diff --git a/monetdb5/modules/mal/Tests/mosaic_literal.mal 
b/monetdb5/modules/mal/Tests/mosaic_literal.mal
--- a/monetdb5/modules/mal/Tests/mosaic_literal.mal
+++ b/monetdb5/modules/mal/Tests/mosaic_literal.mal
@@ -1,6 +1,3 @@
-# Compression of noncompressable column
-
-
 b:= bat.new(:oid,:int);
 bat.append(b,50);
 bat.append(b,19531015);
diff --git a/monetdb5/modules/mal/mosaic.c b/monetdb5/modules/mal/mosaic.c
--- a/monetdb5/modules/mal/mosaic.c
+++ b/monetdb5/modules/mal/mosaic.c
@@ -45,6 +45,7 @@ MOSinit(MOStask task, BAT *b){
base = Tloc(b,BUNfirst(b));
assert(base);
task-type = b-ttype;
+   task-b = b;
task-hdr = (MosaicHdr) base;
base += MosaicHdrSize;
task-blk = (MosaicBlk)  base;
@@ -223,6 +224,7 @@ MOScompressInternal(Client cntxt, int *r
case TYPE_wrd:
case TYPE_flt:
case TYPE_dbl:
+   case TYPE_str:
break;
default:
// don't compress them
@@ -250,12 +252,12 @@ MOScompressInternal(Client cntxt, int *r
 #endif
// allocate space for a compressed version.
// It should always take less space then the orginal column.
-   // But be prepared that a last block header may  be stored
+   // But be prepared that a header and last block header may  be stored
// use a size overshoot. Also be aware of possible dictionary headers
-   if (inplace)
+   //if (inplace)
bsrc = BATcopy(bcompress, bcompress-htype, bcompress-ttype, 
TRUE,TRANSIENT);
-   else
-   bsrc = BATnew(bcompress-htype, bcompress-ttype, 
BATgrows(bcompress), TRANSIENT);
+   if( !inplace)
+   bsrc = BATextend(bsrc, BATgrows(bsrc)+MosaicHdrSize);
 
if (bsrc == NULL) {
BBPreleaseref(bcompress-batCacheid);
@@ -273,7 +275,7 @@ MOScompressInternal(Client cntxt, int *r
 
if( inplace){
// initialize in place compression
-   bcompress = BATextend(bcompress, BATgrows(bcompress));
+   bcompress = BATextend(bcompress, 
BATgrows(bcompress)+MosaicHdrSize);
if( bcompress == NULL){
BBPreleaseref(bsrc-batCacheid);
throw(MAL,mosaic.compress, MAL_MALLOC_FAIL);
@@ -345,7 +347,6 @@ MOScompressInternal(Client cntxt, int *r
factor = fac;
}
}
-*/
if ( filter[MOSAIC_ZONE]){
fac = MOSestimate_zone(cntxt,task);
if (fac  factor){
@@ -353,6 +354,7 @@ MOScompressInternal(Client cntxt, int *r
factor = fac;
}
}
+*/
if ( filter[MOSAIC_DELTA]){
fac = MOSestimate_delta(cntxt,task);
if ( fac  factor ){
@@ -378,9 +380,9 @@ MOScompressInternal(Client cntxt, int *r
if( (MOSgetTag(task-blk) == MOSAIC_NONE || 
MOSgetTag(task-blk) == MOSAIC_ZONE)  MOSgetCnt(task-blk) ){
MOSupdateHeader(cntxt,task);
if( MOSgetTag(task-blk) == MOSAIC_NONE)
-   MOSskip_literal(cntxt,task);
+   MOSadvance_literal(cntxt,task);
else
-   MOSskip_zone(cntxt,task);
+   MOSadvance_zone(cntxt,task);
// always start with an EOL block
task-dst = ((char*) task-blk)+ MosaicBlkSize;
MOSsetTag(task-blk,MOSAIC_EOL);
@@ -391,9 +393,9 @@ MOScompressInternal(Client cntxt, int *r
if ( MOSgetCnt(task-blk) == MOSlimit()){
MOSupdateHeader(cntxt,task);
if( MOSgetTag(task-blk) == MOSAIC_NONE)
-   MOSskip_literal(cntxt,task);
+   MOSadvance_literal(cntxt,task);
else
-  

MonetDB: mosaic - Add missing str signatures

2014-09-07 Thread Martin Kersten
Changeset: d7e3cd1b6873 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d7e3cd1b6873
Modified Files:
monetdb5/modules/mal/mosaic.mal
Branch: mosaic
Log Message:

Add missing str signatures


diffs (53 lines):

diff --git a/monetdb5/modules/mal/mosaic.mal b/monetdb5/modules/mal/mosaic.mal
--- a/monetdb5/modules/mal/mosaic.mal
+++ b/monetdb5/modules/mal/mosaic.mal
@@ -69,6 +69,9 @@ address MOSsubselect;
 pattern subselect(b:bat[:oid,:dbl], low:dbl, high:dbl, li:bit, hi:bit, 
anti:bit) :bat[:oid,:oid]
 address MOSsubselect;
 
+pattern subselect(b:bat[:oid,:str], low:str, high:str, li:bit, hi:bit, 
anti:bit) :bat[:oid,:oid]
+address MOSsubselect;
+
 pattern subselect(b:bat[:oid,:timestamp], low:timestamp, high:timestamp, 
li:bit, hi:bit, anti:bit) :bat[:oid,:oid]
 address MOSsubselect
 comment Overloaded selection routine;
@@ -105,6 +108,9 @@ address MOSsubselect;
 pattern subselect(b:bat[:oid,:dbl], cand:bat[:oid,:oid], low:dbl, high:dbl, 
li:bit, hi:bit, anti:bit) :bat[:oid,:oid]
 address MOSsubselect;
 
+pattern subselect(b:bat[:oid,:str], cand:bat[:oid,:oid], low:str, high:str, 
li:bit, hi:bit, anti:bit) :bat[:oid,:oid]
+address MOSsubselect;
+
 pattern subselect(b:bat[:oid,:timestamp], cand:bat[:oid,:oid], low:timestamp, 
high:timestamp, li:bit, hi:bit, anti:bit) :bat[:oid,:oid]
 address MOSsubselect
 comment Overloaded selection routine;
@@ -141,6 +147,9 @@ address MOSthetasubselect;
 pattern thetasubselect(b:bat[:oid,:dbl], low:dbl, oper:str) :bat[:oid,:oid]
 address MOSthetasubselect;
 
+pattern thetasubselect(b:bat[:oid,:str], low:str, oper:str) :bat[:oid,:oid]
+address MOSthetasubselect;
+
 pattern thetasubselect(b:bat[:oid,:timestamp], low:timestamp, oper:str) 
:bat[:oid,:oid]
 address MOSthetasubselect
 comment Overloaded selection routine;
@@ -177,6 +186,9 @@ address MOSthetasubselect;
 pattern thetasubselect(b:bat[:oid,:dbl], c:bat[:oid,:oid], low:dbl, oper:str) 
:bat[:oid,:oid]
 address MOSthetasubselect;
 
+pattern thetasubselect(b:bat[:oid,:str], c:bat[:oid,:oid], low:str, oper:str) 
:bat[:oid,:oid]
+address MOSthetasubselect;
+
 pattern thetasubselect(b:bat[:oid,:timestamp], c:bat[:oid,:oid], 
low:timestamp, oper:str) :bat[:oid,:oid]
 address MOSthetasubselect
 comment Overloaded selection routine;
@@ -213,6 +225,9 @@ address MOSleftfetchjoin;
 pattern leftfetchjoin(b:bat[:oid,:oid], cand:bat[:oid,:dbl]) :bat[:oid,:dbl]
 address MOSleftfetchjoin;
 
+pattern leftfetchjoin(b:bat[:oid,:oid], cand:bat[:oid,:str]) :bat[:oid,:str]
+address MOSleftfetchjoin;
+
 pattern leftfetchjoin(b:bat[:oid,:oid], cand:bat[:oid,:timestamp]) 
:bat[:oid,:timestamp]
 address MOSleftfetchjoin
 comment Overloaded leftfetchjoin operation;
___
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list


MonetDB: mosaic - Enable variance dictionary compression

2014-09-07 Thread Martin Kersten
Changeset: 4c6cbebc02f9 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4c6cbebc02f9
Modified Files:
monetdb5/modules/mal/mosaic.c
monetdb5/modules/mal/mosaic_variance.c
Branch: mosaic
Log Message:

Enable variance dictionary compression


diffs (267 lines):

diff --git a/monetdb5/modules/mal/mosaic.c b/monetdb5/modules/mal/mosaic.c
--- a/monetdb5/modules/mal/mosaic.c
+++ b/monetdb5/modules/mal/mosaic.c
@@ -339,14 +339,14 @@ MOScompressInternal(Client cntxt, int *r
factor = fac;
}
}
-/*
if ( filter[MOSAIC_VARIANCE]){
fac = MOSestimate_variance(cntxt,task);
if (fac  factor){
-   cand = MOSAIC_DICT;
+   cand = MOSAIC_VARIANCE;
factor = fac;
}
}
+/*
if ( filter[MOSAIC_ZONE]){
fac = MOSestimate_zone(cntxt,task);
if (fac  factor){
diff --git a/monetdb5/modules/mal/mosaic_variance.c 
b/monetdb5/modules/mal/mosaic_variance.c
--- a/monetdb5/modules/mal/mosaic_variance.c
+++ b/monetdb5/modules/mal/mosaic_variance.c
@@ -29,6 +29,11 @@
 #include mosaic_dictionary.h
 #include mosaic_variance.h
 
+/*
+ * The dictionary size should be limited or a binary search is required
+ */
+static int vardictsize=8;
+
 void
 MOSadvance_variance(Client cntxt, MOStask task)
 {
@@ -37,23 +42,23 @@ MOSadvance_variance(Client cntxt, MOStas
task-start += MOSgetCnt(task-blk);
switch(ATOMstorage(task-type)){
//case TYPE_bte: case TYPE_bit: no compressionachievable
-   case TYPE_sht: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(sht)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),sht)); break;
-   case TYPE_int: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(int)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),int)); break;
-   case TYPE_oid: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(oid)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),oid)); break;
-   case TYPE_lng: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(lng)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),lng)); break;
-   case TYPE_wrd: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(wrd)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),wrd)); break;
-   case TYPE_flt: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(flt)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),flt)); break;
-   case TYPE_dbl: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(dbl)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),dbl)); break;
+   case TYPE_sht: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(sht)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),sht)); break;
+   case TYPE_int: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(int)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),int)); break;
+   case TYPE_oid: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(oid)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),oid)); break;
+   case TYPE_lng: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(lng)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),lng)); break;
+   case TYPE_wrd: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(wrd)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),wrd)); break;
+   case TYPE_flt: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(flt)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),flt)); break;
+   case TYPE_dbl: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(dbl)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),dbl)); break;
 #ifdef HAVE_HGE
-   case TYPE_hge: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(hge)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),hge)); break;
+   case TYPE_hge: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + vardictsize * sizeof(hge)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),hge)); break;
 #endif
case  TYPE_str:
// we only have to look at the index width, not the values
switch(task-b-T-width){
-   case 1: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(bte)+ wordaligned(sizeof(bte) * 
MOSgetCnt(task-blk),bte)); break;
-   case 2: task-blk = (MosaicBlk)( ((char*)task-blk) + 2* 
MosaicBlkSize + dictsize * sizeof(sht)+ wordaligned(sizeof(bte) * 

MonetDB: default - merged changes from Oct2014

2014-09-07 Thread Niels Nes
Changeset: eaca160265ed for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=eaca160265ed
Modified Files:
gdk/gdk.h
gdk/gdk_aggr.c
gdk/gdk_atoms.c
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_group.c
gdk/gdk_select.c
gdk/gdk_setop.c
gdk/gdk_value.c
monetdb5/mal/mal_instruction.c
sql/storage/bat/bat_table.c
sql/storage/store.c
sql/test/BugTracker-2009/Tests/primekeyconstraint.SF-2783425.stable.err
Branch: default
Log Message:

merged changes from Oct2014


diffs (truncated from 872 to 300 lines):

diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -1359,6 +1359,12 @@ gdk_export bte ATOMelmshift(int sz);
(b)-batCount++;\
} while (0)
 
+#define bunfastapp_nocheck_inc(b, p, t)\
+   do {\
+   bunfastapp_nocheck(b, p, t, Tsize(b));  \
+   p++;\
+   } while (0)
+
 #define bunfastapp(b, t)   \
do {\
register BUN _p = BUNlast(b);   \
@@ -2594,7 +2600,8 @@ gdk_export BAT *BATattach(int tt, const 
 #define putenv _putenv
 #endif
 
-/* also see VALget */
+/* Return a pointer to the value contained in V.  Also see VALget
+ * which returns a void *. */
 static inline const void *
 VALptr(const ValRecord *v)
 {
@@ -3346,7 +3353,6 @@ gdk_export BAT *BATsample(BAT *b, BUN n)
 /*
  *
  */
-#define ILLEGALVALUE   ((ptr)-1L)
 #define MAXPARAMS  32
 
 #ifndef NDEBUG
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -1497,6 +1497,8 @@ BATgroupavg(BAT **bnp, BAT **cntsp, BAT 
(*cntsp)-tkey = BATcount(*cntsp) = 1;
(*cntsp)-tsorted = BATcount(*cntsp) = 1;
(*cntsp)-trevsorted = BATcount(*cntsp) = 1;
+   (*cntsp)-T-nil = 0;
+   (*cntsp)-T-nonil = 1;
}
BATsetcount(bn, ngrp);
BATseqbase(bn, min);
diff --git a/gdk/gdk_atoms.c b/gdk/gdk_atoms.c
--- a/gdk/gdk_atoms.c
+++ b/gdk/gdk_atoms.c
@@ -348,11 +348,9 @@ ATOMformat(int t, const void *p, char **
 {
int (*tostr) (str *, int *, const void *);
 
-   if (p  0 = t  t  GDKatomcnt 
-   (tostr = BATatoms[t].atomToStr)) {
-   int sz = 0, l = (*tostr) (buf, sz, p);
-
-   return l;
+   if (p  0 = t  t  GDKatomcnt  (tostr = BATatoms[t].atomToStr)) {
+   int sz = 0;
+   return (*tostr) (buf, sz, p);
}
*buf = GDKmalloc(4);
if (*buf == NULL)
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -967,35 +967,35 @@ BATcopy(BAT *b, int ht, int tt, int writ
if (ATOMtype(ht) == ATOMtype(b-htype)) {
ALIGNsetH(bn, b);
} else if (ATOMtype(ATOMstorage(ht)) == 
ATOMtype(ATOMstorage(b-htype))) {
-   bn-hsorted = b-hsorted || (cnt = 1  
BATatoms[b-htype].linear);
-   bn-hrevsorted = b-hrevsorted || (cnt = 1  
BATatoms[b-htype].linear);
+   bn-hsorted = b-hsorted;
+   bn-hrevsorted = b-hrevsorted;
bn-hdense = b-hdense  ATOMtype(bn-htype) == TYPE_oid;
if (b-hkey)
BATkey(bn, TRUE);
bn-H-nonil = b-H-nonil;
} else {
-   bn-hsorted = bn-hrevsorted = (cnt = 1  
BATatoms[b-htype].linear);
+   bn-hsorted = bn-hrevsorted = 0; /* set based on count later */
bn-hdense = bn-H-nonil = 0;
}
if (ATOMtype(tt) == ATOMtype(b-ttype)) {
ALIGNsetT(bn, b);
} else if (ATOMtype(ATOMstorage(tt)) == 
ATOMtype(ATOMstorage(b-ttype))) {
-   bn-tsorted = b-tsorted || (cnt = 1  
BATatoms[b-ttype].linear);
-   bn-trevsorted = b-trevsorted || (cnt = 1  
BATatoms[b-ttype].linear);
+   bn-tsorted = b-tsorted;
+   bn-trevsorted = b-trevsorted;
bn-tdense = b-tdense  ATOMtype(bn-ttype) == TYPE_oid;
if (b-tkey)
BATkey(BATmirror(bn), TRUE);
bn-T-nonil = b-T-nonil;
} else {
-   bn-tsorted = bn-trevsorted = (cnt = 1  
BATatoms[b-ttype].linear);
+   bn-tsorted = bn-trevsorted = 0; /* set based on count later */
bn-tdense = bn-T-nonil = 0;
}
if (BATcount(bn) = 1) {
-   bn-hsorted = 1;
-   bn-hrevsorted = 1;
+   bn-hsorted = BATatoms[b-htype].linear;
+   bn-hrevsorted = BATatoms[b-htype].linear;
bn-hkey = 1;
-   bn-tsorted = 1;
-   bn-trevsorted = 1;
+   bn-tsorted = BATatoms[b-ttype].linear;
+   bn-trevsorted = 

MonetDB: default - generalized filter functions (old version was...

2014-09-07 Thread Niels Nes
Changeset: b132e9477d66 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b132e9477d66
Modified Files:
monetdb5/modules/mal/pcre.mal
sql/backends/monet5/LSST/Tests/lsst_htmxmatch.sql
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql_gencode.c
sql/backends/monet5/sql_statement.c
sql/backends/monet5/sql_statement.h
sql/benchmarks/tpch/Tests/02-plan.stable.out
sql/benchmarks/tpch/Tests/09-plan.stable.out.int128
sql/benchmarks/tpch/Tests/13-plan.stable.out
sql/benchmarks/tpch/Tests/16-plan.stable.out
sql/benchmarks/tpch/Tests/17-explain.stable.out.int128
sql/benchmarks/tpch/Tests/17-plan.stable.out.int128
sql/benchmarks/tpch/Tests/20-explain.stable.out.int128
sql/benchmarks/tpch/Tests/20-plan.stable.out.int128
sql/server/rel_dump.c
sql/server/rel_exp.c
sql/server/rel_exp.h
sql/server/rel_optimizer.c
sql/server/rel_select.c
sql/server/sql_parser.y
sql/test/BugTracker-2009/Tests/primekeyconstraint.SF-2783425.stable.err
sql/test/leaks/Tests/check1.stable.out.int128
sql/test/leaks/Tests/check2.stable.out.int128
sql/test/leaks/Tests/check3.stable.out.int128
sql/test/leaks/Tests/check4.stable.out.int128
sql/test/leaks/Tests/check5.stable.out.int128
sql/test/leaks/Tests/select1.stable.out.int128
sql/test/leaks/Tests/select2.stable.out.int128
Branch: default
Log Message:

generalized filter functions (old version was limited to l filter (r, option),
ie for like filters).
New syntax is  [ l0, l1 .., ln ] Filter_Op [ r0, r1, .., rn ] where
l0 and r0 are the columns to join/select over.
Extra columns/options can be passed using the l1 to ln and r1 to rn.

Currently the filter functions could be added to the system using
create filter function name( scalar types) external name mod.name;
In mal we assume (require) mod.name functions to exist for the subselect
and subjoin variations. See subjoin/select and likesubselect variants.

Also bit returning map operators are needed (if select/join isn't the first
operator on a relation). These have the form (l0, ..ln, r0, ..rn):= bit.
For now the name should be 'mod'.sqlname. Where the sqlname is the name
given to the function within sql.

Probably we cleanup this requirement and add some documentation ;-).


diffs (truncated from 1839 to 300 lines):

diff --git a/monetdb5/modules/mal/pcre.mal b/monetdb5/modules/mal/pcre.mal
--- a/monetdb5/modules/mal/pcre.mal
+++ b/monetdb5/modules/mal/pcre.mal
@@ -118,6 +118,25 @@ address BATPCREnotilike;
 command batstr.not_ilike(s:bat[:oid,:str], pat:str):bat[:oid,:bit]
 address BATPCREnotilike2;
 
+command algebra.like(s:str, pat:str, esc:str):bit address PCRElike3;
+command algebra.like(s:str, pat:str):bit address PCRElike2;
+command algebra.not_like(s:str, pat:str, esc:str):bit address PCREnotlike3;
+command algebra.not_like(s:str, pat:str):bit address PCREnotlike2;
+command algebra.ilike(s:str, pat:str, esc:str):bit address PCREilike3;
+command algebra.ilike(s:str, pat:str):bit address PCREilike2;
+command algebra.not_ilike(s:str, pat:str, esc:str):bit address PCREnotilike3;
+command algebra.not_ilike(s:str, pat:str):bit address PCREnotilike2;
+
+module batalgebra;
+command batalgebra.like(s:bat[:oid,:str], pat:str, esc:str):bat[:oid,:bit] 
address BATPCRElike;
+command batalgebra.like(s:bat[:oid,:str], pat:str):bat[:oid,:bit] address 
BATPCRElike2;
+command batalgebra.not_like(s:bat[:oid,:str], pat:str, esc:str):bat[:oid,:bit] 
address BATPCREnotlike;
+command batalgebra.not_like(s:bat[:oid,:str], pat:str):bat[:oid,:bit] address 
BATPCREnotlike2;
+command batalgebra.ilike(s:bat[:oid,:str], pat:str, esc:str):bat[:oid,:bit] 
address BATPCREilike;
+command batalgebra.ilike(s:bat[:oid,:str], pat:str):bat[:oid,:bit] address 
BATPCREilike2;
+command batalgebra.not_ilike(s:bat[:oid,:str], pat:str, 
esc:str):bat[:oid,:bit] address BATPCREnotilike;
+command batalgebra.not_ilike(s:bat[:oid,:str], pat:str):bat[:oid,:bit] address 
BATPCREnotliike2;
+
 command algebra.likesubselect(b:bat[:oid,:str], pat:str, esc:str, 
caseignore:bit, anti:bit) :bat[:oid,:oid]
 address PCRElikesubselect1
 comment Select all head values for which the tail value is \like\
diff --git a/sql/backends/monet5/LSST/Tests/lsst_htmxmatch.sql 
b/sql/backends/monet5/LSST/Tests/lsst_htmxmatch.sql
--- a/sql/backends/monet5/LSST/Tests/lsst_htmxmatch.sql
+++ b/sql/backends/monet5/LSST/Tests/lsst_htmxmatch.sql
@@ -5,9 +5,9 @@ insert into htm values (120), (121), (12
 insert into htm values (130), (131), (132), (133);
 
 -- select identical pairs
-select  * from htm a, htm b where a.id xmatch(0) b.id;
+select  * from htm a, htm b where [a.id] xmatch [b.id,0];
 
 -- select pairs at distance one
-select  * from htm a, htm b where a.id xmatch(1) b.id;
+select  * from htm a, htm b where [a.id] xmatch [b.id,1];
 
 drop table htm;
diff --git