# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0.  If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.

atom pcre;
command index(pat:pcre, s:str) :int
address PCREindex
comment "match a pattern, return matched position (or 0 when not found)";

command match(s:str, pat:str):bit
address PCREmatch
comment "Perl Compatible Regular Expression pattern matching against a string";

command imatch(s:str, pat:str):bit
address PCREimatch
comment "Caseless Perl Compatible Regular Expression pattern matching against a string";

command patindex(pat:str, s:str) :int
address PCREpatindex
comment "Location of the first POSIX pattern matching against a string";

command replace(origin:str,pat:str,repl:str,flags:str):str
address PCREreplace_wrap
comment "Replace _all_ matches of \"pattern\" in \"origin_str\" with \"replacement\".
	 Parameter \"flags\" accept these flags: 'i', 'm', 's', and 'x'.
	   'e': if present, an empty string is considered to be a valid match
	   'i': if present, the match operates in case-insensitive mode.
		Otherwise, in case-sensitive mode.
	   'm': if present, the match operates in multi-line mode.
	   's': if present, the match operates in \"dot-all\"
	   The specifications of the flags can be found in \"man pcreapi\"
	   The flag letters may be repeated.
	   No other letters than 'e', 'i', 'm', 's' and 'x' are allowed in \"flags\".
	   Returns the replaced string, or if no matches found, the original string.";

command replace(orig:bat[:str],pat:str,repl:str,flag:str):bat[:str]
address PCREreplace_bat_wrap;

command pcre_quote(s:str):str
address PCREquote
comment "Return a PCRE pattern string that matches the argument exactly.";

command sql2pcre(pat:str,esc:str):str
address PCREsql2pcre
comment "Convert a SQL like pattern with the given escape character into a PCRE pattern.";

command prelude() :void
address pcre_init
comment "Initialize pcre";

pcre.prelude();

command str.replace(origin:str,pat:str,repl:str,flags:str):str
address PCREreplace_wrap;

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[:str], pat:str, esc:str):bat[:bit] address BATPCRElike;
command batalgebra.like(s:bat[:str], pat:str):bat[:bit] address BATPCRElike2;
command batalgebra.not_like(s:bat[:str], pat:str, esc:str):bat[:bit] address BATPCREnotlike;
command batalgebra.not_like(s:bat[:str], pat:str):bat[:bit] address BATPCREnotlike2;
command batalgebra.ilike(s:bat[:str], pat:str, esc:str):bat[:bit] address BATPCREilike;
command batalgebra.ilike(s:bat[:str], pat:str):bat[:bit] address BATPCREilike2;
command batalgebra.not_ilike(s:bat[:str], pat:str, esc:str):bat[:bit] address BATPCREnotilike;
command batalgebra.not_ilike(s:bat[:str], pat:str):bat[:bit] address BATPCREnotilike2;

command algebra.likesubselect(b:bat[:str], s:bat[:oid], pat:str, esc:str, caseignore:bit, anti:bit) :bat[:oid]
address PCRElikesubselect2
comment "Select all head values of the first input BAT for which the
	tail value is \"like\" the given (SQL-style) pattern and for
	which the head value occurs in the tail of the second input
	BAT.
	Input is a dense-headed BAT, output is a dense-headed BAT with in
	the tail the head value of the input BAT for which the
	relationship holds.  The output BAT is sorted on the tail value.";

command algebra.likesubselect(b:bat[:str], cand:bat[:oid], pat:str, esc:str, anti:bit) :bat[:oid]
address PCRElikesubselect3;

command algebra.ilikesubselect(b:bat[:str], cand:bat[:oid], pat:str, esc:str, anti:bit) :bat[:oid]
address PCRElikesubselect1;

command algebra.likesubselect(b:bat[:str], cand:bat[:oid], pat:str, anti:bit) :bat[:oid]
address PCRElikesubselect5;

command algebra.ilikesubselect(b:bat[:str], cand:bat[:oid], pat:str, anti:bit) :bat[:oid]
address PCRElikesubselect4;

command algebra.likesubjoin(l:bat[:str],r:bat[:str],esc:str,sl:bat[:oid],sr:bat[:oid],nil_matches:bit,estimate:lng) (:bat[:oid],:bat[:oid])
address LIKEsubjoin
comment "Join the string bat L with the pattern bat R
with optional candidate lists SL and SR using pattern escape string ESC
and doing a case sensitive match.
The result is two aligned bats with oids of matching rows.";

command algebra.ilikesubjoin(l:bat[:str],r:bat[:str],esc:str,sl:bat[:oid],sr:bat[:oid],nil_matches:bit,estimate:lng) (:bat[:oid],:bat[:oid])
address ILIKEsubjoin
comment "Join the string bat L with the pattern bat R
with optional candidate lists SL and SR using pattern escape string ESC
and doing a case insensitive match.
The result is two aligned bats with oids of matching rows.";

command algebra.likesubjoin(l:bat[:str],r:bat[:str],sl:bat[:oid],sr:bat[:oid],nil_matches:bit,estimate:lng) (:bat[:oid],:bat[:oid])
address LIKEsubjoin1;

command algebra.ilikesubjoin(l:bat[:str],r:bat[:str],sl:bat[:oid],sr:bat[:oid],nil_matches:bit,estimate:lng) (:bat[:oid],:bat[:oid])
address ILIKEsubjoin1;
