# 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.

module batsql;
module sql;

pattern start():void 
address SQLsession
comment "Switch to processing SQL statements";

pattern start2():void
address SQLsession2
comment "Switch to processing precompiled sql statements";

pattern init():void
address SQLinitEnvironment
comment "Initialize the environment for MAL";

pattern shutdown(delay:bte, force:bit):str
address SQLshutdown_wrap;
pattern shutdown(delay:sht, force:bit):str
address SQLshutdown_wrap;
pattern shutdown(delay:int, force:bit):str
address SQLshutdown_wrap;

pattern shutdown(delay:bte):str
address SQLshutdown_wrap;
pattern shutdown(delay:sht):str
address SQLshutdown_wrap;
pattern shutdown(delay:int):str
address SQLshutdown_wrap;

pattern mvc():int
address SQLmvc
comment "Get the multiversion catalog context. 
Needed for correct statement dependencies
(ie sql.update, should be after sql.bind in concurrent execution)";

pattern trans(type:int,chain:int,name:str):void
address SQLtransaction
comment "A transaction statement (type can be commit,release,rollback or start)";

unsafe pattern transaction()
address SQLtransaction2
comment "Start an autocommit transaction";

pattern commit()
address SQLcommit
comment "Trigger the commit operation for a MAL block";

pattern abort()
address SQLabort
comment "Trigger the abort operation for a MAL block";

pattern catalog(type:int,sname:str,name:str,action:int):void
address SQLcatalog
comment "a catalog statement";

pattern catalog(type:int,sname:str,name:str,funcid:int,ft:int,action:int):void
address SQLcatalog
comment "a catalog statement";

pattern catalog(type:int,sname:str,name:str,tname:str,time:int,o:int,event:int,oname:str,nname:str,condition:str,query:str):void
address SQLcatalog
comment "a catalog statement";

pattern catalog(type:int,sname:str,t:ptr):void
address SQLcatalog
comment "a catalog statement";

pattern catalog(type:int,sname:str,t:ptr,temp:int):void
address SQLcatalog
comment "a catalog statement";

pattern catalog(type:int,sname:str,t:ptr,restart:lng):void
address SQLcatalog
comment "a catalog statement";

pattern catalog(type:int,sname:str,tname:str):void
address SQLcatalog
comment "a catalog trigger statement";

pattern catalog(type:int,grantee:str,role:str,grantor:int,admin:int):void
address SQLcatalog
comment "a grant/revoke role statement";

pattern catalog(type:int,user:str,passwd:str,enc:int,schema:str,fullname:str):void
address SQLcatalog
comment "a user catalog statement";

pattern catalog(type:int,sname:str,tname:str,grantee:str,privs:int,cname:str,grant:int,grantor:int):void
address SQLcatalog
comment "a grant/revoke privileges statement";

pattern catalog(type:int,sname:str,func:int,grantee:str,privs:int,grant:int,grantor:int):void
address SQLcatalog
comment "a grant/revoke function privileges statement";

pattern catalog(type:int,iname:str,itype:int,sname:str,tname:str...):void
address SQLcatalog
comment "a create index catalog statement";

pattern catalog(type:int,sname:str,tname:str,access:int):void
address SQLcatalog
comment "a alter table access statement";

pattern catalog(type:int,msname:str,mtname:str,psname:str,ptname:str,action:int):void
address SQLcatalog
comment "a alter table add/del table catalog statement";

pattern catalog(type:int,sname:str,tname:str,impl:str):void
address SQLcatalog
comment "a create type catalog statement";

pattern eval(cmd:str):void 
address SQLstatement
comment "Compile and execute a single sql statement";
pattern eval(cmd:str, output:bit):void 
address SQLstatement
comment "Compile and execute a single sql statement (and optionaly send output on the output stream)";

pattern include(fname:str):void 
address SQLinclude
comment "Compile and execute a sql statements on the file";

pattern evalAlgebra(cmd:str, optimize:bit):void
address RAstatement
comment "Compile and execute a single 'relational algebra' statement";

pattern register(mod:str, fname:str, rel_stmt:str, sig:str):int
address RAstatement2
comment "Compile the relational statement (rel_smt) and register it as mal function, mod.fname(signature)";

command flush_log( ) :void
address SQLflush_log
comment "flush the log now";

pattern assert(b:bit,msg:str):void
address SQLassert
comment "Generate an exception when b==true";
pattern assert(b:int,msg:str):void
address SQLassertInt
comment "Generate an exception when b!=0";
pattern assert(b:lng,msg:str):void
address SQLassertLng
comment "Generate an exception when b!=0";

pattern setVariable(mvc:int, varname:str, value:any_1 ):int
address setVariable
comment "Set the value of a session variable";

pattern getVariable(mvc:int, varname:str ):any_1
address getVariable
comment "Get the value of a session variable";

unsafe pattern logfile(filename:str):void 
address mvc_logfile
comment "Enable/disable saving the sql statement traces";

pattern next_value( sname:str, sequence:str ):lng
address mvc_next_value
comment "return the next value of the sequence";

pattern batsql.next_value( sname:bat[:str], sequence:str ) :bat[:lng]
address mvc_bat_next_value
comment "return the next value of the sequence";

pattern get_value( sname:str, sequence:str ):lng
address mvc_get_value
comment "return the current value of the sequence";

unsafe pattern restart( sname:str, sequence:str, start:lng ):lng
address mvc_restart_seq
comment "restart the sequence with value start";

