Changeset: 0854c336d304 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0854c336d304 Modified Files: monetdb5/extras/jaql/Tests/func01.stable.err monetdb5/extras/jaql/Tests/func01.stable.out monetdb5/extras/jaql/jaqlgencode.c Branch: jacqueline Log Message:
funcs: improve function resolution and execution Match functions more depending on their MAL signature. In particular for function overloading this gets quite easily quite messy. Since typing is done before execution in MAL, all overloaded cases need to be expanded in branches of MAL code. Since we should avoid to call non-existing variants of each overloaded function, all available types must be stored. Currently we require inputs to be symmetric, that is, for all inputs that change in type, each type should exist in all other combinations of type changing inputs. diffs (truncated from 921 to 300 lines): diff --git a/monetdb5/extras/jaql/Tests/func01.stable.err b/monetdb5/extras/jaql/Tests/func01.stable.err new file mode 100644 --- /dev/null +++ b/monetdb5/extras/jaql/Tests/func01.stable.err @@ -0,0 +1,31 @@ +stderr of test 'func01` in directory 'extras/jaql` itself: + + +# 20:16:10 > +# 20:16:10 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "gdk_dbfarm=/net/sofia.ins.cwi.nl/export/scratch1/fabian/tmp/mtest-jacqueline-sofia.ins.cwi.nl/five/dbfarm" "--set" "mapi_open=true" "--set" "mapi_port=37633" "--set" "monet_prompt=" "--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" "func01.mal" +# 20:16:10 > + +# builtin opt gdk_dbname = demo +# builtin opt gdk_dbfarm = /ufs/fabian/scratch/ssd/monetdb/jacqueline/program-x86_64/var/lib/monetdb5/dbfarm +# builtin opt gdk_debug = 0 +# builtin opt gdk_alloc_map = no +# builtin opt gdk_vmtrim = yes +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 +# cmdline opt gdk_dbfarm = /net/sofia.ins.cwi.nl/export/scratch1/fabian/tmp/mtest-jacqueline-sofia.ins.cwi.nl/five/dbfarm +# cmdline opt mapi_open = true +# cmdline opt mapi_port = 37633 +# cmdline opt monet_prompt = +# cmdline opt mal_listing = 2 +# cmdline opt gdk_dbname = mTests_extras_jaql + +# 20:16:10 > +# 20:16:10 > "Done." +# 20:16:10 > + diff --git a/monetdb5/extras/jaql/Tests/func01.stable.out b/monetdb5/extras/jaql/Tests/func01.stable.out new file mode 100644 --- /dev/null +++ b/monetdb5/extras/jaql/Tests/func01.stable.out @@ -0,0 +1,32 @@ +stdout of test 'func01` in directory 'extras/jaql` itself: + + +# 20:16:10 > +# 20:16:10 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "gdk_dbfarm=/net/sofia.ins.cwi.nl/export/scratch1/fabian/tmp/mtest-jacqueline-sofia.ins.cwi.nl/five/dbfarm" "--set" "mapi_open=true" "--set" "mapi_port=37633" "--set" "monet_prompt=" "--trace" "--forcemito" "--set" "mal_listing=2" "--dbname=mTests_extras_jaql" "func01.mal" +# 20:16:10 > + +# MonetDB 5 server v11.8.0 "jacqueline-6964bb75810c" +# Serving database 'mTests_extras_jaql', using 8 threads +# Compiled for x86_64-pc-linux-gnu/64bit with 64bit OIDs dynamically linked +# Found 15.630 GiB available main-memory. +# Copyright (c) 1993-July 2008 CWI. +# Copyright (c) August 2008-2012 MonetDB B.V., all rights reserved +# Visit http://www.monetdb.org/ for further information +# Listening for connection requests on mapi:monetdb://sofia.ins.cwi.nl:37633/ +# MonetDB/GIS module loaded +# MonetDB/SQL module loaded +function user.main():void; +# test of groupable functions + jaql.x("[1,2,3] -> sum();"); + jaql.x("sum([1.2,2.4,3.6]);"); + jaql.x("count([1.2,5,3.6,8,\"bla\"]);"); +end main; +[ 6 ] +[ 7.200000 ] +[ 5 ] + + +# 20:16:10 > +# 20:16:10 > "Done." +# 20:16:10 > + diff --git a/monetdb5/extras/jaql/jaqlgencode.c b/monetdb5/extras/jaql/jaqlgencode.c --- a/monetdb5/extras/jaql/jaqlgencode.c +++ b/monetdb5/extras/jaql/jaqlgencode.c @@ -51,7 +51,7 @@ typedef struct _jgvar { static int dumpvariabletransformation(MalBlkPtr mb, tree *t, int elems, int *j1, int *j2, int *j3, int *j4, int *j5, int *j6, int *j7); static int dumpnextid(MalBlkPtr mb, int j1); -/* returns a bat with subset from kind bat (:oid,:chr) which are +/* returns a bat with subset from kind bat (:oid,:bte) which are * referenced by the first array of the JSON structure (oid 0@0 of kind * bat, pointing to array, so all oids from array bat that have head oid * value 0@0) */ @@ -3241,6 +3241,68 @@ changetmplrefsjoin(tree *t) } } +static int +dumpvalsfromarr(MalBlkPtr mb, enum treetype tpe, + int j1, int j2, int j3, int j4, int j5) +{ + InstrPtr q; + int a; + + a = dumpwalkvar(mb, j1, j5); + + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, selectRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushArgument(mb, q, a); + switch (tpe) { + case j_str: + q = pushBte(mb, q, 's'); + break; + case j_num: + q = pushBte(mb, q, 'i'); + break; + case j_dbl: + q = pushBte(mb, q, 'd'); + break; + default: + assert(0); + } + a = getArg(q, 0); + pushInstruction(mb, q); + + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, semijoinRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + switch (tpe) { + case j_str: + q = pushArgument(mb, q, j2); + break; + case j_num: + q = pushArgument(mb, q, j3); + break; + case j_dbl: + q = pushArgument(mb, q, j4); + break; + default: + assert(0); + } + q = pushArgument(mb, q, a); + a = getArg(q, 0); + pushInstruction(mb, q); + + q = newInstruction(mb, ASSIGNsymbol); + setModuleId(q, algebraRef); + setFunctionId(q, projectRef); + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + q = pushOid(mb, q, 0); + q = pushArgument(mb, q, a); + a = getArg(q, 0); + pushInstruction(mb, q); + return a; +} + static void dumpjsonshred(MalBlkPtr mb, char *json, int *j1, int *j2, int *j3, int *j4, int *j5, int *j6, int *j7) @@ -3283,6 +3345,125 @@ dumpjsonshred(MalBlkPtr mb, char *json, pushInstruction(mb, q); } +static void +conditionalcall(int *j1, int *j2, int *j3, int *j4, int *j5, int *j6, int *j7, + MalBlkPtr mb, tree *t, enum treetype coltypes[], int dynaarg[][7], int coltpos, InstrPtr q) +{ + InstrPtr r; + int a, b, i; + for (i = 0; i < coltpos; i++) { + switch (coltypes[i]) { + case j_json: + case j_json_arr: + pushArgument(mb, q, dynaarg[i][0]); + pushArgument(mb, q, dynaarg[i][1]); + pushArgument(mb, q, dynaarg[i][2]); + pushArgument(mb, q, dynaarg[i][3]); + pushArgument(mb, q, dynaarg[i][4]); + pushArgument(mb, q, dynaarg[i][5]); + pushArgument(mb, q, dynaarg[i][6]); + break; + case j_sort_arg: + a = dynaarg[i][0]; + if (dynaarg[i][1] > 0) { + r = newInstruction(mb, ASSIGNsymbol); + setModuleId(r, calcRef); + setFunctionId(r, putName("==", 2)); + r->barrier = BARRIERsymbol; + r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any)); + r = pushArgument(mb, r, a); + r = pushStr(mb, r, "str"); + b = getArg(r, 0); + pushInstruction(mb, r); + + r = copyInstruction(q); + r = pushArgument(mb, r, dynaarg[i][1]); + + conditionalcall(j1, j2, j3, j4, j5, j6, j7, + mb, t, &coltypes[i + 1], &dynaarg[i + 1], + coltpos - (i + 1), r); + + r = newAssignment(mb); + getArg(r, 0) = b; + r->argc = r->retc = 1; + r->barrier = EXITsymbol; + } + + if (dynaarg[i][2] > 0) { + r = newInstruction(mb, ASSIGNsymbol); + setModuleId(r, calcRef); + setFunctionId(r, putName("==", 2)); + r->barrier = BARRIERsymbol; + r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any)); + r = pushArgument(mb, r, a); + r = pushStr(mb, r, "dbl"); + b = getArg(r, 0); + pushInstruction(mb, r); + + r = copyInstruction(q); + r = pushArgument(mb, r, dynaarg[i][2]); + + conditionalcall(j1, j2, j3, j4, j5, j6, j7, + mb, t, &coltypes[i + 1], &dynaarg[i + 1], + coltpos - (i + 1), r); + + r = newAssignment(mb); + getArg(r, 0) = b; + r->argc = r->retc = 1; + r->barrier = EXITsymbol; + } + + if (dynaarg[i][3] > 0) { + r = newInstruction(mb, ASSIGNsymbol); + setModuleId(r, calcRef); + setFunctionId(r, putName("==", 2)); + r->barrier = BARRIERsymbol; + r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any)); + r = pushArgument(mb, r, a); + r = pushStr(mb, r, "lng"); + b = getArg(r, 0); + pushInstruction(mb, r); + + r = copyInstruction(q); + r = pushArgument(mb, r, dynaarg[i][3]); + + conditionalcall(j1, j2, j3, j4, j5, j6, j7, + mb, t, &coltypes[i + 1], &dynaarg[i + 1], + coltpos - (i + 1), r); + + r = newAssignment(mb); + getArg(r, 0) = b; + r->argc = r->retc = 1; + r->barrier = EXITsymbol; + } + return; + default: + pushArgument(mb, q, dynaarg[i][0]); + break; + } + } + + q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any)); + pushInstruction(mb, q); + + /* this is for top-level (in a JAQL pipe), so it should always + * return a JSON struct, hence create an array with values from the + * BAT we have returned */ + r = newInstruction(mb, ASSIGNsymbol); + setModuleId(r, putName("json", 4)); + setFunctionId(r, putName("wrap", 4)); + r = pushReturn(mb, r, *j1); + r = pushReturn(mb, r, *j2); + r = pushReturn(mb, r, *j3); + r = pushReturn(mb, r, *j4); + r = pushReturn(mb, r, *j5); + r = pushReturn(mb, r, *j6); + r = pushReturn(mb, r, *j7); + r = pushArgument(mb, r, getArg(q, 0)); + pushInstruction(mb, r); +} + + int dumptree(jc *j, Client cntxt, MalBlkPtr mb, tree *t) { @@ -4084,8 +4265,9 @@ dumptree(jc *j, Client cntxt, MalBlkPtr InstrPtr f; #define MAXJAQLARG 23 enum treetype coltypes[MAXJAQLARG + 1]; + int dynaarg[MAXJAQLARG][7]; int coltpos = 0; - int i; + int i, funcretc = 0; /* lookup the function we need */ s = findSymbol(cntxt->nspace, @@ -4135,11 +4317,20 @@ dumptree(jc *j, Client cntxt, MalBlkPtr if (j->err[0] != '\0') break; + for (i = 0; i < coltpos; i++) { + /* initialise as "not in use" */ + dynaarg[i][1] = -1; + dynaarg[i][2] = -1; + dynaarg[i][3] = -1; _______________________________________________ Checkin-list mailing list [email protected] http://mail.monetdb.org/mailman/listinfo/checkin-list
