1 | /* |
2 | * This Source Code Form is subject to the terms of the Mozilla Public |
3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
5 | * |
6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
7 | */ |
8 | |
9 | /* |
10 | * M.L.Kersten |
11 | * BAT Algebra Extensions |
12 | * The kernel libraries are unaware of the MAL runtime semantics. |
13 | * This calls for declaring some operations in the MAL module section |
14 | * and register them in the kernel modules explicitly. |
15 | * |
16 | * A good example of this borderline case are BAT creation operations, |
17 | * which require a mapping of the type identifier to the underlying |
18 | * implementation type. |
19 | * |
20 | * Another example concerns the (un)pack operations, which direct |
21 | * access the runtime stack to (push)pull the values needed. |
22 | */ |
23 | #include "monetdb_config.h" |
24 | #include "batExtensions.h" |
25 | |
26 | /* |
27 | * BAT enhancements |
28 | * The code to enhance the kernel. |
29 | */ |
30 | |
31 | str |
32 | CMDBATnew(Client cntxt, MalBlkPtr m, MalStkPtr s, InstrPtr p){ |
33 | int tt; |
34 | role_t kind = TRANSIENT; |
35 | BUN cap = 0; |
36 | bat *res; |
37 | |
38 | (void) cntxt; |
39 | res = getArgReference_bat(s, p, 0); |
40 | tt = getArgType(m, p, 1); |
41 | if (p->argc > 2) { |
42 | lng lcap; |
43 | |
44 | if (getArgType(m, p, 2) == TYPE_lng) |
45 | lcap = *getArgReference_lng(s, p, 2); |
46 | else if (getArgType(m, p, 2) == TYPE_int) |
47 | lcap = (lng) *getArgReference_int(s, p, 2); |
48 | else |
49 | throw(MAL, "bat.new" , ILLEGAL_ARGUMENT " Incorrect type for size" ); |
50 | if (lcap < 0) |
51 | throw(MAL, "bat.new" , POSITIVE_EXPECTED); |
52 | if (lcap > (lng) BUN_MAX) |
53 | throw(MAL, "bat.new" , ILLEGAL_ARGUMENT " Capacity too large" ); |
54 | cap = (BUN) lcap; |
55 | if( p->argc == 4 && getVarConstant(m,getArg(p,3)).val.ival) |
56 | kind = PERSISTENT; |
57 | } |
58 | |
59 | if (tt == TYPE_any || isaBatType(tt)) |
60 | throw(MAL, "bat.new" , SEMANTIC_TYPE_ERROR); |
61 | return (str) BKCnewBAT(res, &tt, &cap, kind); |
62 | } |
63 | |
64 | str |
65 | CMDBATsingle(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) |
66 | { |
67 | BAT *b; |
68 | int * ret= getArgReference_bat(stk,pci,0); |
69 | void *u =(void*) getArgReference(stk,pci,1); |
70 | |
71 | (void)cntxt; |
72 | |
73 | b = COLnew(0,getArgType(mb,pci,1),0, TRANSIENT); |
74 | if( b == 0) |
75 | throw(MAL,"bat.single" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
76 | if (ATOMextern(b->ttype)) |
77 | u = (ptr) *(str *)u; |
78 | if (BUNappend(b, u, false) != GDK_SUCCEED) { |
79 | BBPreclaim(b); |
80 | throw(MAL, "bat.single" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
81 | } |
82 | BBPkeepref(*ret = b->batCacheid); |
83 | return MAL_SUCCEED; |
84 | } |
85 | |
86 | /* If the optimizer has not determined the partition bounds we derive one here. */ |
87 | str |
88 | CMDBATpartition(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) |
89 | { |
90 | BAT *b,*bn; |
91 | bat *ret; |
92 | int i; |
93 | bat bid; |
94 | oid lval,hval=0, step; |
95 | |
96 | (void) mb; |
97 | (void) cntxt; |
98 | bid = *getArgReference_bat(stk, pci, pci->retc); |
99 | |
100 | if ((b = BATdescriptor(bid)) == NULL) { |
101 | throw(MAL, "bat.partition" , INTERNAL_BAT_ACCESS); |
102 | } |
103 | step = BATcount(b) / pci->retc + 1; |
104 | |
105 | /* create the slices slightly overshoot to make sure it all is taken*/ |
106 | for(i=0; i<pci->retc; i++){ |
107 | lval = i*step; |
108 | hval = lval + step; |
109 | if (i == pci->retc-1) |
110 | hval = BATcount(b); |
111 | bn = BATslice(b, lval,hval); |
112 | if (bn== NULL){ |
113 | BBPunfix(b->batCacheid); |
114 | throw(MAL, "bat.partition" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
115 | } |
116 | BAThseqbase(bn, lval); |
117 | stk->stk[getArg(pci,i)].val.bval = bn->batCacheid; |
118 | ret= getArgReference_bat(stk,pci,i); |
119 | BBPkeepref(*ret = bn->batCacheid); |
120 | } |
121 | BBPunfix(b->batCacheid); |
122 | return MAL_SUCCEED; |
123 | } |
124 | str |
125 | CMDBATpartition2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) |
126 | { |
127 | BAT *b,*bn; |
128 | bat *ret,bid; |
129 | int pieces= *getArgReference_int(stk, pci, 2); |
130 | int idx = *getArgReference_int(stk, pci, 3); |
131 | oid lval,hval=0, step; |
132 | |
133 | (void) mb; |
134 | (void) cntxt; |
135 | if ( pieces <=0 ) |
136 | throw(MAL, "bat.partition" , POSITIVE_EXPECTED); |
137 | if ( idx >= pieces || idx <0 ) |
138 | throw(MAL, "bat.partition" , ILLEGAL_ARGUMENT " Illegal piece index" ); |
139 | |
140 | bid = *getArgReference_bat(stk, pci, pci->retc); |
141 | |
142 | if ((b = BATdescriptor(bid)) == NULL) { |
143 | throw(MAL, "bat.partition" , INTERNAL_BAT_ACCESS); |
144 | } |
145 | step = BATcount(b) / pieces; |
146 | |
147 | lval = idx * step; |
148 | if ( idx == pieces-1) |
149 | hval = BATcount(b); |
150 | else |
151 | hval = lval+step; |
152 | bn = BATslice(b, lval,hval); |
153 | BAThseqbase(bn, lval + b->hseqbase); |
154 | BBPunfix(b->batCacheid); |
155 | if (bn== NULL){ |
156 | throw(MAL, "bat.partition" , INTERNAL_OBJ_CREATE); |
157 | } |
158 | ret= getArgReference_bat(stk,pci,0); |
159 | BBPkeepref(*ret = bn->batCacheid); |
160 | return MAL_SUCCEED; |
161 | } |
162 | |
163 | str |
164 | CMDBATimprints(void *ret, bat *bid) |
165 | { |
166 | BAT *b; |
167 | gdk_return r; |
168 | |
169 | (void) ret; |
170 | if ((b = BATdescriptor(*bid)) == NULL) |
171 | throw(MAL, "bat.imprints" , INTERNAL_BAT_ACCESS); |
172 | |
173 | r = BATimprints(b); |
174 | BBPunfix(b->batCacheid); |
175 | if (r != GDK_SUCCEED) |
176 | throw(MAL, "bat.imprints" , GDK_EXCEPTION); |
177 | return MAL_SUCCEED; |
178 | } |
179 | str |
180 | CMDBATimprintsize(lng *ret, bat *bid) |
181 | { |
182 | BAT *b; |
183 | |
184 | if ((b = BATdescriptor(*bid)) == NULL) |
185 | throw(MAL, "bat.imprints" , INTERNAL_BAT_ACCESS); |
186 | |
187 | *ret = IMPSimprintsize(b); |
188 | BBPunfix(b->batCacheid); |
189 | return MAL_SUCCEED; |
190 | } |
191 | |