pattern emptybindidx(mvc:int, schema:str, table:str, index:str, access:int):bat[:any_1]
address mvc_bind_idxbat_wrap;
pattern bind_idxbat(mvc:int, schema:str, table:str, index:str, access:int):bat[:any_1]
address mvc_bind_idxbat_wrap
comment "Bind the 'schema.table.index' BAT with access kind:
	0 - base table
	1 - inserts
	2 - updates";

pattern emptybindidx(mvc:int, schema:str, table:str, index:str, access:int)(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_idxbat_wrap;
pattern bind_idxbat(mvc:int, schema:str, table:str, index:str, access:int)(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_idxbat_wrap
comment "Bind the 'schema.table.index' BAT with access kind:
	0 - base table
	1 - inserts
	2 - updates";

pattern emptybindidx(mvc:int, schema:str, table:str, index:str, access:int, part_nr:int, nr_parts:int):bat[:any_1]
address mvc_bind_idxbat_wrap;
pattern bind_idxbat(mvc:int, schema:str, table:str, index:str, access:int, part_nr:int, nr_parts:int):bat[:any_1]
address mvc_bind_idxbat_wrap
comment "Bind the 'schema.table.index' BAT with access kind:
	0 - base table
	1 - inserts
	2 - updates";

pattern emptybindidx(mvc:int, schema:str, table:str, index:str, access:int, part_nr:int, nr_parts:int)(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_idxbat_wrap;
pattern bind_idxbat(mvc:int, schema:str, table:str, index:str, access:int, part_nr:int, nr_parts:int)(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_idxbat_wrap
comment "Bind the 'schema.table.index' BAT with access kind:
	0 - base table
	1 - inserts
	2 - updates";

pattern emptybind(mvc:int, schema:str, table:str, column:str, access:int ):bat[:any_1]
address mvc_bind_wrap;
pattern bind(mvc:int, schema:str, table:str, column:str, access:int ):bat[:any_1]
address mvc_bind_wrap
comment "Bind the 'schema.table.column' BAT with access kind:
	0 - base table
	1 - inserts
	2 - updates";

pattern emptybind(mvc:int, schema:str, table:str, column:str, access:int )(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_wrap;
pattern bind(mvc:int, schema:str, table:str, column:str, access:int )(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_wrap
comment "Bind the 'schema.table.column' BAT with access kind:
	0 - base table
	1 - inserts
	2 - updates";

pattern emptybind(mvc:int, schema:str, table:str, column:str, access:int, part_nr:int, nr_parts:int ):bat[:any_1]
address mvc_bind_wrap;
pattern bind(mvc:int, schema:str, table:str, column:str, access:int, part_nr:int, nr_parts:int ):bat[:any_1]
address mvc_bind_wrap
comment "Bind the 'schema.table.column' BAT partition with access kind:
	0 - base table
	1 - inserts
	2 - updates";

pattern emptybind(mvc:int, schema:str, table:str, column:str, access:int, part_nr:int, nr_parts:int )(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_wrap;
pattern bind(mvc:int, schema:str, table:str, column:str, access:int, part_nr:int, nr_parts:int )(uid:bat[:oid],uval:bat[:any_1])
address mvc_bind_wrap
comment "Bind the 'schema.table.column' BAT with access kind:
	0 - base table
	1 - inserts
	2 - updates";

command delta( col:bat[:any_3], uid:bat[:oid], uval:bat[:any_3], ins:bat[:any_3] )
		:bat[:any_3] 
address DELTAbat
comment "Return column bat with delta's applied.";

command projectdelta( subselect:bat[:oid], col:bat[:any_3], uid:bat[:oid], uval:bat[:any_3], ins:bat[:any_3] ) :bat[:any_3] 
address DELTAproject
comment "Return column bat with delta's applied.";

command subdelta( col:bat[:oid], cand:bat[:oid], uid:bat[:oid], uval:bat[:oid], ins:bat[:oid] ) :bat[:oid]
address DELTAsub
comment "Return a single bat of subselected delta.";

command delta( col:bat[:any_3], uid:bat[:oid], uval:bat[:any_3]) :bat[:any_3] 
address DELTAbat2
comment "Return column bat with delta's applied.";

command projectdelta( subselect:bat[:oid], col:bat[:any_3], uid:bat[:oid], uval:bat[:any_3]) :bat[:any_3] 
address DELTAproject2
comment "Return column bat with delta's applied.";

command subdelta( col:bat[:oid], cand:bat[:oid], uid:bat[:oid], uval:bat[:oid]) :bat[:oid]
address DELTAsub2
comment "Return a single bat of subselected delta.";

command project( col:bat[:oid], l:bat[:oid], r:bat[:oid]) :bat[:oid]
address BATleftproject
comment "Last step of a left outer join, ie project the inner join (l,r) over the left input side (col)"

command getVersion(clientid:int):lng
address mvc_getVersion
comment "Return the database version identifier for a client";

pattern append(mvc:int, sname:str, tname:str, cname:str, ins:any):int
address mvc_append_wrap
comment "Append b to the column tname.cname (possibly optimized to replace the insert bat of tname.cname (returns sequence number for order dependence)";

pattern update(mvc:int, sname:str, tname:str, cname:str, rids:any, upd:any):int
address mvc_update_wrap
comment "Update the values of the column tname.cname";

unsafe pattern clear_table(sname:str, tname:str) :lng
address mvc_clear_table_wrap
comment "Clear table";

pattern tid( mvc:int, sname:str, tname:str):bat[:oid] 
address SQLtid
comment "Return the tables tid column.";
pattern tid( mvc:int, sname:str, tname:str, part_nr:int, nr_parts:int ):bat[:oid] 
address SQLtid
comment "Return the tables tid column.";

unsafe pattern delete(mvc:int, sname:str, tname:str, b:any):int
address mvc_delete_wrap
comment "delete from table";

unsafe pattern resultSet(tbl:str, attr:str, tpe:str, len:int, scale:int, eclass:int, val:any) :int 
address mvc_scalar_value_wrap
comment "Prepare a table result set";

unsafe pattern resultSet(tbl:bat[:str], attr:bat[:str], tpe:bat[:str], len:bat[:int],scale:bat[:int], cols:any...) :int 
address mvc_row_result_wrap
comment "Prepare a table result set";

unsafe pattern resultSet(tbl:bat[:str], attr:bat[:str], tpe:bat[:str], len:bat[:int],scale:bat[:int], cols:bat[:any]...) :int 
address mvc_table_result_wrap
comment "Prepare a table result set for the client in default CSV format";

unsafe pattern export_table(fname:str, fmt:str, colsep:str, recsep:str, qout:str, nullrep:str, tbl:bat[:str], attr:bat[:str], tpe:bat[:str], len:bat[:int],scale:bat[:int], cols:any...) :int 
address mvc_export_row_wrap
comment "Prepare a table result set for the COPY INTO stream";
unsafe pattern export_table(fname:str, fmt:str, colsep:str, recsep:str, qout:str, nullrep:str, tbl:bat[:str], attr:bat[:str], tpe:bat[:str], len:bat[:int],scale:bat[:int], cols:bat[:any]...) :int 
address mvc_export_table_wrap
comment "Prepare a table result set for the COPY INTO stream";

unsafe pattern declaredTable( name:str ) :int 
address mvc_declared_table_wrap
comment "Prepare a declared table"; 

unsafe pattern dtColumn(rs:int, tname:str, name:str, typename:str, digits:int, scale:int) :void
address mvc_declared_table_column_wrap;

unsafe pattern dropDeclaredTable( name:str ) :void 
address mvc_drop_declared_table_wrap
comment "drop a declared table"; 

unsafe pattern dropDeclaredTables( nr:int ) :void 
address mvc_drop_declared_tables_wrap
comment "drop top n declared tables"; 

pattern drop_func_upgrade_oct2014(id:int) :int
address UPGdrop_func
comment "Drop the function identified by id, needed for the Oct2014 upgrade";

pattern create_func_upgrade_oct2014(sname:str,f:str) :int
address UPGcreate_func
comment "Create the function described by f, needed for the Oct2014 upgrade";

pattern create_view_upgrade_oct2014(sname:str,v:str) :int
address UPGcreate_view
comment "Create the view described by f, needed for the Oct2014 upgrade";

unsafe pattern exportHead(s:streams, res_id:int) :void
address mvc_export_head_wrap
comment "Export a result (in order) to stream s"; 

unsafe pattern exportResult(s:streams, res_id:int) :void
address mvc_export_result_wrap
comment "Export a result (in order) to stream s"; 

unsafe pattern exportChunk(s:streams, res_id:int) :void
address mvc_export_chunk_wrap
comment "Export a chunk of the result set (in order) to stream s"; 

unsafe pattern exportChunk(s:streams, res_id:int, offset:int, nr:int) :void
address mvc_export_chunk_wrap
comment "Export a chunk of the result set (in order) to stream s"; 

unsafe pattern exportOperation() :void
address mvc_export_operation_wrap
comment "Export result of schema/transaction queries"; 

unsafe pattern affectedRows(mvc:int, nr:lng) :int
address mvc_affected_rows_wrap
comment "export the number of affected rows by the current query";

unsafe pattern copy_from( t:ptr, 
	sep:str, rsep:str, ssep:str, ns:str, fname:str, nr:lng, offset:lng, locked:int, best:int) (:bat[:any]...)
address mvc_import_table_wrap
comment "Import a table from bstream s with the 
	given tuple and seperators (sep/rsep)";

#command copy_errors() (efile:bat[:str], erow:bat[:int], efld:bat[:int], emsg:bat[:str], einp:bat[:str])
#address mvc_import_errors
#comment "Summary of the failed tuple imports";

pattern single(x:any_2):bat[:any_2]
address CMDBATsingle;

unsafe pattern importTable( sname:str, tname:str, fname:str... )(:bat[:any]...)
address mvc_bin_import_table_wrap
comment "Import a table from the files (fname)";

command zero_or_one( col:bat[:any_1]) :any_1
address zero_or_one
comment "if col contains exactly one value return this. Incase of more raise an exception else return nil";

inline function sql.subzero_or_one( b:bat[:any_1], gp:bat[:oid], gpe:bat[:oid], no_nil:bit) :bat[:any_1];
	(g,e,h) := group.subgroup(gp);
	m := aggr.max(h);
	c0 := calc.isnil(m);
	c01 := calc.not(c0);
	c1 := calc.>(m,1:lng);
	c11 := calc.and(c01,c1);
	ms := calc.str(m); 
	msg := str.+("21000!zero_or_one: cardinality violation (", ms);
	msg1 := str.+(msg, ">1)");
	sql.assert(c11, msg1);
	return zero_or_one := b;
end sql.subzero_or_one;

command all( col:bat[:any_1]) :any_1
address SQLall
comment "if col contains exactly one value return this. Incase of more raise an exception else return nil";

# todo implement = all aggregator (ie keep last value and compare status)
inline function sql.all( b:bat[:any_1], gp:bat[:oid], gpe:bat[:oid], no_nil:bit) :bat[:any_1];
	(g,e,h) := group.subgroup(gp);
	m := aggr.max(h);
	c0 := calc.isnil(m);
	c01 := calc.not(c0);
	c1 := calc.>(m,1:lng);
	c11 := calc.and(c01,c1);
	ms := calc.str(m); 
	msg := str.+("21000!zero_or_one: cardinality violation (", ms);
	msg1 := str.+(msg, ">1)");
	sql.assert(c11, msg1);
	return all := b;
end sql.all;

command not_unique( b:bat[:oid]) :bit 
address not_unique 
comment "check if the tail sorted bat b doesn't have unique tail values" ;

command optimizers()(:bat[:str],:bat[:str],:bat[:str])
address getPipeCatalog;

pattern optimizer_updates()
address SQLoptimizersUpdate;

pattern argRecord():str
address SQLargRecord
comment "Glue together the calling sequence";
pattern argRecord(a:any...):str
address SQLargRecord
comment "Glue together the calling sequence";

pattern sql_variables():bat[:str]
address sql_variables
comment "return the table with session variables";

pattern sessions() ( user:bat[:str], start:bat[:timestamp],stimeout:bat[:lng], lastcmd:bat[:timestamp], qtimeout:bat[:lng], idle:bat[:bit])
address sql_sessions_wrap
comment "SQL export table of active sessions, their timeouts and idle status";

pattern db_users() :bat[:str]
address db_users_wrap
comment "return table of users with sql scenario";

pattern password(user:str) :str
address db_password_wrap
comment "Return password hash of user";

pattern dump_cache()(query:bat[:str],count:bat[:int])
address dump_cache
comment "dump the content of the query cache";

pattern dump_opt_stats()(rewrite:bat[:str],count:bat[:int])
address dump_opt_stats
comment "dump the optimizer rewrite statistics";

pattern dump_trace()(
	event:bat[:int],
	clk:bat[:str],
	pc:bat[:str],
	thread:bat[:int],
	ticks:bat[:lng],
	rssMB:bat[:lng],
	vmMB:bat[:lng],
	reads:bat[:lng],
	writes:bat[:lng],
	minflt:bat[:lng],
	majflt:bat[:lng],
	nvcsw:bat[:lng],
	stmt:bat[:str])
address dump_trace
comment "dump the trace statistics";

pattern analyze(minmax:int, sample:lng):void
address sql_analyze;
pattern analyze(minmax:int, sample:lng, sch:str):void
address sql_analyze;
pattern analyze(minmax:int, sample:lng, sch:str, tbl:str):void
address sql_analyze;
pattern analyze(minmax:int, sample:lng, sch:str, tbl:str, col:str):void
address sql_analyze
comment "Update the database statistics table";

pattern storage()(
	schema:bat[:str],
	table:bat[:str],
	column:bat[:str],
	type:bat[:str],
	mode:bat[:str],
	location:bat[:str],
	count:bat[:lng],
	atomwidth:bat[:int],
	columnsize:bat[:lng],
	heap:bat[:lng],
	hashes:bat[:lng],
	phash:bat[:bit],
	imprints:bat[:lng],
	sorted:bat[:bit],
	revsorted:bat[:bit],
	key:bat[:bit],
	orderidx:bat[:lng])
address sql_storage
comment "return a table with storage information ";

pattern storage(sname:str)(
	schema:bat[:str],
	table:bat[:str],
	column:bat[:str],
	type:bat[:str],
	mode:bat[:str],
	location:bat[:str],
	count:bat[:lng],
	atomwidth:bat[:int],
	columnsize:bat[:lng],
	heap:bat[:lng],
	hashes:bat[:lng],
	phash:bat[:bit],
	imprints:bat[:lng],
	sorted:bat[:bit],
	revsorted:bat[:bit],
	key:bat[:bit],
	orderidx:bat[:lng])
address sql_storage
comment "return a table with storage information for a particular schema ";

pattern storage(sname:str, tname:str)(
	schema:bat[:str],
	table:bat[:str],
	column:bat[:str],
	type:bat[:str],
	mode:bat[:str],
	location:bat[:str],
	count:bat[:lng],
	atomwidth:bat[:int],
	columnsize:bat[:lng],
	heap:bat[:lng],
	hashes:bat[:lng],
	phash:bat[:bit],
	imprints:bat[:lng],
	sorted:bat[:bit],
	revsorted:bat[:bit],
	key:bat[:bit],
	orderidx:bat[:lng])
address sql_storage
comment "return a table with storage information for a particular table";

pattern storage(sname:str, tname:str, cname:str)(
	schema:bat[:str],
	table:bat[:str],
	column:bat[:str],
	type:bat[:str],
	mode:bat[:str],
	location:bat[:str],
	count:bat[:lng],
	atomwidth:bat[:int],
	columnsize:bat[:lng],
	heap:bat[:lng],
	hashes:bat[:lng],
	phash:bat[:bit],
	imprints:bat[:lng],
	sorted:bat[:bit],
	revsorted:bat[:bit],
	key:bat[:bit],
	orderidx:bat[:lng])
address sql_storage
comment "return a table with storage information for a particular column";

pattern createorderindex(sch:str,tbl:str,col:str)
address sql_createorderindex
comment "Instantiate the order index on a column";

pattern droporderindex(sch:str,tbl:str,col:str)
address sql_droporderindex
comment "Drop the order index on a column";

command calc.identity(:any_2) :oid 
address SQLidentity
comment "Returns a unique row identitfier.";

command batcalc.identity(b:bat[:any_2]) :bat[:oid] 
address BATSQLidentity
comment "Returns the unique row identitfiers.";

pattern batcalc.identity(b:bat[:any_2], s:oid ) (resb:bat[:oid],ns:oid)
address PBATSQLidentity
comment "Returns the unique row identitfiers.";

pattern querylog_catalog()(
	id:bat[:oid],
	user:bat[:str],
	defined:bat[:timestamp],
	query:bat[:str],
	pipe:bat[:str],
	plan:bat[:str],
	mal:bat[:int],
	optimize:bat[:lng]
)
address sql_querylog_catalog
comment "Obtain the query log catalog";

pattern querylog_calls()(
	id:bat[:oid],
	start:bat[:timestamp],
	stop:bat[:timestamp],
	arguments:bat[:str],
	tuples:bat[:lng],
	exec:bat[:lng],
	result:bat[:lng],
	cpuload:bat[:int],
	iowait:bat[:int]
)
address sql_querylog_calls
comment "Obtain the query log calls";

pattern querylog_empty()
address sql_querylog_empty;

command querylog_enable()
address QLOGenable;
command querylog_enable(thres:int)
address QLOGenableThreshold;
command querylog_disable()
address QLOGdisable;


pattern sysmon_queue()(qtag:bat[:lng], user:bat[:str],started:bat[:timestamp],estimate:bat[:timestamp],progress:bat[:int], status:bat[:str], tag:bat[:oid], query:bat[:str])
address SYSMONqueue;

pattern sysmon_pause(tag:sht)
address SYSMONpause;
pattern sysmon_pause(tag:int)
address SYSMONpause;
pattern sysmon_pause(tag:lng)
address SYSMONpause;

pattern sysmon_resume(tag:sht)
address SYSMONresume;
pattern sysmon_resume(tag:int)
address SYSMONresume;
pattern sysmon_resume(tag:lng)
address SYSMONresume;

pattern sysmon_stop(tag:sht)
address SYSMONstop;
pattern sysmon_stop(tag:int)
address SYSMONstop;
pattern sysmon_stop(tag:lng)
address SYSMONstop;

pattern copy_rejects() (rowid:bat[:lng], fldid:bat[:int], msg:bat[:str], inp:bat[:str])
address COPYrejects;
pattern copy_rejects_clear()
address COPYrejects_clear;

pattern calc.hash( v:bte ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:bte] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:sht ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:sht] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:int ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:int] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:lng ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:lng] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:oid ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:oid] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:lng ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:lng] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:flt ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:flt] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:dbl ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:dbl] ) :bat[:lng] address MKEYbathash;
pattern calc.hash( v:any ) :lng address MKEYhash; 
command batcalc.hash( b:bat[:any_1] ) :bat[:lng] address MKEYbathash;
pattern calc.rotate_xor_hash(h:lng, nbits:int, v:any_1) :lng address MKEYrotate_xor_hash;
command batcalc.rotate_xor_hash(h:bat[:lng], nbits:int, b:bat[:any_1]) :bat[:int] address MKEYbulk_rotate_xor_hash;

command sql.dec_round( v:bte, r:bte ) :bte 
address bte_dec_round_wrap
comment "round off the value v to nearests multiple of r";
command batsql.dec_round( v:bat[:bte], r:bte ) :bat[:bte] 
address bte_bat_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command sql.round( v:bte, d:int, s:int, r:bte) :bte
address bte_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";
command batsql.round( v:bat[:bte], d:int, s:int, r:bte) :bat[:bte]
address bte_bat_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";

command calc.second_interval( sc:int, v:bte, ek:int, sk:int ) :lng
address bte_dec2second_interval
comment "cast bte decimal to a second_interval";

command sql.dec_round( v:sht, r:sht ) :sht 
address sht_dec_round_wrap
comment "round off the value v to nearests multiple of r";
command batsql.dec_round( v:bat[:sht], r:sht ) :bat[:sht] 
address sht_bat_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command sql.round( v:sht, d:int, s:int, r:bte) :sht
address sht_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";
command batsql.round( v:bat[:sht], d:int, s:int, r:bte) :bat[:sht]
address sht_bat_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";

command calc.second_interval( sc:int, v:sht, ek:int, sk:int ) :lng
address sht_dec2second_interval
comment "cast sht decimal to a second_interval";

command sql.dec_round( v:int, r:int ) :int 
address int_dec_round_wrap
comment "round off the value v to nearests multiple of r";
command batsql.dec_round( v:bat[:int], r:int ) :bat[:int] 
address int_bat_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command sql.round( v:int, d:int, s:int, r:bte) :int
address int_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";
command batsql.round( v:bat[:int], d:int, s:int, r:bte) :bat[:int]
address int_bat_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";

command calc.second_interval( sc:int, v:int, ek:int, sk:int ) :lng
address int_dec2second_interval
comment "cast int decimal to a second_interval";

command sql.dec_round( v:lng, r:lng ) :lng 
address lng_dec_round_wrap
comment "round off the value v to nearests multiple of r";
command batsql.dec_round( v:bat[:lng], r:lng ) :bat[:lng] 
address lng_bat_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command sql.round( v:lng, d:int, s:int, r:bte) :lng
address lng_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";
command batsql.round( v:bat[:lng], d:int, s:int, r:bte) :bat[:lng]
address lng_bat_round_wrap
comment "round off the decimal v(d,s) to r digits behind the dot (if r < 0, before the dot)";

command calc.second_interval( sc:int, v:lng, ek:int, sk:int ) :lng
address lng_dec2second_interval
comment "cast lng decimal to a second_interval";

command sql.dec_round( v:flt, r:flt ) :flt 
address flt_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command batsql.dec_round( v:bat[:flt], r:flt ) :bat[:flt] 
address flt_bat_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command sql.round( v:flt, r:bte) :flt
address flt_round_wrap
comment "round off the floating point v to r digits behind the dot (if r < 0, before the dot)";

command batsql.round( v:bat[:flt], r:bte) :bat[:flt]
address flt_bat_round_wrap
comment "round off the floating point v to r digits behind the dot (if r < 0, before the dot)";

command sql.ms_trunc( v:flt, r:int) :flt
address flt_trunc_wrap
comment "truncate the floating point v to r digits behind the dot (if r < 0, before the dot)";

command sql.dec_round( v:dbl, r:dbl ) :dbl 
address dbl_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command batsql.dec_round( v:bat[:dbl], r:dbl ) :bat[:dbl] 
address dbl_bat_dec_round_wrap
comment "round off the value v to nearests multiple of r";

command sql.round( v:dbl, r:bte) :dbl
address dbl_round_wrap
comment "round off the floating point v to r digits behind the dot (if r < 0, before the dot)";

command batsql.round( v:bat[:dbl], r:bte) :bat[:dbl]
address dbl_bat_round_wrap
comment "round off the floating point v to r digits behind the dot (if r < 0, before the dot)";

command sql.ms_trunc( v:dbl, r:int) :dbl
address dbl_trunc_wrap
comment "truncate the floating point v to r digits behind the dot (if r < 0, before the dot)";

command sql.alpha(dec:dbl, theta:dbl) :dbl
address SQLcst_alpha_cst
comment "Implementation of astronomy alpha function: expands the radius theta depending on the declination";

command batsql.alpha(dec:bat[:dbl], theta:dbl) :bat[:dbl]
address SQLbat_alpha_cst
comment "BAT implementation of astronomy alpha function";

command batsql.alpha(dec:dbl, theta:bat[:dbl]) :bat[:dbl]
address SQLcst_alpha_bat
comment "BAT implementation of astronomy alpha function";

command calc.bte( v:void, digits:int ) :bte 
address nil_2num_bte
comment "cast to bte and check for overflow";
command calc.bte( v:void, digits:int, scale:int ) :bte 
address nil_2dec_bte
comment "cast to dec(bte) and check for overflow";
command batcalc.bte( v:bat[:oid], digits:int ) :bat[:bte] 
address batnil_2num_bte
comment "cast to bte and check for overflow";
command batcalc.bte( v:bat[:oid], digits:int, scale:int ) :bat[:bte] 
address batnil_2dec_bte
comment "cast to dec(bte) and check for overflow";

command calc.bte( v:str, digits:int ) :bte 
address str_2num_bte
comment "cast to bte and check for overflow";
command calc.bte( v:str, digits:int, scale:int ) :bte 
address str_2dec_bte
comment "cast to dec(bte) and check for overflow";
command batcalc.bte( v:bat[:str], digits:int ) :bat[:bte] 
address batstr_2num_bte
comment "cast to bte and check for overflow";
command batcalc.bte( v:bat[:str], digits:int, scale:int ) :bat[:bte] 
address batstr_2dec_bte
comment "cast to dec(bte) and check for overflow";

command calc.sht( v:void, digits:int ) :sht 
address nil_2num_sht
comment "cast to sht and check for overflow";
command calc.sht( v:void, digits:int, scale:int ) :sht 
address nil_2dec_sht
comment "cast to dec(sht) and check for overflow";
command batcalc.sht( v:bat[:oid], digits:int ) :bat[:sht] 
address batnil_2num_sht
comment "cast to sht and check for overflow";
command batcalc.sht( v:bat[:oid], digits:int, scale:int ) :bat[:sht] 
address batnil_2dec_sht
comment "cast to dec(sht) and check for overflow";

command calc.sht( v:str, digits:int ) :sht 
address str_2num_sht
comment "cast to sht and check for overflow";
command calc.sht( v:str, digits:int, scale:int ) :sht 
address str_2dec_sht
comment "cast to dec(sht) and check for overflow";
command batcalc.sht( v:bat[:str], digits:int ) :bat[:sht] 
address batstr_2num_sht
comment "cast to sht and check for overflow";
command batcalc.sht( v:bat[:str], digits:int, scale:int ) :bat[:sht] 
address batstr_2dec_sht
comment "cast to dec(sht) and check for overflow";

command calc.int( v:void, digits:int ) :int 
address nil_2num_int
comment "cast to int and check for overflow";
command calc.int( v:void, digits:int, scale:int ) :int 
address nil_2dec_int
comment "cast to dec(int) and check for overflow";
command batcalc.int( v:bat[:oid], digits:int ) :bat[:int] 
address batnil_2num_int
comment "cast to int and check for overflow";
command batcalc.int( v:bat[:oid], digits:int, scale:int ) :bat[:int] 
address batnil_2dec_int
comment "cast to dec(int) and check for overflow";

command calc.int( v:str, digits:int ) :int 
address str_2num_int
comment "cast to int and check for overflow";
command calc.int( v:str, digits:int, scale:int ) :int 
address str_2dec_int
comment "cast to dec(int) and check for overflow";
command batcalc.int( v:bat[:str], digits:int ) :bat[:int] 
address batstr_2num_int
comment "cast to int and check for overflow";
command batcalc.int( v:bat[:str], digits:int, scale:int ) :bat[:int] 
address batstr_2dec_int
comment "cast to dec(int) and check for overflow";

command calc.lng( v:void, digits:int ) :lng 
address nil_2num_lng
comment "cast to lng and check for overflow";
command calc.lng( v:void, digits:int, scale:int ) :lng 
address nil_2dec_lng
comment "cast to dec(lng) and check for overflow";
command batcalc.lng( v:bat[:oid], digits:int ) :bat[:lng] 
address batnil_2num_lng
comment "cast to lng and check for overflow";
command batcalc.lng( v:bat[:oid], digits:int, scale:int ) :bat[:lng] 
address batnil_2dec_lng
comment "cast to dec(lng) and check for overflow";

command calc.lng( v:str, digits:int ) :lng 
address str_2num_lng
comment "cast to lng and check for overflow";
command calc.lng( v:str, digits:int, scale:int ) :lng 
address str_2dec_lng
comment "cast to dec(lng) and check for overflow";
command batcalc.lng( v:bat[:str], digits:int ) :bat[:lng] 
address batstr_2num_lng
comment "cast to lng and check for overflow";
command batcalc.lng( v:bat[:str], digits:int, scale:int ) :bat[:lng] 
address batstr_2dec_lng
comment "cast to dec(lng) and check for overflow";

command calc.timestamp( v:void ) :timestamp 
address nil_2_timestamp
comment "Cast to timestamp";
command calc.timestamp( v:void, digits:int ) :timestamp 
address nil_2time_timestamp
comment "cast to timestamp and check for overflow";

command batcalc.timestamp( v:bat[:oid] ) :bat[:timestamp] 
address batnil_2_timestamp
comment "Cast to timestamp";
command batcalc.timestamp( v:bat[:oid], digits:int ) :bat[:timestamp] 
address batnil_2time_timestamp
comment "cast to timestamp and check for overflow";

command calc.timestamp( v:str ) :timestamp 
address str_2_timestamp
comment "Cast to timestamp";
command calc.timestamp( v:str, digits:int ) :timestamp 
address str_2time_timestamp
comment "cast to timestamp and check for overflow";
command calc.timestamp( v:str, digits:int, has_tz:int ) :timestamp 
address str_2time_timestamptz
comment "cast to timestamp and check for overflow";
command calc.timestamp( v:timestamp, digits:int ) :timestamp 
address timestamp_2time_timestamp
comment "cast timestamp to timestamp and check for overflow";

command batcalc.timestamp( v:bat[:str] ) :bat[:timestamp] 
address batstr_2_timestamp
comment "Cast to timestamp";
command batcalc.timestamp( v:bat[:str], digits:int ) :bat[:timestamp] 
address batstr_2time_timestamp
comment "cast to timestamp and check for overflow";
command batcalc.timestamp( v:bat[:str], digits:int, has_tz:int ) :bat[:timestamp] 
address batstr_2time_timestamptz
comment "cast to timestamp and check for overflow";
command batcalc.timestamp( v:bat[:timestamp], digits:int ) :bat[:timestamp] 
address battimestamp_2time_timestamp
comment "cast timestamp to timestamp and check for overflow";

command calc.daytime( v:void ) :daytime 
address nil_2_daytime
comment "Cast to daytime";
command calc.daytime( v:void, digits:int ) :daytime 
address nil_2time_daytime
comment "cast to daytime and check for overflow";

command batcalc.daytime( v:bat[:oid] ) :bat[:daytime] 
address batnil_2_daytime
comment "Cast to daytime";
command batcalc.daytime( v:bat[:oid], digits:int ) :bat[:daytime] 
address batnil_2time_daytime
comment "cast to daytime and check for overflow";

command calc.daytime( v:str ) :daytime 
address str_2_daytime
comment "Cast to daytime";
command calc.daytime( v:str, digits:int ) :daytime 
address str_2time_daytime
comment "cast to daytime and check for overflow";
command calc.daytime( v:str, digits:int, has_tz:int ) :daytime 
address str_2time_daytimetz
comment "cast to daytime and check for overflow";
command calc.daytime( v:daytime, digits:int ) :daytime 
address daytime_2time_daytime
comment "cast daytime to daytime and check for overflow";

command batcalc.daytime( v:bat[:str] ) :bat[:daytime] 
address batstr_2_daytime
comment "Cast to daytime";
command batcalc.daytime( v:bat[:str], digits:int ) :bat[:daytime] 
address batstr_2time_daytime
comment "cast to daytime and check for overflow";
command batcalc.daytime( v:bat[:str], digits:int, has_tz:int ) :bat[:daytime] 
address batstr_2time_daytimetz
comment "cast to daytime and check for overflow";
command batcalc.daytime( v:bat[:daytime], digits:int ) :bat[:daytime] 
address batdaytime_2time_daytime
comment "cast daytime to daytime and check for overflow";

pattern current_time() :daytime
address SQLcurrent_daytime
comment "Get the clients current daytime";

pattern current_timestamp() :timestamp
address SQLcurrent_timestamp
comment "Get the clients current timestamp";

command calc.date( v:void ) :date 
address nil_2_date
comment "cast to date";
command batcalc.date( v:bat[:oid] ) :bat[:date] 
address batnil_2_date
comment "cast to date";

command calc.date( v:str ) :date 
address str_2_date
comment "cast to date";
command batcalc.date( v:bat[:str] ) :bat[:date] 
address batstr_2_date
comment "cast to date";
command calc.str( v:date ) :str 
address SQLdate_2_str
comment "cast date to str";

command calc.sqlblob( v:str ) :sqlblob 
address str_2_sqlblob
comment "cast to sqlblob";
command batcalc.sqlblob( v:bat[:str] ) :bat[:sqlblob] 
address batstr_2_sqlblob
comment "cast to sqlblob";
command calc.str( v:sqlblob ) :str 
address SQLsqlblob_2_str
comment "cast sqlblob to str";

pattern calc.str( eclass:int, d1:int, s1:int, has_tz:int, v:any_1, digits:int ) :str 
address SQLstr_cast
comment "cast to string and check for overflow";

pattern batcalc.str( eclass:int, d1:int, s1:int, has_tz:int, v:bat[:any_1], digits:int ) :bat[:str] 
address SQLbatstr_cast
comment "cast to string and check for overflow";

command calc.substring(s:str,offset:int):str
address STRsubstringTail;
command calc.substring(s:str,offset:int,count:int):str
address STRsubstring;

command calc.month_interval( v:str, ek:int, sk:int ) :int
address month_interval_str
comment "cast str to a month_interval and check for overflow";

command calc.second_interval( v:str, ek:int, sk:int ) :lng
address second_interval_str
comment "cast str to a second_interval and check for overflow";

pattern calc.month_interval( v:bte, ek:int, sk:int ) :int
address month_interval
comment "cast bte to a month_interval and check for overflow";

pattern calc.second_interval( v:bte, ek:int, sk:int ) :lng
address second_interval
comment "cast bte to a second_interval and check for overflow";

pattern calc.month_interval( v:sht, ek:int, sk:int ) :int
address month_interval
comment "cast sht to a month_interval and check for overflow";

pattern calc.second_interval( v:sht, ek:int, sk:int ) :lng
address second_interval
comment "cast sht to a second_interval and check for overflow";

pattern calc.month_interval( v:int, ek:int, sk:int ) :int
address month_interval
comment "cast int to a month_interval and check for overflow";

pattern calc.second_interval( v:int, ek:int, sk:int ) :lng
address second_interval
comment "cast int to a second_interval and check for overflow";

pattern calc.month_interval( v:lng, ek:int, sk:int ) :int
address month_interval
comment "cast lng to a month_interval and check for overflow";

pattern calc.second_interval( v:lng, ek:int, sk:int ) :lng
address second_interval
comment "cast lng to a second_interval and check for overflow";

pattern calc.rowid(v:any_1, schema:str, table:str) :oid
address sql_rowid
comment "return the next rowid";

pattern shrink(sch:str, tbl:str)
address SQLshrink
comment "Consolidate the deletion table over all columns using shrinking";

pattern reuse(sch:str, tbl:str)
address SQLreuse
comment "Consolidate the deletion table over all columns reusing deleted slots";

pattern vacuum(sch:str, tbl:str)
address SQLvacuum
comment "Choose an approach to consolidate the deletions";

pattern drop_hash(sch:str, tbl:str)
address SQLdrop_hash
comment "Drop hash indices for the given table";

command prelude()
address SQLprelude;

command epilogue()
address SQLepilogue;

command calc.second_interval( v:daytime, ek:int, sk:int ) :lng
address second_interval_daytime
comment "cast daytime to a second_interval and check for overflow";

command calc.daytime( v:lng, d:int) :daytime
address second_interval_2_daytime
comment "cast second_interval to a daytime and check for overflow";

command calc.daytime( v:timestamp, d:int) :daytime
address timestamp_2_daytime
comment "cast timestamp to a daytime and check for overflow";

command calc.timestamp( v:date, d:int) :timestamp
address date_2_timestamp
comment "cast date to a timestamp and check for overflow";

command calc.index(v:str, u:bit) :bte 
address STRindex_bte
comment "Return the offsets as an index bat";

command batcalc.index(v:bat[:str], u:bit) :bat[:bte] 
address BATSTRindex_bte
comment "Return the offsets as an index bat";

command calc.index(v:str, u:bit) :sht 
address STRindex_sht
comment "Return the offsets as an index bat";

command batcalc.index(v:bat[:str], u:bit) :bat[:sht] 
address BATSTRindex_sht
comment "Return the offsets as an index bat";

command calc.index(v:str, u:bit) :int 
address STRindex_int
comment "Return the offsets as an index bat";

command batcalc.index(v:bat[:str], u:bit) :bat[:int] 
address BATSTRindex_int
comment "Return the offsets as an index bat";

command calc.strings(v:str) :str 
address STRstrings
comment "Return the strings";

command batcalc.strings(v:bat[:str]) :bat[:str] 
address BATSTRstrings
comment "Return the strings";

include sql_decimal;
include sql_rank;
#include sql_cast;
include sql_aggr_bte;
include sql_aggr_sht;
include sql_aggr_int;
include sql_aggr_lng;
include sql_aggr_flt;
include sql_aggr_dbl;
include sql_inspect;

sql.prelude();
