Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "gdk.h"
15 : #include <ctype.h>
16 : #include <string.h>
17 : #include "mal_client.h"
18 : #include "mal_interpreter.h"
19 : #include "mal_exception.h"
20 : #include "str.h"
21 : #ifdef HAVE_ICONV
22 : #include <iconv.h>
23 : #endif
24 :
25 : /* In order to make avaialble a bulk version of a string function with candidates, all possible combinations of scalar/vector
26 : version of each argument must be avaiable for the function. Obviously this won't scale for functions with a large number of
27 : arguments, so we keep a blacklist for functions without candidate versions. */
28 : static const char *batstr_funcs_with_no_cands[8] =
29 : { "lpad3", "rpad3", "splitpart", "substitute", "locate3", "insert",
30 : "replace", NULL };
31 :
32 : bool
33 232 : batstr_func_has_candidates(const char *func)
34 : {
35 1842 : for (size_t i = 0; batstr_funcs_with_no_cands[i]; i++)
36 1622 : if (strcmp(batstr_funcs_with_no_cands[i], func) == 0)
37 : return false;
38 : return true;
39 : }
40 :
41 : static inline void
42 2869 : finalize_output(bat *res, BAT *bn, str msg, bool nils, BUN q)
43 : {
44 2869 : if (bn && !msg) {
45 2869 : BATsetcount(bn, q);
46 2869 : bn->tnil = nils;
47 2869 : bn->tnonil = !nils;
48 2869 : bn->tkey = BATcount(bn) <= 1;
49 2869 : bn->tsorted = BATcount(bn) <= 1;
50 2869 : bn->trevsorted = BATcount(bn) <= 1;
51 2869 : bn->theap->dirty |= BATcount(bn) > 0;
52 2869 : *res = bn->batCacheid;
53 2869 : BBPkeepref(bn);
54 0 : } else if (bn)
55 0 : BBPreclaim(bn);
56 2870 : }
57 :
58 : static void
59 2870 : unfix_inputs(int nargs, ...)
60 : {
61 2870 : va_list valist;
62 :
63 2870 : va_start(valist, nargs);
64 8830 : for (int i = 0; i < nargs; i++) {
65 5960 : BAT *b = va_arg(valist, BAT *);
66 9094 : BBPreclaim(b);
67 : }
68 2870 : va_end(valist);
69 2870 : }
70 :
71 : static inline str
72 102595 : str_prefix(str *buf, size_t *buflen, const char *s, int l)
73 : {
74 102595 : return str_Sub_String(buf, buflen, s, 0, l);
75 : }
76 :
77 : static str
78 1889 : do_batstr_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
79 : const char *name, int (*func)(const char *restrict))
80 : {
81 1889 : BATiter bi;
82 1889 : BAT *bn = NULL, *b = NULL, *bs = NULL;
83 1889 : int *restrict vals;
84 1889 : str msg = MAL_SUCCEED;
85 1889 : bool nils = false;
86 1889 : struct canditer ci1 = { 0 };
87 1889 : oid off1;
88 1889 : bat *res = getArgReference_bat(stk, pci, 0),
89 1889 : *bid = getArgReference_bat(stk, pci, 1),
90 1889 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
91 :
92 1889 : (void) cntxt;
93 1889 : (void) mb;
94 1889 : if (!(b = BATdescriptor(*bid))) {
95 0 : msg = createException(MAL, name,
96 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
97 0 : goto bailout;
98 : }
99 1888 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
100 0 : msg = createException(MAL, name,
101 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
102 0 : goto bailout;
103 : }
104 1889 : canditer_init(&ci1, b, bs);
105 1889 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
106 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
107 0 : goto bailout;
108 : }
109 :
110 1889 : off1 = b->hseqbase;
111 1889 : bi = bat_iterator(b);
112 1889 : vals = Tloc(bn, 0);
113 1889 : if (ci1.tpe == cand_dense) {
114 2259077 : for (BUN i = 0; i < ci1.ncand; i++) {
115 2257228 : oid p1 = (canditer_next_dense(&ci1) - off1);
116 2257228 : const char *restrict x = BUNtvar(bi, p1);
117 :
118 2255859 : if (strNil(x)) {
119 0 : vals[i] = int_nil;
120 0 : nils = true;
121 : } else {
122 2255859 : vals[i] = func(x);
123 : }
124 : }
125 : } else {
126 1938535 : for (BUN i = 0; i < ci1.ncand; i++) {
127 1938495 : oid p1 = (canditer_next(&ci1) - off1);
128 1938156 : const char *restrict x = BUNtvar(bi, p1);
129 :
130 1936958 : if (strNil(x)) {
131 0 : vals[i] = int_nil;
132 0 : nils = true;
133 : } else {
134 1936958 : vals[i] = func(x);
135 : }
136 : }
137 : }
138 1889 : bat_iterator_end(&bi);
139 1889 : bailout:
140 1889 : finalize_output(res, bn, msg, nils, ci1.ncand);
141 1889 : unfix_inputs(2, b, bs);
142 1889 : return msg;
143 : }
144 :
145 : static str
146 1888 : STRbatLength(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
147 : {
148 1888 : return do_batstr_int(cntxt, mb, stk, pci, "batstr.length", UTF8_strlen);
149 : }
150 :
151 : static str
152 1 : STRbatBytes(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
153 : {
154 1 : return do_batstr_int(cntxt, mb, stk, pci, "batstr.bytes", str_strlen);
155 : }
156 :
157 : static str
158 3 : STRbatAscii(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
159 : {
160 3 : BATiter bi;
161 3 : BAT *bn = NULL, *b = NULL, *bs = NULL;
162 3 : int *restrict vals, next;
163 3 : str msg = MAL_SUCCEED;
164 3 : bool nils = false;
165 3 : struct canditer ci1 = { 0 };
166 3 : oid off1;
167 3 : bat *res = getArgReference_bat(stk, pci, 0),
168 3 : *bid = getArgReference_bat(stk, pci, 1),
169 3 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
170 :
171 3 : (void) cntxt;
172 3 : (void) mb;
173 3 : if (!(b = BATdescriptor(*bid))) {
174 0 : msg = createException(MAL, "batstr.unicodeAt",
175 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
176 0 : goto bailout;
177 : }
178 3 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
179 0 : msg = createException(MAL, "batstr.unicodeAt",
180 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
181 0 : goto bailout;
182 : }
183 3 : canditer_init(&ci1, b, bs);
184 3 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
185 0 : msg = createException(MAL, "batstr.unicodeAt",
186 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
187 0 : goto bailout;
188 : }
189 :
190 3 : off1 = b->hseqbase;
191 3 : bi = bat_iterator(b);
192 3 : vals = Tloc(bn, 0);
193 3 : if (ci1.tpe == cand_dense) {
194 10 : for (BUN i = 0; i < ci1.ncand; i++) {
195 8 : oid p1 = (canditer_next_dense(&ci1) - off1);
196 8 : const char *restrict x = BUNtvar(bi, p1);
197 :
198 8 : if ((msg = str_wchr_at(&next, x, 0)) != MAL_SUCCEED)
199 0 : goto bailout1;
200 8 : vals[i] = next;
201 8 : nils |= is_int_nil(next);
202 : }
203 : } else {
204 15 : for (BUN i = 0; i < ci1.ncand; i++) {
205 14 : oid p1 = (canditer_next(&ci1) - off1);
206 14 : const char *restrict x = BUNtvar(bi, p1);
207 :
208 14 : if ((msg = str_wchr_at(&next, x, 0)) != MAL_SUCCEED)
209 0 : goto bailout1;
210 14 : vals[i] = next;
211 14 : nils |= is_int_nil(next);
212 : }
213 : }
214 1 : bailout1:
215 3 : bat_iterator_end(&bi);
216 3 : bailout:
217 3 : finalize_output(res, bn, msg, nils, ci1.ncand);
218 3 : unfix_inputs(2, b, bs);
219 3 : return msg;
220 : }
221 :
222 : static str
223 1 : STRbatFromWChr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
224 : {
225 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
226 1 : size_t buflen = MAX(strlen(str_nil) + 1, 8);
227 1 : int *restrict vals, x;
228 1 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
229 1 : bool nils = false;
230 1 : struct canditer ci1 = { 0 };
231 1 : oid off1;
232 1 : bat *res = getArgReference_bat(stk, pci, 0),
233 1 : *bid = getArgReference_bat(stk, pci, 1),
234 1 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
235 1 : BATiter bi;
236 :
237 1 : (void) cntxt;
238 1 : (void) mb;
239 1 : if (!buf) {
240 0 : msg = createException(MAL, "batstr.unicode",
241 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
242 0 : goto bailout;
243 : }
244 1 : if (!(b = BATdescriptor(*bid))) {
245 0 : msg = createException(MAL, "batstr.unicode",
246 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
247 0 : goto bailout;
248 : }
249 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
250 0 : msg = createException(MAL, "batstr.unicode",
251 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
252 0 : goto bailout;
253 : }
254 1 : canditer_init(&ci1, b, bs);
255 1 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
256 0 : msg = createException(MAL, "batstr.unicode",
257 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
258 0 : goto bailout;
259 : }
260 :
261 1 : bi = bat_iterator(b);
262 1 : off1 = b->hseqbase;
263 1 : vals = bi.base;
264 1 : if (ci1.tpe == cand_dense) {
265 5 : for (BUN i = 0; i < ci1.ncand; i++) {
266 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
267 4 : x = vals[p1];
268 :
269 4 : if (is_int_nil(x)) {
270 2 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
271 0 : msg = createException(MAL, "batstr.unicode",
272 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
273 0 : goto bailout1;
274 : }
275 : nils = true;
276 : } else {
277 2 : if ((msg = str_from_wchr(&buf, &buflen, vals[p1])) != MAL_SUCCEED) {
278 0 : goto bailout1;
279 : }
280 2 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
281 0 : msg = createException(MAL, "batstr.unicode",
282 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
283 0 : goto bailout1;
284 : }
285 : }
286 : }
287 : } else {
288 0 : for (BUN i = 0; i < ci1.ncand; i++) {
289 0 : oid p1 = (canditer_next(&ci1) - off1);
290 0 : x = vals[p1];
291 :
292 0 : if (is_int_nil(x)) {
293 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
294 0 : msg = createException(MAL, "batstr.unicode",
295 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
296 0 : goto bailout1;
297 : }
298 : nils = true;
299 : } else {
300 0 : if ((msg = str_from_wchr(&buf, &buflen, vals[p1])) != MAL_SUCCEED) {
301 0 : goto bailout1;
302 : }
303 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
304 0 : msg = createException(MAL, "batstr.unicode",
305 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
306 0 : goto bailout1;
307 : }
308 : }
309 : }
310 : }
311 0 : bailout1:
312 1 : bat_iterator_end(&bi);
313 1 : bailout:
314 1 : GDKfree(buf);
315 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
316 1 : unfix_inputs(2, b, bs);
317 1 : return msg;
318 : }
319 :
320 : static str
321 0 : STRbatSpace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
322 : {
323 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
324 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
325 0 : int *restrict vals, x;
326 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
327 0 : bool nils = false;
328 0 : const char space[] = " ", *s = space;
329 0 : struct canditer ci1 = { 0 };
330 0 : oid off1;
331 0 : bat *res = getArgReference_bat(stk, pci, 0),
332 0 : *bid = getArgReference_bat(stk, pci, 1),
333 0 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
334 0 : BATiter bi;
335 :
336 0 : (void) cntxt;
337 0 : (void) mb;
338 0 : if (!buf) {
339 0 : msg = createException(MAL, "batstr.space",
340 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
341 0 : goto bailout;
342 : }
343 0 : if (!(b = BATdescriptor(*bid))) {
344 0 : msg = createException(MAL, "batstr.space",
345 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
346 0 : goto bailout;
347 : }
348 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
349 0 : msg = createException(MAL, "batstr.search",
350 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
351 0 : goto bailout;
352 : }
353 0 : canditer_init(&ci1, b, bs);
354 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
355 0 : msg = createException(MAL, "batstr.space",
356 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
357 0 : goto bailout;
358 : }
359 :
360 0 : off1 = b->hseqbase;
361 0 : bi = bat_iterator(b);
362 0 : vals = bi.base;
363 0 : if (ci1.tpe == cand_dense) {
364 0 : for (BUN i = 0; i < ci1.ncand; i++) {
365 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
366 0 : x = vals[p1];
367 :
368 0 : if (is_int_nil(x) || x < 0) {
369 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
370 0 : msg = createException(MAL, "batstr.space",
371 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
372 0 : goto bailout1;
373 : }
374 : nils = true;
375 : } else {
376 0 : if ((msg = str_repeat(&buf, &buflen, s, x)) != MAL_SUCCEED)
377 0 : goto bailout1;
378 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
379 0 : msg = createException(MAL, "batstr.space",
380 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
381 0 : goto bailout1;
382 : }
383 : }
384 : }
385 : } else {
386 0 : for (BUN i = 0; i < ci1.ncand; i++) {
387 0 : oid p1 = (canditer_next(&ci1) - off1);
388 0 : x = vals[p1];
389 :
390 0 : if (is_int_nil(x) || x < 0) {
391 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
392 0 : msg = createException(MAL, "batstr.space",
393 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
394 0 : goto bailout1;
395 : }
396 : nils = true;
397 : } else {
398 0 : if ((msg = str_repeat(&buf, &buflen, s, x)) != MAL_SUCCEED)
399 0 : goto bailout1;
400 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
401 0 : msg = createException(MAL, "batstr.space",
402 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
403 0 : goto bailout1;
404 : }
405 : }
406 : }
407 : }
408 0 : bailout1:
409 0 : bat_iterator_end(&bi);
410 0 : bailout:
411 0 : GDKfree(buf);
412 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
413 0 : unfix_inputs(2, b, bs);
414 0 : return msg;
415 : }
416 :
417 : static str
418 128 : do_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
419 : const char *name, str (*func)(str *, size_t *, const char *))
420 : {
421 128 : BATiter bi;
422 128 : BAT *bn = NULL, *b = NULL, *bs = NULL;
423 128 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
424 128 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
425 128 : bool nils = false;
426 128 : struct canditer ci1 = { 0 };
427 128 : oid off1;
428 128 : bat *res = getArgReference_bat(stk, pci, 0),
429 128 : *bid = getArgReference_bat(stk, pci, 1),
430 128 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
431 :
432 128 : (void) cntxt;
433 128 : (void) mb;
434 128 : if (!buf) {
435 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
436 0 : goto bailout;
437 : }
438 128 : if (!(b = BATdescriptor(*bid))) {
439 0 : msg = createException(MAL, name,
440 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
441 0 : goto bailout;
442 : }
443 128 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
444 0 : msg = createException(MAL, name,
445 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
446 0 : goto bailout;
447 : }
448 128 : canditer_init(&ci1, b, bs);
449 128 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
450 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
451 0 : goto bailout;
452 : }
453 :
454 128 : off1 = b->hseqbase;
455 128 : bi = bat_iterator(b);
456 128 : if (ci1.tpe == cand_dense) {
457 184720 : for (BUN i = 0; i < ci1.ncand; i++) {
458 184592 : oid p1 = (canditer_next_dense(&ci1) - off1);
459 184592 : const char *restrict x = BUNtvar(bi, p1);
460 :
461 184601 : if (strNil(x)) {
462 3072 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
463 0 : msg = createException(MAL, name,
464 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
465 0 : goto bailout1;
466 : }
467 : nils = true;
468 : } else {
469 181529 : if ((msg = (*func) (&buf, &buflen, x)) != MAL_SUCCEED)
470 0 : goto bailout1;
471 181435 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
472 0 : msg = createException(MAL, name,
473 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
474 0 : goto bailout1;
475 : }
476 : }
477 : }
478 : } else {
479 0 : for (BUN i = 0; i < ci1.ncand; i++) {
480 0 : oid p1 = (canditer_next(&ci1) - off1);
481 0 : const char *restrict x = BUNtvar(bi, p1);
482 :
483 0 : if (strNil(x)) {
484 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
485 0 : msg = createException(MAL, name,
486 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
487 0 : goto bailout1;
488 : }
489 : nils = true;
490 : } else {
491 0 : if ((msg = (*func) (&buf, &buflen, x)) != MAL_SUCCEED)
492 0 : goto bailout1;
493 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
494 0 : msg = createException(MAL, name,
495 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
496 0 : goto bailout1;
497 : }
498 : }
499 : }
500 : }
501 0 : bailout1:
502 128 : bat_iterator_end(&bi);
503 128 : bailout:
504 128 : GDKfree(buf);
505 128 : finalize_output(res, bn, msg, nils, ci1.ncand);
506 128 : unfix_inputs(2, b, bs);
507 128 : return msg;
508 : }
509 :
510 : /* Input: a BAT of strings 'b' and a constant string 'y'
511 : * Output type: str (a BAT of strings)
512 : */
513 : static str
514 3 : do_batstr_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
515 : const char *name, size_t buflen,
516 : str (*func)(str *, size_t *, const char *, const char *))
517 : {
518 3 : BATiter bi;
519 3 : BAT *bn = NULL, *b = NULL, *bs = NULL;
520 3 : const char *y = *getArgReference_str(stk, pci, 2);
521 3 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
522 3 : bool nils = false;
523 3 : struct canditer ci1 = { 0 };
524 3 : oid off1;
525 3 : bat *res = getArgReference_bat(stk, pci, 0),
526 3 : *bid = getArgReference_bat(stk, pci, 1),
527 3 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
528 :
529 3 : (void) cntxt;
530 3 : (void) mb;
531 3 : if (!buf) {
532 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
533 0 : goto bailout;
534 : }
535 3 : if (!(b = BATdescriptor(*bid))) {
536 0 : msg = createException(MAL, name,
537 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
538 0 : goto bailout;
539 : }
540 3 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
541 0 : msg = createException(MAL, name,
542 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
543 0 : goto bailout;
544 : }
545 3 : canditer_init(&ci1, b, bs);
546 3 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
547 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
548 0 : goto bailout;
549 : }
550 :
551 3 : off1 = b->hseqbase;
552 3 : bi = bat_iterator(b);
553 3 : if (ci1.tpe == cand_dense) {
554 12 : for (BUN i = 0; i < ci1.ncand; i++) {
555 9 : oid p1 = (canditer_next_dense(&ci1) - off1);
556 9 : const char *x = BUNtvar(bi, p1);
557 :
558 18 : if (strNil(x) || strNil(y)) {
559 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
560 0 : msg = createException(MAL, name,
561 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
562 0 : goto bailout1;
563 : }
564 : nils = true;
565 : } else {
566 9 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
567 0 : goto bailout1;
568 9 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
569 0 : msg = createException(MAL, name,
570 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
571 0 : goto bailout1;
572 : }
573 : }
574 : }
575 : } else {
576 0 : for (BUN i = 0; i < ci1.ncand; i++) {
577 0 : oid p1 = (canditer_next(&ci1) - off1);
578 0 : const char *x = BUNtvar(bi, p1);
579 :
580 0 : if (strNil(x) || strNil(y)) {
581 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
582 0 : msg = createException(MAL, name,
583 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
584 0 : goto bailout1;
585 : }
586 : nils = true;
587 : } else {
588 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
589 0 : goto bailout1;
590 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
591 0 : msg = createException(MAL, name,
592 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
593 0 : goto bailout1;
594 : }
595 : }
596 : }
597 : }
598 0 : bailout1:
599 3 : bat_iterator_end(&bi);
600 3 : bailout:
601 3 : GDKfree(buf);
602 3 : finalize_output(res, bn, msg, nils, ci1.ncand);
603 3 : unfix_inputs(2, b, bs);
604 3 : return msg;
605 : }
606 :
607 : /* Input: a const string 'x' and a BAT of strings 'y'
608 : * Output type: str (a BAT of strings)
609 : */
610 : static str
611 0 : do_batstr_str_conststr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
612 : const char *name, size_t buflen,
613 : str (*func)(str *, size_t *, const char *, const char *))
614 : {
615 0 : BATiter bi;
616 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
617 0 : const char *x = *getArgReference_str(stk, pci, 1);
618 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
619 0 : bool nils = false;
620 0 : struct canditer ci1 = { 0 };
621 0 : oid off1;
622 0 : bat *res = getArgReference_bat(stk, pci, 0),
623 0 : *bid = getArgReference_bat(stk, pci, 2),
624 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
625 :
626 0 : (void) cntxt;
627 0 : (void) mb;
628 0 : if (!buf) {
629 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
630 0 : goto bailout;
631 : }
632 0 : if (!(b = BATdescriptor(*bid))) {
633 0 : msg = createException(MAL, name,
634 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
635 0 : goto bailout;
636 : }
637 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
638 0 : msg = createException(MAL, name,
639 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
640 0 : goto bailout;
641 : }
642 0 : canditer_init(&ci1, b, bs);
643 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
644 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
645 0 : goto bailout;
646 : }
647 :
648 0 : off1 = b->hseqbase;
649 0 : bi = bat_iterator(b);
650 0 : if (ci1.tpe == cand_dense) {
651 0 : for (BUN i = 0; i < ci1.ncand; i++) {
652 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
653 0 : const char *y = BUNtvar(bi, p1);
654 :
655 0 : if (strNil(x) || strNil(y)) {
656 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
657 0 : msg = createException(MAL, name,
658 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
659 0 : goto bailout1;
660 : }
661 : nils = true;
662 : } else {
663 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
664 0 : goto bailout1;
665 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
666 0 : msg = createException(MAL, name,
667 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
668 0 : goto bailout1;
669 : }
670 : }
671 : }
672 : } else {
673 0 : for (BUN i = 0; i < ci1.ncand; i++) {
674 0 : oid p1 = (canditer_next(&ci1) - off1);
675 0 : const char *y = BUNtvar(bi, p1);
676 :
677 0 : if (strNil(x) || strNil(y)) {
678 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
679 0 : msg = createException(MAL, name,
680 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
681 0 : goto bailout1;
682 : }
683 : nils = true;
684 : } else {
685 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
686 0 : goto bailout1;
687 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
688 0 : msg = createException(MAL, name,
689 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
690 0 : goto bailout1;
691 : }
692 : }
693 : }
694 : }
695 0 : bailout1:
696 0 : bat_iterator_end(&bi);
697 0 : bailout:
698 0 : GDKfree(buf);
699 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
700 0 : unfix_inputs(2, b, bs);
701 0 : return msg;
702 : }
703 :
704 : /* Input: two BATs of strings 'l' and 'l2'
705 : * Output type: str (a BAT of strings)
706 : */
707 : static str
708 7 : do_batstr_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
709 : const char *name, size_t buflen,
710 : str (*func)(str *, size_t *, const char *, const char *))
711 : {
712 7 : BATiter lefti, righti;
713 7 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
714 7 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
715 7 : bool nils = false;
716 7 : struct canditer ci1 = { 0 }, ci2 = { 0 };
717 7 : oid off1, off2;
718 7 : bat *res = getArgReference_bat(stk, pci, 0),
719 7 : *l = getArgReference_bat(stk, pci, 1),
720 7 : *l2 = getArgReference_bat(stk, pci, 2),
721 7 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
722 7 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
723 :
724 7 : (void) cntxt;
725 7 : (void) mb;
726 7 : if (!buf) {
727 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
728 0 : goto bailout;
729 : }
730 7 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*l2))) {
731 0 : msg = createException(MAL, name,
732 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
733 0 : goto bailout;
734 : }
735 7 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
736 7 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
737 0 : msg = createException(MAL, name,
738 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
739 0 : goto bailout;
740 : }
741 7 : canditer_init(&ci1, left, lefts);
742 7 : canditer_init(&ci2, right, rights);
743 7 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
744 0 : msg = createException(MAL, name,
745 : ILLEGAL_ARGUMENT
746 : " Requires bats of identical size");
747 0 : goto bailout;
748 : }
749 7 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
750 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
751 0 : goto bailout;
752 : }
753 :
754 7 : off1 = left->hseqbase;
755 7 : off2 = right->hseqbase;
756 7 : lefti = bat_iterator(left);
757 7 : righti = bat_iterator(right);
758 7 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
759 25 : for (BUN i = 0; i < ci1.ncand; i++) {
760 18 : oid p1 = (canditer_next_dense(&ci1) - off1),
761 18 : p2 = (canditer_next_dense(&ci2) - off2);
762 18 : const char *x = BUNtvar(lefti, p1);
763 18 : const char *y = BUNtvar(righti, p2);
764 :
765 36 : if (strNil(x) || strNil(y)) {
766 9 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
767 0 : msg = createException(MAL, name,
768 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
769 0 : goto bailout1;
770 : }
771 : nils = true;
772 : } else {
773 9 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
774 0 : goto bailout1;
775 9 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
776 0 : msg = createException(MAL, name,
777 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
778 0 : goto bailout1;
779 : }
780 : }
781 : }
782 : } else {
783 0 : for (BUN i = 0; i < ci1.ncand; i++) {
784 0 : oid p1 = (canditer_next(&ci1) - off1),
785 0 : p2 = (canditer_next(&ci2) - off2);
786 0 : const char *x = BUNtvar(lefti, p1);
787 0 : const char *y = BUNtvar(righti, p2);
788 :
789 0 : if (strNil(x) || strNil(y)) {
790 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
791 0 : msg = createException(MAL, name,
792 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
793 0 : goto bailout1;
794 : }
795 : nils = true;
796 : } else {
797 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
798 0 : goto bailout1;
799 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
800 0 : msg = createException(MAL, name,
801 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
802 0 : goto bailout1;
803 : }
804 : }
805 : }
806 : }
807 0 : bailout1:
808 7 : bat_iterator_end(&lefti);
809 7 : bat_iterator_end(&righti);
810 7 : bailout:
811 7 : GDKfree(buf);
812 7 : finalize_output(res, bn, msg, nils, ci1.ncand);
813 7 : unfix_inputs(4, left, lefts, right, rights);
814 7 : return msg;
815 : }
816 :
817 : /* Input: a BAT of strings 'l' and a constant int 'y'
818 : * Output type: str (a BAT of strings)
819 : */
820 : static str
821 2 : do_batstr_constint_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
822 : const char *name,
823 : str (*func)(str *, size_t *, const char *, int))
824 : {
825 2 : BATiter bi;
826 2 : BAT *bn = NULL, *b = NULL, *bs = NULL;
827 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
828 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
829 2 : int y = *getArgReference_int(stk, pci, 2);
830 2 : bool nils = false;
831 2 : struct canditer ci1 = { 0 };
832 2 : oid off1;
833 2 : bat *res = getArgReference_bat(stk, pci, 0),
834 2 : *bid = getArgReference_bat(stk, pci, 1),
835 2 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
836 :
837 2 : (void) cntxt;
838 2 : (void) mb;
839 2 : if (!buf) {
840 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
841 0 : goto bailout;
842 : }
843 2 : if (!(b = BATdescriptor(*bid))) {
844 0 : msg = createException(MAL, name,
845 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
846 0 : goto bailout;
847 : }
848 2 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
849 0 : msg = createException(MAL, name,
850 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
851 0 : goto bailout;
852 : }
853 2 : canditer_init(&ci1, b, bs);
854 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
855 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
856 0 : goto bailout;
857 : }
858 :
859 2 : off1 = b->hseqbase;
860 2 : bi = bat_iterator(b);
861 2 : if (ci1.tpe == cand_dense) {
862 6 : for (BUN i = 0; i < ci1.ncand; i++) {
863 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
864 4 : const char *x = BUNtvar(bi, p1);
865 :
866 8 : if (strNil(x) || is_int_nil(y)) {
867 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
868 0 : msg = createException(MAL, name,
869 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
870 0 : goto bailout1;
871 : }
872 : nils = true;
873 : } else {
874 4 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
875 0 : goto bailout1;
876 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
877 0 : msg = createException(MAL, name,
878 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
879 0 : goto bailout1;
880 : }
881 : }
882 : }
883 : } else {
884 0 : for (BUN i = 0; i < ci1.ncand; i++) {
885 0 : oid p1 = (canditer_next(&ci1) - off1);
886 0 : const char *x = BUNtvar(bi, p1);
887 :
888 0 : if (strNil(x) || is_int_nil(y)) {
889 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
890 0 : msg = createException(MAL, name,
891 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
892 0 : goto bailout1;
893 : }
894 : nils = true;
895 : } else {
896 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
897 0 : goto bailout1;
898 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
899 0 : msg = createException(MAL, name,
900 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
901 0 : goto bailout1;
902 : }
903 : }
904 : }
905 : }
906 0 : bailout1:
907 2 : bat_iterator_end(&bi);
908 2 : bailout:
909 2 : GDKfree(buf);
910 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
911 2 : unfix_inputs(2, b, bs);
912 2 : return msg;
913 : }
914 :
915 : /* Input: a constant string 'x' and a BAT of integers 'y'
916 : * Output type: str (a BAT of strings)
917 : */
918 : static str
919 0 : do_batstr_int_conststr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
920 : const char *name,
921 : str (*func)(str *, size_t *, const char *, int))
922 : {
923 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
924 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
925 0 : const char *x = *getArgReference_str(stk, pci, 1);
926 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
927 0 : int y, *restrict inputs;
928 0 : bool nils = false;
929 0 : struct canditer ci1 = { 0 };
930 0 : oid off1;
931 0 : bat *res = getArgReference_bat(stk, pci, 0),
932 0 : *bid = getArgReference_bat(stk, pci, 2),
933 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
934 0 : BATiter bi;
935 :
936 0 : (void) cntxt;
937 0 : (void) mb;
938 0 : if (!buf) {
939 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
940 0 : goto bailout;
941 : }
942 0 : if (!(b = BATdescriptor(*bid))) {
943 0 : msg = createException(MAL, name,
944 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
945 0 : goto bailout;
946 : }
947 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
948 0 : msg = createException(MAL, name,
949 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
950 0 : goto bailout;
951 : }
952 0 : canditer_init(&ci1, b, bs);
953 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
954 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
955 0 : goto bailout;
956 : }
957 :
958 0 : off1 = b->hseqbase;
959 0 : bi = bat_iterator(b);
960 0 : inputs = bi.base;
961 0 : if (ci1.tpe == cand_dense) {
962 0 : for (BUN i = 0; i < ci1.ncand; i++) {
963 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
964 0 : y = inputs[p1];
965 :
966 0 : if (strNil(x) || is_int_nil(y)) {
967 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
968 0 : msg = createException(MAL, name,
969 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
970 0 : goto bailout1;
971 : }
972 : nils = true;
973 : } else {
974 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
975 0 : goto bailout1;
976 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
977 0 : msg = createException(MAL, name,
978 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
979 0 : goto bailout1;
980 : }
981 : }
982 : }
983 : } else {
984 0 : for (BUN i = 0; i < ci1.ncand; i++) {
985 0 : oid p1 = (canditer_next(&ci1) - off1);
986 0 : y = inputs[p1];
987 :
988 0 : if (strNil(x) || is_int_nil(y)) {
989 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
990 0 : msg = createException(MAL, name,
991 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
992 0 : goto bailout1;
993 : }
994 : nils = true;
995 : } else {
996 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
997 0 : goto bailout1;
998 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
999 0 : msg = createException(MAL, name,
1000 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1001 0 : goto bailout1;
1002 : }
1003 : }
1004 : }
1005 : }
1006 0 : bailout1:
1007 0 : bat_iterator_end(&bi);
1008 0 : bailout:
1009 0 : GDKfree(buf);
1010 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
1011 0 : unfix_inputs(2, b, bs);
1012 0 : return msg;
1013 : }
1014 :
1015 : /* Input: a BAT of strings 'l' and a BAT of integers 'n'
1016 : * Output type: str (a BAT of strings)
1017 : */
1018 : static str
1019 2 : do_batstr_batint_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1020 : const char *name,
1021 : str (*func)(str *, size_t *, const char *, int))
1022 : {
1023 2 : BATiter lefti;
1024 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1025 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1026 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1027 2 : bool nils = false;
1028 2 : int *restrict righti, y;
1029 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1030 2 : oid off1, off2;
1031 2 : bat *res = getArgReference_bat(stk, pci, 0),
1032 2 : *l = getArgReference_bat(stk, pci, 1),
1033 2 : *n = getArgReference_bat(stk, pci, 2),
1034 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
1035 2 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
1036 2 : BATiter bi;
1037 :
1038 2 : (void) cntxt;
1039 2 : (void) mb;
1040 2 : if (!buf) {
1041 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1042 0 : goto bailout;
1043 : }
1044 2 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*n))) {
1045 0 : msg = createException(MAL, name,
1046 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1047 0 : goto bailout;
1048 : }
1049 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1050 2 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1051 0 : msg = createException(MAL, name,
1052 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1053 0 : goto bailout;
1054 : }
1055 2 : canditer_init(&ci1, left, ls);
1056 2 : canditer_init(&ci2, right, rs);
1057 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1058 0 : msg = createException(MAL, name,
1059 : ILLEGAL_ARGUMENT
1060 : " Requires bats of identical size");
1061 0 : goto bailout;
1062 : }
1063 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1064 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1065 0 : goto bailout;
1066 : }
1067 :
1068 2 : off1 = left->hseqbase;
1069 2 : off2 = right->hseqbase;
1070 2 : lefti = bat_iterator(left);
1071 2 : bi = bat_iterator(right);
1072 2 : righti = bi.base;
1073 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1074 6 : for (BUN i = 0; i < ci1.ncand; i++) {
1075 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
1076 4 : p2 = (canditer_next_dense(&ci2) - off2);
1077 4 : const char *x = BUNtvar(lefti, p1);
1078 4 : y = righti[p2];
1079 :
1080 8 : if (strNil(x) || is_int_nil(y)) {
1081 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1082 0 : msg = createException(MAL, name,
1083 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1084 0 : goto bailout1;
1085 : }
1086 : nils = true;
1087 : } else {
1088 4 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1089 0 : goto bailout1;
1090 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1091 0 : msg = createException(MAL, name,
1092 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1093 0 : goto bailout1;
1094 : }
1095 : }
1096 : }
1097 : } else {
1098 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1099 0 : oid p1 = (canditer_next(&ci1) - off1),
1100 0 : p2 = (canditer_next(&ci2) - off2);
1101 0 : const char *x = BUNtvar(lefti, p1);
1102 0 : y = righti[p2];
1103 :
1104 0 : if (strNil(x) || is_int_nil(y)) {
1105 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1106 0 : msg = createException(MAL, name,
1107 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1108 0 : goto bailout1;
1109 : }
1110 : nils = true;
1111 : } else {
1112 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1113 0 : goto bailout1;
1114 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1115 0 : msg = createException(MAL, name,
1116 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1117 0 : goto bailout1;
1118 : }
1119 : }
1120 : }
1121 : }
1122 0 : bailout1:
1123 2 : bat_iterator_end(&bi);
1124 2 : bat_iterator_end(&lefti);
1125 2 : bailout:
1126 2 : GDKfree(buf);
1127 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1128 2 : unfix_inputs(4, left, ls, right, rs);
1129 2 : return msg;
1130 : }
1131 :
1132 : /* Input: a BAT of strings 'l', a constant int 'y' and a constant str 'z'
1133 : * Output type: str (a BAT of strings)
1134 : */
1135 : static str
1136 2 : do_batstr_constint_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1137 : InstrPtr pci, const char *name,
1138 : str (*func)(str *, size_t *, const char *, int, const char *))
1139 : {
1140 2 : BATiter bi;
1141 2 : BAT *bn = NULL, *b = NULL, *bs = NULL;
1142 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1143 2 : const char *z = *getArgReference_str(stk, pci, 3);
1144 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1145 2 : int y = *getArgReference_int(stk, pci, 2);
1146 2 : bool nils = false;
1147 2 : struct canditer ci1 = { 0 };
1148 2 : oid off1;
1149 2 : bat *res = getArgReference_bat(stk, pci, 0),
1150 2 : *l = getArgReference_bat(stk, pci, 1),
1151 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
1152 :
1153 2 : (void) cntxt;
1154 2 : (void) mb;
1155 2 : if (!buf) {
1156 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1157 0 : goto bailout;
1158 : }
1159 2 : if (!(b = BATdescriptor(*l))) {
1160 0 : msg = createException(MAL, name,
1161 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1162 0 : goto bailout;
1163 : }
1164 2 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
1165 0 : msg = createException(MAL, name,
1166 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1167 0 : goto bailout;
1168 : }
1169 2 : canditer_init(&ci1, b, bs);
1170 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1171 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1172 0 : goto bailout;
1173 : }
1174 :
1175 2 : off1 = b->hseqbase;
1176 2 : bi = bat_iterator(b);
1177 2 : if (ci1.tpe == cand_dense) {
1178 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1179 8 : oid p1 = (canditer_next_dense(&ci1) - off1);
1180 8 : const char *x = BUNtvar(bi, p1);
1181 :
1182 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1183 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1184 0 : msg = createException(MAL, name,
1185 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1186 0 : goto bailout1;
1187 : }
1188 : nils = true;
1189 : } else {
1190 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1191 0 : goto bailout1;
1192 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1193 0 : msg = createException(MAL, name,
1194 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1195 0 : goto bailout1;
1196 : }
1197 : }
1198 : }
1199 : } else {
1200 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1201 0 : oid p1 = (canditer_next(&ci1) - off1);
1202 0 : const char *x = BUNtvar(bi, p1);
1203 :
1204 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1205 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1206 0 : msg = createException(MAL, name,
1207 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1208 0 : goto bailout1;
1209 : }
1210 : nils = true;
1211 : } else {
1212 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1213 0 : goto bailout1;
1214 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1215 0 : msg = createException(MAL, name,
1216 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1217 0 : goto bailout1;
1218 : }
1219 : }
1220 : }
1221 : }
1222 0 : bailout1:
1223 2 : bat_iterator_end(&bi);
1224 2 : bailout:
1225 2 : GDKfree(buf);
1226 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1227 2 : unfix_inputs(2, b, bs);
1228 2 : return msg;
1229 : }
1230 :
1231 : /* Input: a BAT of strings 'l', a BAT of integers 'n' and a constant str 'z'
1232 : * Output type: str (a BAT of strings)
1233 : */
1234 : static str
1235 2 : do_batstr_batint_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1236 : InstrPtr pci, const char *name,
1237 : str (*func)(str *, size_t *, const char *,
1238 : int, const char *))
1239 : {
1240 2 : BATiter lefti;
1241 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1242 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1243 2 : const char *z = *getArgReference_str(stk, pci, 3);
1244 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1245 2 : bool nils = false;
1246 2 : int *restrict righti, y;
1247 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1248 2 : oid off1, off2;
1249 2 : bat *res = getArgReference_bat(stk, pci, 0),
1250 2 : *l = getArgReference_bat(stk, pci, 1),
1251 2 : *n = getArgReference_bat(stk, pci, 2),
1252 2 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
1253 2 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
1254 2 : BATiter bi;
1255 :
1256 2 : (void) cntxt;
1257 2 : (void) mb;
1258 2 : if (!buf) {
1259 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1260 0 : goto bailout;
1261 : }
1262 2 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*n))) {
1263 0 : msg = createException(MAL, name,
1264 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1265 0 : goto bailout;
1266 : }
1267 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1268 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1269 0 : msg = createException(MAL, name,
1270 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1271 0 : goto bailout;
1272 : }
1273 2 : canditer_init(&ci1, left, ls);
1274 2 : canditer_init(&ci2, right, rs);
1275 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1276 0 : msg = createException(MAL, name,
1277 : ILLEGAL_ARGUMENT
1278 : " Requires bats of identical size");
1279 0 : goto bailout;
1280 : }
1281 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1282 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1283 0 : goto bailout;
1284 : }
1285 :
1286 2 : off1 = left->hseqbase;
1287 2 : off2 = right->hseqbase;
1288 2 : lefti = bat_iterator(left);
1289 2 : bi = bat_iterator(right);
1290 2 : righti = bi.base;
1291 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1292 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1293 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1294 8 : p2 = (canditer_next_dense(&ci2) - off2);
1295 8 : const char *x = BUNtvar(lefti, p1);
1296 8 : y = righti[p2];
1297 :
1298 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1299 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1300 0 : msg = createException(MAL, name,
1301 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1302 0 : goto bailout1;
1303 : }
1304 : nils = true;
1305 : } else {
1306 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1307 0 : goto bailout1;
1308 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1309 0 : msg = createException(MAL, name,
1310 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1311 0 : goto bailout1;
1312 : }
1313 : }
1314 : }
1315 : } else {
1316 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1317 0 : oid p1 = (canditer_next(&ci1) - off1),
1318 0 : p2 = (canditer_next(&ci2) - off2);
1319 0 : const char *x = BUNtvar(lefti, p1);
1320 0 : y = righti[p2];
1321 :
1322 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1323 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1324 0 : msg = createException(MAL, name,
1325 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1326 0 : goto bailout1;
1327 : }
1328 : nils = true;
1329 : } else {
1330 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1331 0 : goto bailout1;
1332 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1333 0 : msg = createException(MAL, name,
1334 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1335 0 : goto bailout1;
1336 : }
1337 : }
1338 : }
1339 : }
1340 0 : bailout1:
1341 2 : bat_iterator_end(&bi);
1342 2 : bat_iterator_end(&lefti);
1343 2 : bailout:
1344 2 : GDKfree(buf);
1345 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1346 2 : unfix_inputs(4, left, ls, right, rs);
1347 2 : return msg;
1348 : }
1349 :
1350 : /* Input: a BAT of strings 'l', a constant int 'y' and a BAT of strings 'l2'
1351 : * Output type: str (a BAT of strings)
1352 : */
1353 : static str
1354 2 : do_batstr_constint_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1355 : InstrPtr pci, const char *name,
1356 : str (*func)(str *, size_t *, const char *,
1357 : int, const char *))
1358 : {
1359 2 : BATiter lefti, righti;
1360 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1361 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1362 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1363 2 : bool nils = false;
1364 2 : int y = *getArgReference_int(stk, pci, 2);
1365 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1366 2 : oid off1, off2;
1367 2 : bat *res = getArgReference_bat(stk, pci, 0),
1368 2 : *l = getArgReference_bat(stk, pci, 1),
1369 2 : *l2 = getArgReference_bat(stk, pci, 3),
1370 2 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
1371 2 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
1372 :
1373 2 : (void) cntxt;
1374 2 : (void) mb;
1375 2 : if (!buf) {
1376 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1377 0 : goto bailout;
1378 : }
1379 2 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*l2))) {
1380 0 : msg = createException(MAL, name,
1381 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1382 0 : goto bailout;
1383 : }
1384 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1385 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1386 0 : msg = createException(MAL, name,
1387 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1388 0 : goto bailout;
1389 : }
1390 2 : canditer_init(&ci1, left, ls);
1391 2 : canditer_init(&ci2, right, rs);
1392 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1393 0 : msg = createException(MAL, name,
1394 : ILLEGAL_ARGUMENT
1395 : " Requires bats of identical size");
1396 0 : goto bailout;
1397 : }
1398 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1399 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1400 0 : goto bailout;
1401 : }
1402 :
1403 2 : off1 = left->hseqbase;
1404 2 : off2 = right->hseqbase;
1405 2 : lefti = bat_iterator(left);
1406 2 : righti = bat_iterator(right);
1407 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1408 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1409 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1410 8 : p2 = (canditer_next_dense(&ci2) - off2);
1411 8 : const char *x = BUNtvar(lefti, p1);
1412 8 : const char *z = BUNtvar(righti, p2);
1413 :
1414 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1415 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1416 0 : msg = createException(MAL, name,
1417 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1418 0 : goto bailout1;
1419 : }
1420 : nils = true;
1421 : } else {
1422 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1423 0 : goto bailout1;
1424 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1425 0 : msg = createException(MAL, name,
1426 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1427 0 : goto bailout1;
1428 : }
1429 : }
1430 : }
1431 : } else {
1432 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1433 0 : oid p1 = (canditer_next(&ci1) - off1),
1434 0 : p2 = (canditer_next(&ci2) - off2);
1435 0 : const char *x = BUNtvar(lefti, p1);
1436 0 : const char *z = BUNtvar(righti, p2);
1437 :
1438 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1439 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1440 0 : msg = createException(MAL, name,
1441 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1442 0 : goto bailout1;
1443 : }
1444 : nils = true;
1445 : } else {
1446 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1447 0 : goto bailout1;
1448 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1449 0 : msg = createException(MAL, name,
1450 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1451 0 : goto bailout1;
1452 : }
1453 : }
1454 : }
1455 : }
1456 0 : bailout1:
1457 2 : bat_iterator_end(&lefti);
1458 2 : bat_iterator_end(&righti);
1459 2 : bailout:
1460 2 : GDKfree(buf);
1461 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1462 2 : unfix_inputs(4, left, ls, right, rs);
1463 2 : return msg;
1464 : }
1465 :
1466 : /* Input: a BAT of strings 'l', a BAT of int 'n' and a BAT of strings 'l2'
1467 : * Output type: str (a BAT of strings)
1468 : */
1469 : static str
1470 2 : do_batstr_batint_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1471 : InstrPtr pci, const char *name,
1472 : str (*func)(str *, size_t *, const char *,
1473 : int, const char *))
1474 : {
1475 2 : BATiter arg1i, arg3i, bi;
1476 2 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL, *arg2s = NULL,
1477 2 : *arg3 = NULL, *arg3s = NULL;
1478 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1479 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1480 2 : bool nils = false;
1481 2 : int *restrict arg2i, y;
1482 2 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
1483 2 : oid off1, off2, off3;
1484 2 : bat *res = getArgReference_bat(stk, pci, 0),
1485 2 : *l = getArgReference_bat(stk, pci, 1),
1486 2 : *n = getArgReference_bat(stk, pci, 2),
1487 2 : *l2 = getArgReference_bat(stk, pci, 3),
1488 2 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
1489 2 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
1490 2 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
1491 :
1492 2 : (void) cntxt;
1493 2 : (void) mb;
1494 2 : if (!buf) {
1495 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1496 0 : goto bailout;
1497 : }
1498 2 : if (!(arg1 = BATdescriptor(*l)) || !(arg2 = BATdescriptor(*n))
1499 2 : || !(arg3 = BATdescriptor(*l2))) {
1500 0 : msg = createException(MAL, name,
1501 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1502 0 : goto bailout;
1503 : }
1504 2 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1)))
1505 2 : || (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2)))
1506 2 : || (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3)))) {
1507 0 : msg = createException(MAL, name,
1508 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1509 0 : goto bailout;
1510 : }
1511 2 : canditer_init(&ci1, arg1, arg1s);
1512 2 : canditer_init(&ci2, arg2, arg2s);
1513 2 : canditer_init(&ci3, arg3, arg3s);
1514 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
1515 2 : || ci2.hseq != ci3.hseq) {
1516 0 : msg = createException(MAL, name,
1517 : ILLEGAL_ARGUMENT
1518 : " Requires bats of identical size");
1519 0 : goto bailout;
1520 : }
1521 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1522 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1523 0 : goto bailout;
1524 : }
1525 :
1526 2 : off1 = arg1->hseqbase;
1527 2 : off2 = arg2->hseqbase;
1528 2 : off3 = arg3->hseqbase;
1529 2 : arg1i = bat_iterator(arg1);
1530 2 : bi = bat_iterator(arg2);
1531 2 : arg2i = bi.base;
1532 2 : arg3i = bat_iterator(arg3);
1533 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
1534 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1535 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1536 8 : p2 = (canditer_next_dense(&ci2) - off2),
1537 8 : p3 = (canditer_next_dense(&ci3) - off3);
1538 8 : const char *x = BUNtvar(arg1i, p1);
1539 8 : y = arg2i[p2];
1540 8 : const char *z = BUNtvar(arg3i, p3);
1541 :
1542 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1543 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1544 0 : msg = createException(MAL, name,
1545 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1546 0 : goto bailout1;
1547 : }
1548 : nils = true;
1549 : } else {
1550 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1551 0 : goto bailout1;
1552 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1553 0 : msg = createException(MAL, name,
1554 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1555 0 : goto bailout1;
1556 : }
1557 : }
1558 : }
1559 : } else {
1560 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1561 0 : oid p1 = (canditer_next(&ci1) - off1),
1562 0 : p2 = (canditer_next(&ci2) - off2),
1563 0 : p3 = (canditer_next(&ci3) - off3);
1564 0 : const char *x = BUNtvar(arg1i, p1);
1565 0 : y = arg2i[p2];
1566 0 : const char *z = BUNtvar(arg3i, p3);
1567 :
1568 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1569 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1570 0 : msg = createException(MAL, name,
1571 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1572 0 : goto bailout1;
1573 : }
1574 : nils = true;
1575 : } else {
1576 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1577 0 : goto bailout1;
1578 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1579 0 : msg = createException(MAL, name,
1580 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1581 0 : goto bailout1;
1582 : }
1583 : }
1584 : }
1585 : }
1586 0 : bailout1:
1587 2 : bat_iterator_end(&arg1i);
1588 2 : bat_iterator_end(&arg3i);
1589 2 : bat_iterator_end(&bi);
1590 2 : bailout:
1591 2 : GDKfree(buf);
1592 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1593 2 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
1594 2 : return msg;
1595 : }
1596 :
1597 : static str
1598 76 : STRbatLower(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1599 : {
1600 76 : str msg = MAL_SUCCEED;
1601 :
1602 76 : if ((msg = str_case_hash_lock(false)))
1603 : return msg;
1604 76 : msg = do_batstr_str(cntxt, mb, stk, pci, "batstr.lower", str_lower);
1605 76 : str_case_hash_unlock(false);
1606 76 : return msg;
1607 : }
1608 :
1609 : static str
1610 14 : STRbatUpper(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1611 : {
1612 14 : str msg = MAL_SUCCEED;
1613 :
1614 14 : if ((msg = str_case_hash_lock(true)))
1615 : return msg;
1616 14 : msg = do_batstr_str(cntxt, mb, stk, pci, "batstr.upper", str_upper);
1617 14 : str_case_hash_unlock(true);
1618 14 : return msg;
1619 : }
1620 :
1621 : static str
1622 10 : STRbatStrip(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1623 : {
1624 10 : return do_batstr_str(cntxt, mb, stk, pci, "batstr.strip", str_strip);
1625 : }
1626 :
1627 : static str
1628 2 : STRbatLtrim(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1629 : {
1630 2 : return do_batstr_str(cntxt, mb, stk, pci, "batstr.ltrim", str_ltrim);
1631 : }
1632 :
1633 : static str
1634 26 : STRbatRtrim(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1635 : {
1636 26 : return do_batstr_str(cntxt, mb, stk, pci, "batstr.rtrim", str_rtrim);
1637 : }
1638 :
1639 : static str
1640 1 : STRbatStrip2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1641 : {
1642 1 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.strip",
1643 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1644 : str_strip2);
1645 : }
1646 :
1647 : static str
1648 1 : STRbatLtrim2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1649 : {
1650 1 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.ltrim",
1651 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1652 : str_ltrim2);
1653 : }
1654 :
1655 : static str
1656 1 : STRbatRtrim2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1657 : {
1658 1 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.rtrim",
1659 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1660 : str_rtrim2);
1661 : }
1662 :
1663 : static str
1664 0 : STRbatStrip2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1665 : {
1666 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.strip",
1667 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1668 : str_strip2);
1669 : }
1670 :
1671 : static str
1672 0 : STRbatLtrim2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1673 : {
1674 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.ltrim",
1675 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1676 : str_ltrim2);
1677 : }
1678 :
1679 : static str
1680 0 : STRbatRtrim2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1681 : {
1682 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.rtrim",
1683 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1684 : str_rtrim2);
1685 : }
1686 :
1687 : static str
1688 5 : STRbatStrip2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1689 : {
1690 5 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.strip",
1691 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1692 : str_strip2);
1693 : }
1694 :
1695 : static str
1696 1 : STRbatLtrim2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1697 : {
1698 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.ltrim",
1699 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1700 : str_ltrim2);
1701 : }
1702 :
1703 : static str
1704 1 : STRbatRtrim2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1705 : {
1706 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.rtrim",
1707 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1708 : str_rtrim2);
1709 : }
1710 :
1711 : static str
1712 1 : STRbatLpad_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1713 : {
1714 1 : return do_batstr_constint_str(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1715 : }
1716 :
1717 : static str
1718 1 : STRbatRpad_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1719 : {
1720 1 : return do_batstr_constint_str(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1721 : }
1722 :
1723 : static str
1724 0 : STRbatLpad_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1725 : {
1726 0 : return do_batstr_int_conststr(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1727 : }
1728 :
1729 : static str
1730 0 : STRbatRpad_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1731 : {
1732 0 : return do_batstr_int_conststr(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1733 : }
1734 :
1735 : static str
1736 1 : STRbatLpad_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1737 : {
1738 1 : return do_batstr_batint_str(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1739 : }
1740 :
1741 : static str
1742 1 : STRbatRpad_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1743 : {
1744 1 : return do_batstr_batint_str(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1745 : }
1746 :
1747 : static str
1748 1 : STRbatLpad3_const_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1749 : {
1750 1 : return do_batstr_constint_conststr_str(cntxt, mb, stk, pci, "batstr.lpad",
1751 : str_lpad3);
1752 : }
1753 :
1754 : static str
1755 1 : STRbatRpad3_const_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1756 : {
1757 1 : return do_batstr_constint_conststr_str(cntxt, mb, stk, pci, "batstr.rpad",
1758 : str_rpad3);
1759 : }
1760 :
1761 : static str
1762 1 : STRbatLpad3_bat_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1763 : {
1764 1 : return do_batstr_batint_conststr_str(cntxt, mb, stk, pci, "batstr.lpad",
1765 : str_lpad3);
1766 : }
1767 :
1768 : static str
1769 1 : STRbatRpad3_bat_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1770 : {
1771 1 : return do_batstr_batint_conststr_str(cntxt, mb, stk, pci, "batstr.rpad",
1772 : str_rpad3);
1773 : }
1774 :
1775 : static str
1776 1 : STRbatLpad3_const_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1777 : {
1778 1 : return do_batstr_constint_batstr_str(cntxt, mb, stk, pci, "batstr.lpad",
1779 : str_lpad3);
1780 : }
1781 :
1782 : static str
1783 1 : STRbatRpad3_const_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1784 : {
1785 1 : return do_batstr_constint_batstr_str(cntxt, mb, stk, pci, "batstr.rpad",
1786 : str_rpad3);
1787 : }
1788 :
1789 : static str
1790 1 : STRbatLpad3_bat_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1791 : {
1792 1 : return do_batstr_batint_batstr_str(cntxt, mb, stk, pci, "batstr.lpad",
1793 : str_lpad3);
1794 : }
1795 :
1796 : static str
1797 1 : STRbatRpad3_bat_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1798 : {
1799 1 : return do_batstr_batint_batstr_str(cntxt, mb, stk, pci, "batstr.rpad",
1800 : str_rpad3);
1801 : }
1802 :
1803 : /*
1804 : * A general assumption in all cases is the bats are synchronized on their
1805 : * head column. This is not checked and may be mis-used to deploy the
1806 : * implementation for shifted window arithmetic as well.
1807 : */
1808 : static str
1809 2 : prefix_or_suffix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1810 : const char *name, int (*func)(const char *, const char *, int),
1811 : bit *icase)
1812 : {
1813 2 : (void) cntxt;
1814 2 : (void) mb;
1815 :
1816 2 : BATiter lefti, righti;
1817 2 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
1818 2 : bit *restrict vals;
1819 2 : str msg = MAL_SUCCEED;
1820 2 : bool nils = false;
1821 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1822 2 : oid off1, off2;
1823 2 : bat *res = getArgReference_bat(stk, pci, 0),
1824 2 : *l = getArgReference_bat(stk, pci, 1),
1825 2 : *r = getArgReference_bat(stk, pci, 2),
1826 4 : *sid1 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 4 : 3) : NULL,
1827 4 : *sid2 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 5 : 4) : NULL;
1828 :
1829 2 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
1830 0 : msg = createException(MAL, name,
1831 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1832 0 : goto exit2;
1833 : }
1834 2 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) ||
1835 2 : (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
1836 0 : msg = createException(MAL, name,
1837 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1838 0 : goto exit2;
1839 : }
1840 2 : canditer_init(&ci1, left, lefts);
1841 2 : canditer_init(&ci2, right, rights);
1842 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1843 0 : msg = createException(MAL, name,
1844 : ILLEGAL_ARGUMENT
1845 : " Requires bats of identical size");
1846 0 : goto exit2;
1847 : }
1848 2 : if (!(bn = COLnew(ci1.hseq, TYPE_bit, ci1.ncand, TRANSIENT))) {
1849 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1850 0 : goto exit2;
1851 : }
1852 :
1853 2 : off1 = left->hseqbase;
1854 2 : off2 = right->hseqbase;
1855 2 : lefti = bat_iterator(left);
1856 2 : righti = bat_iterator(right);
1857 2 : vals = Tloc(bn, 0);
1858 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1859 4 : for (BUN i = 0; i < ci1.ncand; i++) {
1860 2 : oid p1 = (canditer_next_dense(&ci1) - off1),
1861 2 : p2 = (canditer_next_dense(&ci2) - off2);
1862 2 : char *x = BUNtvar(lefti, p1);
1863 2 : char *y = BUNtvar(righti, p2);
1864 :
1865 4 : if (strNil(x) || strNil(y)) {
1866 0 : vals[i] = bit_nil;
1867 0 : nils = true;
1868 : } else {
1869 2 : vals[i] = func(x, y, str_strlen(y)) == 0;
1870 : }
1871 : }
1872 : } else {
1873 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1874 0 : oid p1 = (canditer_next(&ci1) - off1),
1875 0 : p2 = (canditer_next(&ci2) - off2);
1876 0 : char *x = BUNtvar(lefti, p1);
1877 0 : char *y = BUNtvar(righti, p2);
1878 :
1879 0 : if (strNil(x) || strNil(y)) {
1880 0 : vals[i] = bit_nil;
1881 0 : nils = true;
1882 : } else {
1883 0 : vals[i] = func(x, y, str_strlen(y)) == 0;
1884 : }
1885 : }
1886 : }
1887 2 : bat_iterator_end(&lefti);
1888 2 : bat_iterator_end(&righti);
1889 2 : exit2:
1890 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1891 2 : unfix_inputs(4, left, lefts, right, rights);
1892 2 : return msg;
1893 : }
1894 :
1895 : static str
1896 0 : BATSTRstarts_with(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1897 : {
1898 0 : bit *icase = NULL;
1899 0 : if (pci->argc == 4 || pci->argc == 6) {
1900 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
1901 0 : icase = getArgReference_bit(stk, pci, 3);
1902 : }
1903 0 : return prefix_or_suffix(cntxt, mb, stk, pci, "batstr.startswith",
1904 : (icase
1905 0 : && *icase) ? str_is_iprefix : str_is_prefix,
1906 : icase);
1907 : }
1908 :
1909 : static str
1910 0 : BATSTRends_with(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1911 : {
1912 0 : bit *icase = NULL;
1913 0 : if (pci->argc == 4 || pci->argc == 6) {
1914 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
1915 0 : icase = getArgReference_bit(stk, pci, 3);
1916 : }
1917 0 : return prefix_or_suffix(cntxt, mb, stk, pci, "batstr.endswith",
1918 : (icase
1919 0 : && *icase) ? str_is_isuffix : str_is_suffix,
1920 : icase);
1921 : }
1922 :
1923 : static str
1924 2 : BATSTRcontains(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1925 : {
1926 2 : bit *icase = NULL;
1927 2 : if (pci->argc == 4 || pci->argc == 6) {
1928 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
1929 0 : icase = getArgReference_bit(stk, pci, 3);
1930 : }
1931 2 : return prefix_or_suffix(cntxt, mb, stk, pci, "batstr.contains",
1932 : (icase
1933 0 : && *icase) ? str_icontains : str_contains, icase);
1934 : }
1935 :
1936 : static str
1937 19 : prefix_or_suffix_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1938 : const char *name, int (*func)(const char *, const char *,
1939 : int), bit *icase)
1940 : {
1941 19 : (void) cntxt;
1942 19 : (void) mb;
1943 :
1944 19 : BATiter bi;
1945 19 : BAT *bn = NULL, *b = NULL, *bs = NULL;
1946 19 : bit *restrict vals;
1947 19 : str y = *getArgReference_str(stk, pci, 2), msg = MAL_SUCCEED;
1948 19 : bool nils = false;
1949 19 : struct canditer ci1 = { 0 };
1950 19 : oid off1;
1951 19 : bat *res = getArgReference_bat(stk, pci, 0),
1952 19 : *bid = getArgReference_bat(stk, pci, 1), *sid1 = NULL;
1953 19 : int ynil, ylen;
1954 :
1955 19 : if ((!icase && (pci->argc == 4)) || pci->argc == 5) {
1956 33 : assert(getArgType(mb, pci, icase ? 4 : 3) == TYPE_bat ||
1957 : isaBatType(getArgType(mb, pci, icase ? 4 : 3)));
1958 17 : sid1 = getArgReference_bat(stk, pci, icase ? 4 : 3);
1959 : }
1960 :
1961 19 : if (!(b = BATdescriptor(*bid))) {
1962 0 : msg = createException(MAL, name,
1963 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1964 0 : goto exit2;
1965 : }
1966 19 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
1967 0 : msg = createException(MAL, name,
1968 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1969 0 : goto exit2;
1970 : }
1971 19 : canditer_init(&ci1, b, bs);
1972 19 : if (!(bn = COLnew(ci1.hseq, TYPE_bit, ci1.ncand, TRANSIENT))) {
1973 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1974 0 : goto exit2;
1975 : }
1976 :
1977 19 : off1 = b->hseqbase;
1978 19 : bi = bat_iterator(b);
1979 19 : vals = Tloc(bn, 0);
1980 19 : ynil = strNil(y);
1981 19 : ylen = str_strlen(y);
1982 19 : if (ci1.tpe == cand_dense) {
1983 3653 : for (BUN i = 0; i < ci1.ncand; i++) {
1984 3634 : oid p1 = (canditer_next_dense(&ci1) - off1);
1985 3634 : char *x = BUNtvar(bi, p1);
1986 :
1987 3634 : if (ynil || strNil(x)) {
1988 0 : vals[i] = bit_nil;
1989 0 : nils = true;
1990 : } else {
1991 3634 : vals[i] = func(x, y, ylen) == 0;
1992 : }
1993 : }
1994 : } else {
1995 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1996 0 : oid p1 = (canditer_next(&ci1) - off1);
1997 0 : char *x = BUNtvar(bi, p1);
1998 :
1999 0 : if (ynil || strNil(x)) {
2000 0 : vals[i] = bit_nil;
2001 0 : nils = true;
2002 : } else {
2003 0 : vals[i] = func(x, y, ylen) == 0;
2004 : }
2005 : }
2006 : }
2007 19 : bat_iterator_end(&bi);
2008 19 : exit2:
2009 19 : finalize_output(res, bn, msg, nils, ci1.ncand);
2010 19 : unfix_inputs(2, b, bs);
2011 19 : return msg;
2012 : }
2013 :
2014 : static str
2015 3 : BATSTRstarts_with_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2016 : {
2017 3 : bit *icase = NULL;
2018 3 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2019 3 : || pci->argc == 5) {
2020 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2021 0 : icase = getArgReference_bit(stk, pci, 3);
2022 : }
2023 3 : return prefix_or_suffix_cst(cntxt, mb, stk, pci, "batstr.startswith",
2024 : (icase
2025 0 : && *icase) ? str_is_iprefix : str_is_prefix,
2026 : icase);
2027 : }
2028 :
2029 : static str
2030 5 : BATSTRends_with_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2031 : {
2032 5 : bit *icase = NULL;
2033 5 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2034 5 : || pci->argc == 5) {
2035 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2036 0 : icase = getArgReference_bit(stk, pci, 3);
2037 : }
2038 5 : return prefix_or_suffix_cst(cntxt, mb, stk, pci, "batstr.endswith",
2039 : (icase
2040 0 : && *icase) ? str_is_isuffix : str_is_suffix,
2041 : icase);
2042 : }
2043 :
2044 : static str
2045 11 : BATSTRcontains_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2046 : {
2047 11 : bit *icase = NULL;
2048 11 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2049 9 : || pci->argc == 5) {
2050 3 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2051 3 : icase = getArgReference_bit(stk, pci, 3);
2052 : }
2053 11 : return prefix_or_suffix_cst(cntxt, mb, stk, pci, "batstr.contains",
2054 : (icase
2055 3 : && *icase) ? str_icontains : str_contains,
2056 : icase);
2057 : }
2058 :
2059 : static str
2060 13 : prefix_or_suffix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2061 : const char *name, int (*func)(const char *,
2062 : const char *, int),
2063 : bit *icase)
2064 : {
2065 13 : (void) cntxt;
2066 13 : (void) mb;
2067 :
2068 13 : BATiter bi;
2069 13 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2070 13 : bit *restrict vals;
2071 13 : char *x = *getArgReference_str(stk, pci, 1);
2072 13 : str msg = MAL_SUCCEED;
2073 13 : bool nils = false;
2074 13 : struct canditer ci1 = { 0 };
2075 13 : oid off1;
2076 13 : bat *res = getArgReference_bat(stk, pci, 0),
2077 13 : *bid = getArgReference_bat(stk, pci, 2), *sid1 = NULL;
2078 13 : int xnil;
2079 :
2080 13 : if ((!icase && (pci->argc == 4)) || pci->argc == 5) {
2081 22 : assert(getArgType(mb, pci, icase ? 4 : 3) == TYPE_bat ||
2082 : isaBatType(getArgType(mb, pci, icase ? 4 : 3)));
2083 11 : sid1 = getArgReference_bat(stk, pci, icase ? 4 : 3);
2084 : }
2085 :
2086 13 : if (!(b = BATdescriptor(*bid))) {
2087 0 : msg = createException(MAL, name,
2088 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2089 0 : goto exit2;
2090 : }
2091 13 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2092 0 : msg = createException(MAL, name,
2093 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2094 0 : goto exit2;
2095 : }
2096 13 : canditer_init(&ci1, b, bs);
2097 13 : if (!(bn = COLnew(ci1.hseq, TYPE_bit, ci1.ncand, TRANSIENT))) {
2098 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2099 0 : goto exit2;
2100 : }
2101 :
2102 13 : off1 = b->hseqbase;
2103 13 : bi = bat_iterator(b);
2104 13 : vals = Tloc(bn, 0);
2105 13 : xnil = strNil(x);
2106 13 : if (ci1.tpe == cand_dense) {
2107 41 : for (BUN i = 0; i < ci1.ncand; i++) {
2108 28 : oid p1 = (canditer_next_dense(&ci1) - off1);
2109 28 : char *y = BUNtvar(bi, p1);
2110 :
2111 28 : if (xnil || strNil(y)) {
2112 0 : vals[i] = bit_nil;
2113 0 : nils = true;
2114 : } else {
2115 28 : vals[i] = func(x, y, str_strlen(y)) == 0;
2116 : }
2117 : }
2118 : } else {
2119 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2120 0 : oid p1 = (canditer_next(&ci1) - off1);
2121 0 : char *y = BUNtvar(bi, p1);
2122 :
2123 0 : if (xnil || strNil(y)) {
2124 0 : vals[i] = bit_nil;
2125 0 : nils = true;
2126 : } else {
2127 0 : vals[i] = func(x, y, str_strlen(y)) == 0;
2128 : }
2129 : }
2130 : }
2131 13 : bat_iterator_end(&bi);
2132 13 : exit2:
2133 13 : finalize_output(res, bn, msg, nils, ci1.ncand);
2134 13 : unfix_inputs(2, b, bs);
2135 13 : return msg;
2136 : }
2137 :
2138 : static str
2139 2 : BATSTRstarts_with_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
2140 : InstrPtr pci)
2141 : {
2142 2 : bit *icase = NULL;
2143 2 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2144 2 : || pci->argc == 5) {
2145 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2146 0 : icase = getArgReference_bit(stk, pci, 3);
2147 : }
2148 2 : return prefix_or_suffix_strcst(cntxt, mb, stk, pci, "batstr.startsWith",
2149 : (icase
2150 0 : && *icase) ? str_is_iprefix : str_is_prefix,
2151 : icase);
2152 : }
2153 :
2154 : static str
2155 1 : BATSTRends_with_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2156 : {
2157 1 : bit *icase = NULL;
2158 1 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2159 1 : || pci->argc == 5) {
2160 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2161 0 : icase = getArgReference_bit(stk, pci, 3);
2162 : }
2163 1 : return prefix_or_suffix_strcst(cntxt, mb, stk, pci, "batstr.endsWith",
2164 : (icase
2165 0 : && *icase) ? str_is_isuffix : str_is_suffix,
2166 : icase);
2167 : }
2168 :
2169 : static str
2170 10 : BATSTRcontains_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2171 : {
2172 10 : bit *icase = NULL;
2173 10 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2174 8 : || pci->argc == 5) {
2175 2 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2176 2 : icase = getArgReference_bit(stk, pci, 3);
2177 : }
2178 10 : return prefix_or_suffix_strcst(cntxt, mb, stk, pci, "batstr.contains",
2179 : (icase
2180 2 : && *icase) ? str_icontains : str_contains,
2181 : icase);
2182 : }
2183 :
2184 : static str
2185 1 : search_string_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2186 : const char *name, int (*func)(const char *, const char *,
2187 : int), bit *icase)
2188 : {
2189 1 : (void) cntxt;
2190 1 : (void) mb;
2191 :
2192 1 : BATiter lefti, righti;
2193 1 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
2194 1 : int *restrict vals;
2195 1 : str msg = MAL_SUCCEED;
2196 1 : bool nils = false;
2197 1 : struct canditer ci1 = { 0 }, ci2 = { 0 };
2198 1 : oid off1, off2;
2199 1 : bat *res = getArgReference_bat(stk, pci, 0),
2200 1 : *l = getArgReference_bat(stk, pci, 1),
2201 1 : *r = getArgReference_bat(stk, pci, 2),
2202 1 : *sid1 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 4 : 3) : NULL,
2203 1 : *sid2 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 5 : 4) : NULL;
2204 :
2205 1 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
2206 0 : msg = createException(MAL, name,
2207 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2208 0 : goto exit2;
2209 : }
2210 1 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) ||
2211 0 : (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
2212 0 : msg = createException(MAL, name,
2213 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2214 0 : goto exit2;
2215 : }
2216 1 : canditer_init(&ci1, left, lefts);
2217 1 : canditer_init(&ci2, right, rights);
2218 1 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
2219 0 : msg = createException(MAL, name,
2220 : ILLEGAL_ARGUMENT
2221 : " Requires bats of identical size");
2222 0 : goto exit2;
2223 : }
2224 1 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2225 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2226 0 : goto exit2;
2227 : }
2228 :
2229 1 : off1 = left->hseqbase;
2230 1 : off2 = right->hseqbase;
2231 1 : lefti = bat_iterator(left);
2232 1 : righti = bat_iterator(right);
2233 1 : vals = Tloc(bn, 0);
2234 1 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
2235 5 : for (BUN i = 0; i < ci1.ncand; i++) {
2236 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
2237 4 : p2 = (canditer_next_dense(&ci2) - off2);
2238 4 : char *x = BUNtvar(lefti, p1);
2239 4 : char *y = BUNtvar(righti, p2);
2240 :
2241 8 : if (strNil(x) || strNil(y)) {
2242 0 : vals[i] = int_nil;
2243 0 : nils = true;
2244 : } else {
2245 4 : vals[i] = func(x, y, str_strlen(y));
2246 : }
2247 : }
2248 : } else {
2249 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2250 0 : oid p1 = (canditer_next(&ci1) - off1),
2251 0 : p2 = (canditer_next(&ci2) - off2);
2252 0 : char *x = BUNtvar(lefti, p1);
2253 0 : char *y = BUNtvar(righti, p2);
2254 :
2255 0 : if (strNil(x) || strNil(y)) {
2256 0 : vals[i] = int_nil;
2257 0 : nils = true;
2258 : } else {
2259 0 : vals[i] = func(x, y, str_strlen(y));
2260 : }
2261 : }
2262 : }
2263 1 : bat_iterator_end(&lefti);
2264 1 : bat_iterator_end(&righti);
2265 1 : exit2:
2266 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
2267 1 : unfix_inputs(4, left, lefts, right, rights);
2268 1 : return msg;
2269 : }
2270 :
2271 : static str
2272 1 : BATSTRstr_search(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2273 : {
2274 1 : bit *icase = NULL;
2275 1 : switch (pci->argc) {
2276 0 : case 4:
2277 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2278 0 : icase = getArgReference_bit(stk, pci, 3);
2279 : break;
2280 0 : case 6:
2281 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2282 0 : icase = getArgReference_bit(stk, pci, 3);
2283 0 : break;
2284 : }
2285 1 : return search_string_bat(cntxt, mb, stk, pci, "batstr.search",
2286 : (icase
2287 0 : && *icase) ? str_isearch : str_search, icase);
2288 : }
2289 :
2290 : static str
2291 0 : BATSTRrevstr_search(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2292 : {
2293 0 : bit *icase = NULL;
2294 0 : switch (pci->argc) {
2295 0 : case 4:
2296 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2297 0 : icase = getArgReference_bit(stk, pci, 3);
2298 : break;
2299 0 : case 6:
2300 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2301 0 : icase = getArgReference_bit(stk, pci, 3);
2302 0 : break;
2303 : }
2304 0 : return search_string_bat(cntxt, mb, stk, pci, "batstr.r_search",
2305 : (icase
2306 0 : && *icase) ? str_reverse_str_isearch :
2307 : str_reverse_str_search, icase);
2308 : }
2309 :
2310 : static str
2311 1 : search_string_bat_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2312 : const char *name, int (*func)(const char *, const char *,
2313 : int), bit *icase)
2314 : {
2315 1 : (void) cntxt;
2316 1 : (void) mb;
2317 :
2318 1 : BATiter bi;
2319 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2320 1 : int *restrict vals;
2321 1 : const char *y = *getArgReference_str(stk, pci, 2);
2322 1 : str msg = MAL_SUCCEED;
2323 1 : bool nils = false;
2324 1 : struct canditer ci1 = { 0 };
2325 1 : oid off1;
2326 1 : bat *res = getArgReference_bat(stk, pci, 0),
2327 1 : *bid = getArgReference_bat(stk, pci, 1),
2328 1 : *sid1 = NULL;
2329 1 : int ynil, ylen;
2330 :
2331 1 : if ((!icase && (pci->argc == 4)) || pci->argc == 5) {
2332 0 : assert(getArgType(mb, pci, icase ? 4 : 3) == TYPE_bat ||
2333 : isaBatType(getArgType(mb, pci, icase ? 4 : 3)));
2334 0 : sid1 = getArgReference_bat(stk, pci, icase ? 4 : 3);
2335 : }
2336 :
2337 1 : if (!(b = BATdescriptor(*bid))) {
2338 0 : msg = createException(MAL, name,
2339 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2340 0 : goto exit2;
2341 : }
2342 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2343 0 : msg = createException(MAL, name,
2344 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2345 0 : goto exit2;
2346 : }
2347 1 : canditer_init(&ci1, b, bs);
2348 1 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2349 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2350 0 : goto exit2;
2351 : }
2352 :
2353 1 : off1 = b->hseqbase;
2354 1 : bi = bat_iterator(b);
2355 1 : vals = Tloc(bn, 0);
2356 1 : ynil = strNil(y);
2357 1 : ylen = str_strlen(y);
2358 1 : if (ci1.tpe == cand_dense) {
2359 5 : for (BUN i = 0; i < ci1.ncand; i++) {
2360 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
2361 4 : char *x = BUNtvar(bi, p1);
2362 :
2363 4 : if (ynil || strNil(x)) {
2364 0 : vals[i] = int_nil;
2365 0 : nils = true;
2366 : } else {
2367 4 : vals[i] = func(x, y, ylen);
2368 : }
2369 : }
2370 : } else {
2371 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2372 0 : oid p1 = (canditer_next(&ci1) - off1);
2373 0 : char *x = BUNtvar(bi, p1);
2374 :
2375 0 : if (ynil || strNil(x)) {
2376 0 : vals[i] = int_nil;
2377 0 : nils = true;
2378 : } else {
2379 0 : vals[i] = func(x, y, ylen);
2380 : }
2381 : }
2382 : }
2383 1 : bat_iterator_end(&bi);
2384 1 : exit2:
2385 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
2386 1 : unfix_inputs(2, b, bs);
2387 1 : return msg;
2388 : }
2389 :
2390 : static str
2391 1 : BATSTRstr_search_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2392 : {
2393 1 : bit *icase = NULL;
2394 1 : switch (pci->argc) {
2395 0 : case 4:
2396 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2397 0 : icase = getArgReference_bit(stk, pci, 3);
2398 : break;
2399 0 : case 5:
2400 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2401 0 : icase = getArgReference_bit(stk, pci, 3);
2402 0 : break;
2403 : }
2404 1 : return search_string_bat_cst(cntxt, mb, stk, pci, "batstr.search",
2405 : (icase
2406 0 : && *icase) ? str_isearch : str_search, icase);
2407 : }
2408 :
2409 : static str
2410 0 : BATSTRrevstr_search_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2411 : {
2412 0 : bit *icase = NULL;
2413 0 : switch (pci->argc) {
2414 0 : case 4:
2415 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2416 0 : icase = getArgReference_bit(stk, pci, 3);
2417 : break;
2418 0 : case 5:
2419 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2420 0 : icase = getArgReference_bit(stk, pci, 3);
2421 0 : break;
2422 : }
2423 0 : return search_string_bat_cst(cntxt, mb, stk, pci, "batstr.r_search",
2424 : (icase
2425 0 : && *icase) ? str_reverse_str_isearch :
2426 : str_reverse_str_search, icase);
2427 : }
2428 :
2429 : static str
2430 0 : search_string_bat_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
2431 : InstrPtr pci, const char *name,
2432 : int (*func)(const char *, const char *, int),
2433 : bit *icase)
2434 : {
2435 0 : (void) cntxt;
2436 0 : (void) mb;
2437 :
2438 0 : BATiter bi;
2439 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2440 0 : int *restrict vals;
2441 0 : char *x = *getArgReference_str(stk, pci, 1);
2442 0 : str msg = MAL_SUCCEED;
2443 0 : bool nils = false;
2444 0 : struct canditer ci1 = { 0 };
2445 0 : oid off1;
2446 0 : bat *res = getArgReference_bat(stk, pci, 0),
2447 0 : *bid = getArgReference_bat(stk, pci, 2), *sid1 = NULL;
2448 0 : int xnil;
2449 :
2450 0 : if ((!icase && (pci->argc == 4)) || pci->argc == 5) {
2451 0 : assert(getArgType(mb, pci, icase ? 4 : 3) == TYPE_bat ||
2452 : isaBatType(getArgType(mb, pci, icase ? 4 : 3)));
2453 0 : sid1 = getArgReference_bat(stk, pci, icase ? 4 : 3);
2454 : }
2455 :
2456 0 : if (!(b = BATdescriptor(*bid))) {
2457 0 : msg = createException(MAL, name,
2458 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2459 0 : goto exit2;
2460 : }
2461 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2462 0 : msg = createException(MAL, name,
2463 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2464 0 : goto exit2;
2465 : }
2466 0 : canditer_init(&ci1, b, bs);
2467 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2468 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2469 0 : goto exit2;
2470 : }
2471 :
2472 0 : off1 = b->hseqbase;
2473 0 : bi = bat_iterator(b);
2474 0 : vals = Tloc(bn, 0);
2475 0 : xnil = strNil(x);
2476 0 : if (ci1.tpe == cand_dense) {
2477 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2478 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
2479 0 : char *y = BUNtvar(bi, p1);
2480 :
2481 0 : if (xnil || strNil(y)) {
2482 0 : vals[i] = int_nil;
2483 0 : nils = true;
2484 : } else {
2485 0 : vals[i] = func(x, y, str_strlen(y));
2486 : }
2487 : }
2488 : } else {
2489 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2490 0 : oid p1 = (canditer_next(&ci1) - off1);
2491 0 : char *y = BUNtvar(bi, p1);
2492 :
2493 0 : if (xnil || strNil(y)) {
2494 0 : vals[i] = int_nil;
2495 0 : nils = true;
2496 : } else {
2497 0 : vals[i] = func(x, y, str_strlen(y));
2498 : }
2499 : }
2500 : }
2501 0 : bat_iterator_end(&bi);
2502 0 : exit2:
2503 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2504 0 : unfix_inputs(2, b, bs);
2505 0 : return msg;
2506 : }
2507 :
2508 : static str
2509 0 : BATSTRstr_search_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2510 : {
2511 0 : bit *icase = NULL;
2512 0 : switch (pci->argc) {
2513 0 : case 4:
2514 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2515 0 : icase = getArgReference_bit(stk, pci, 3);
2516 : break;
2517 0 : case 5:
2518 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2519 0 : icase = getArgReference_bit(stk, pci, 3);
2520 0 : break;
2521 : }
2522 0 : return search_string_bat_strcst(cntxt, mb, stk, pci, "batstr.search",
2523 : (icase
2524 0 : && *icase) ? str_isearch : str_search,
2525 : icase);
2526 : }
2527 :
2528 : static str
2529 0 : BATSTRrevstr_search_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
2530 : InstrPtr pci)
2531 : {
2532 0 : bit *icase = NULL;
2533 0 : switch (pci->argc) {
2534 0 : case 4:
2535 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2536 0 : icase = getArgReference_bit(stk, pci, 3);
2537 : break;
2538 0 : case 5:
2539 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2540 0 : icase = getArgReference_bit(stk, pci, 3);
2541 0 : break;
2542 : }
2543 0 : return search_string_bat_strcst(cntxt, mb, stk, pci, "batstr.r_search",
2544 : (icase
2545 0 : && *icase) ? str_reverse_str_isearch :
2546 : str_reverse_str_search, icase);
2547 : }
2548 :
2549 : static str
2550 0 : STRbatWChrAt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2551 : {
2552 0 : BATiter lefti, bi;
2553 0 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
2554 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2555 0 : int *restrict righti, *restrict vals, next, y;
2556 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2557 0 : bool nils = false;
2558 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
2559 0 : oid off1, off2;
2560 0 : bat *res = getArgReference_bat(stk, pci, 0),
2561 0 : *l = getArgReference_bat(stk, pci, 1),
2562 0 : *r = getArgReference_bat(stk, pci, 2),
2563 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
2564 0 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
2565 :
2566 0 : (void) cntxt;
2567 0 : (void) mb;
2568 0 : if (!buf) {
2569 0 : msg = createException(MAL, "batstr.unicodeAt",
2570 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2571 0 : goto bailout;
2572 : }
2573 0 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
2574 0 : msg = createException(MAL, "batstr.unicodeAt",
2575 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2576 0 : goto bailout;
2577 : }
2578 0 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
2579 0 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
2580 0 : msg = createException(MAL, "batstr.unicodeAt",
2581 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2582 0 : goto bailout;
2583 : }
2584 0 : canditer_init(&ci1, left, lefts);
2585 0 : canditer_init(&ci2, right, rights);
2586 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
2587 0 : msg = createException(MAL, "batstr.unicodeAt",
2588 : ILLEGAL_ARGUMENT
2589 : " Requires bats of identical size");
2590 0 : goto bailout;
2591 : }
2592 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2593 0 : msg = createException(MAL, "batstr.unicodeAt",
2594 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2595 0 : goto bailout;
2596 : }
2597 :
2598 0 : off1 = left->hseqbase;
2599 0 : off2 = right->hseqbase;
2600 0 : lefti = bat_iterator(left);
2601 0 : bi = bat_iterator(right);
2602 0 : righti = bi.base;
2603 0 : vals = Tloc(bn, 0);
2604 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
2605 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2606 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
2607 0 : p2 = (canditer_next_dense(&ci2) - off2);
2608 0 : const char *x = BUNtvar(lefti, p1);
2609 0 : y = righti[p2];
2610 :
2611 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2612 0 : goto bailout1;
2613 0 : vals[i] = next;
2614 0 : nils |= is_int_nil(next);
2615 : }
2616 : } else {
2617 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2618 0 : oid p1 = (canditer_next(&ci1) - off1),
2619 0 : p2 = (canditer_next(&ci2) - off2);
2620 0 : const char *x = BUNtvar(lefti, p1);
2621 0 : y = righti[p2];
2622 :
2623 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2624 0 : goto bailout1;
2625 0 : vals[i] = next;
2626 0 : nils |= is_int_nil(next);
2627 : }
2628 : }
2629 0 : bailout1:
2630 0 : bat_iterator_end(&bi);
2631 0 : bat_iterator_end(&lefti);
2632 0 : bailout:
2633 0 : GDKfree(buf);
2634 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2635 0 : unfix_inputs(4, left, lefts, right, rights);
2636 0 : return msg;
2637 : }
2638 :
2639 : static str
2640 0 : STRbatWChrAtcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2641 : {
2642 0 : BATiter bi;
2643 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2644 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2645 0 : int y = *getArgReference_int(stk, pci, 2), *restrict vals, next;
2646 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2647 0 : bool nils = false;
2648 0 : struct canditer ci1 = { 0 };
2649 0 : oid off1;
2650 0 : bat *res = getArgReference_bat(stk, pci, 0),
2651 0 : *l = getArgReference_bat(stk, pci, 1),
2652 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2653 :
2654 0 : (void) cntxt;
2655 0 : (void) mb;
2656 0 : if (!buf) {
2657 0 : msg = createException(MAL, "batstr.unicodeAt",
2658 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2659 0 : goto bailout;
2660 : }
2661 0 : if (!(b = BATdescriptor(*l))) {
2662 0 : msg = createException(MAL, "batstr.unicodeAt",
2663 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2664 0 : goto bailout;
2665 : }
2666 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2667 0 : msg = createException(MAL, "batstr.unicodeAt",
2668 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2669 0 : goto bailout;
2670 : }
2671 0 : canditer_init(&ci1, b, bs);
2672 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2673 0 : msg = createException(MAL, "batstr.unicodeAt",
2674 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2675 0 : goto bailout;
2676 : }
2677 :
2678 0 : off1 = b->hseqbase;
2679 0 : bi = bat_iterator(b);
2680 0 : vals = Tloc(bn, 0);
2681 0 : if (ci1.tpe == cand_dense) {
2682 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2683 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
2684 0 : const char *x = BUNtvar(bi, p1);
2685 :
2686 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2687 0 : goto bailout1;
2688 0 : vals[i] = next;
2689 0 : nils |= is_int_nil(next);
2690 : }
2691 : } else {
2692 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2693 0 : oid p1 = (canditer_next(&ci1) - off1);
2694 0 : const char *x = BUNtvar(bi, p1);
2695 :
2696 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2697 0 : goto bailout1;
2698 0 : vals[i] = next;
2699 0 : nils |= is_int_nil(next);
2700 : }
2701 : }
2702 0 : bailout1:
2703 0 : bat_iterator_end(&bi);
2704 0 : bailout:
2705 0 : GDKfree(buf);
2706 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2707 0 : unfix_inputs(2, b, bs);
2708 0 : return msg;
2709 : }
2710 :
2711 : static str
2712 0 : STRbatWChrAt_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2713 : {
2714 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2715 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2716 0 : int y, *restrict vals, *restrict input, next;
2717 0 : const char *x = *getArgReference_str(stk, pci, 1);
2718 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2719 0 : bool nils = false;
2720 0 : struct canditer ci1 = { 0 };
2721 0 : oid off1;
2722 0 : bat *res = getArgReference_bat(stk, pci, 0),
2723 0 : *l = getArgReference_bat(stk, pci, 2),
2724 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2725 0 : BATiter bi;
2726 :
2727 0 : (void) cntxt;
2728 0 : (void) mb;
2729 0 : if (!buf) {
2730 0 : msg = createException(MAL, "batstr.unicodeAt",
2731 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2732 0 : goto bailout;
2733 : }
2734 0 : if (!(b = BATdescriptor(*l))) {
2735 0 : msg = createException(MAL, "batstr.unicodeAt",
2736 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2737 0 : goto bailout;
2738 : }
2739 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2740 0 : msg = createException(MAL, "batstr.unicodeAt",
2741 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2742 0 : goto bailout;
2743 : }
2744 0 : canditer_init(&ci1, b, bs);
2745 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2746 0 : msg = createException(MAL, "batstr.unicodeAt",
2747 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2748 0 : goto bailout;
2749 : }
2750 :
2751 0 : off1 = b->hseqbase;
2752 0 : bi = bat_iterator(b);
2753 0 : input = bi.base;
2754 0 : vals = Tloc(bn, 0);
2755 0 : if (ci1.tpe == cand_dense) {
2756 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2757 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
2758 0 : y = input[p1];
2759 :
2760 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2761 0 : goto bailout1;
2762 0 : vals[i] = next;
2763 0 : nils |= is_int_nil(next);
2764 : }
2765 : } else {
2766 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2767 0 : oid p1 = (canditer_next(&ci1) - off1);
2768 0 : y = input[p1];
2769 :
2770 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2771 0 : goto bailout1;
2772 0 : vals[i] = next;
2773 0 : nils |= is_int_nil(next);
2774 : }
2775 : }
2776 0 : bailout1:
2777 0 : bat_iterator_end(&bi);
2778 0 : bailout:
2779 0 : GDKfree(buf);
2780 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2781 0 : unfix_inputs(2, b, bs);
2782 0 : return msg;
2783 : }
2784 :
2785 : static str
2786 158 : do_batstr_str_int_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2787 : const char *name, str (*func)(str *, size_t *,
2788 : const char *, int))
2789 : {
2790 158 : BATiter bi;
2791 158 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2792 158 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2793 158 : int y = *getArgReference_int(stk, pci, 2);
2794 158 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2795 158 : bool nils = false;
2796 158 : struct canditer ci1 = { 0 };
2797 158 : oid off1;
2798 158 : bat *res = getArgReference_bat(stk, pci, 0),
2799 158 : *l = getArgReference_bat(stk, pci, 1),
2800 158 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2801 :
2802 158 : (void) cntxt;
2803 158 : (void) mb;
2804 158 : if (!buf) {
2805 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2806 0 : goto bailout;
2807 : }
2808 158 : if (!(b = BATdescriptor(*l))) {
2809 0 : msg = createException(MAL, name,
2810 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2811 0 : goto bailout;
2812 : }
2813 158 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2814 0 : msg = createException(MAL, name,
2815 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2816 0 : goto bailout;
2817 : }
2818 158 : canditer_init(&ci1, b, bs);
2819 158 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
2820 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2821 0 : goto bailout;
2822 : }
2823 :
2824 158 : off1 = b->hseqbase;
2825 158 : bi = bat_iterator(b);
2826 158 : if (ci1.tpe == cand_dense) {
2827 125412 : for (BUN i = 0; i < ci1.ncand; i++) {
2828 125254 : oid p1 = (canditer_next_dense(&ci1) - off1);
2829 125254 : const char *x = BUNtvar(bi, p1);
2830 :
2831 227776 : if (strNil(x) || is_int_nil(y)) {
2832 22535 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
2833 0 : msg = createException(MAL, name,
2834 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2835 0 : goto bailout1;
2836 : }
2837 : nils = true;
2838 : } else {
2839 102619 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
2840 0 : goto bailout1;
2841 102615 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
2842 0 : msg = createException(MAL, name,
2843 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2844 0 : goto bailout1;
2845 : }
2846 : }
2847 : }
2848 : } else {
2849 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2850 0 : oid p1 = (canditer_next(&ci1) - off1);
2851 0 : const char *x = BUNtvar(bi, p1);
2852 :
2853 0 : if (strNil(x) || is_int_nil(y)) {
2854 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
2855 0 : msg = createException(MAL, name,
2856 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2857 0 : goto bailout1;
2858 : }
2859 : nils = true;
2860 : } else {
2861 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
2862 0 : goto bailout1;
2863 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
2864 0 : msg = createException(MAL, name,
2865 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2866 0 : goto bailout1;
2867 : }
2868 : }
2869 : }
2870 : }
2871 0 : bailout1:
2872 158 : bat_iterator_end(&bi);
2873 158 : bailout:
2874 158 : GDKfree(buf);
2875 158 : finalize_output(res, bn, msg, nils, ci1.ncand);
2876 158 : unfix_inputs(2, b, bs);
2877 158 : return msg;
2878 : }
2879 :
2880 : static str
2881 148 : STRbatprefixcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2882 : {
2883 148 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.prefix",
2884 : str_prefix);
2885 : }
2886 :
2887 : static str
2888 1 : STRbatsuffixcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2889 : {
2890 1 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.suffix",
2891 : str_suffix);
2892 : }
2893 :
2894 : static str
2895 5 : STRbatTailcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2896 : {
2897 5 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.tail", str_tail);
2898 : }
2899 :
2900 : static str
2901 4 : STRbatsubstringTailcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2902 : {
2903 4 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.substring",
2904 : str_substring_tail);
2905 : }
2906 :
2907 : static str
2908 1 : STRbatrepeatcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2909 : {
2910 1 : BATiter bi;
2911 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2912 1 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2913 1 : int y = *getArgReference_int(stk, pci, 2);
2914 1 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2915 1 : bool nils = false;
2916 1 : struct canditer ci1 = { 0 };
2917 1 : oid off1;
2918 1 : bat *res = getArgReference_bat(stk, pci, 0),
2919 1 : *l = getArgReference_bat(stk, pci, 1),
2920 1 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2921 :
2922 1 : (void) cntxt;
2923 1 : (void) mb;
2924 1 : if (!buf) {
2925 0 : msg = createException(MAL, "batstr.repeat",
2926 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2927 0 : goto bailout;
2928 : }
2929 1 : if (!(b = BATdescriptor(*l))) {
2930 0 : msg = createException(MAL, "batstr.repeat",
2931 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2932 0 : goto bailout;
2933 : }
2934 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2935 0 : msg = createException(MAL, "batstr.repeat",
2936 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2937 0 : goto bailout;
2938 : }
2939 1 : canditer_init(&ci1, b, bs);
2940 1 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
2941 0 : msg = createException(MAL, "batstr.repeat",
2942 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2943 0 : goto bailout;
2944 : }
2945 :
2946 1 : off1 = b->hseqbase;
2947 1 : bi = bat_iterator(b);
2948 1 : if (ci1.tpe == cand_dense) {
2949 5 : for (BUN i = 0; i < ci1.ncand; i++) {
2950 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
2951 4 : const char *x = BUNtvar(bi, p1);
2952 :
2953 8 : if (strNil(x) || is_int_nil(y) || y < 0) {
2954 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
2955 0 : msg = createException(MAL, "batstr.repeat",
2956 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2957 0 : goto bailout1;
2958 : }
2959 : nils = true;
2960 : } else {
2961 4 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
2962 0 : goto bailout1;
2963 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
2964 0 : msg = createException(MAL, "batstr.repeat",
2965 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2966 0 : goto bailout1;
2967 : }
2968 : }
2969 : }
2970 : } else {
2971 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2972 0 : oid p1 = (canditer_next(&ci1) - off1);
2973 0 : const char *x = BUNtvar(bi, p1);
2974 :
2975 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
2976 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
2977 0 : msg = createException(MAL, "batstr.repeat",
2978 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2979 0 : goto bailout1;
2980 : }
2981 : nils = true;
2982 : } else {
2983 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
2984 0 : goto bailout1;
2985 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
2986 0 : msg = createException(MAL, "batstr.repeat",
2987 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2988 0 : goto bailout1;
2989 : }
2990 : }
2991 : }
2992 : }
2993 0 : bailout1:
2994 1 : bat_iterator_end(&bi);
2995 1 : bailout:
2996 1 : GDKfree(buf);
2997 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
2998 1 : unfix_inputs(2, b, bs);
2999 1 : return msg;
3000 : }
3001 :
3002 : static str
3003 4 : do_batstr_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3004 : const char *name,
3005 : str (*func)(str *, size_t *, const char *, int))
3006 : {
3007 4 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3008 4 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3009 4 : int *restrict vals, y;
3010 4 : const char *x = *getArgReference_str(stk, pci, 1);
3011 4 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3012 4 : bool nils = false;
3013 4 : struct canditer ci1 = { 0 };
3014 4 : oid off1;
3015 4 : bat *res = getArgReference_bat(stk, pci, 0),
3016 4 : *l = getArgReference_bat(stk, pci, 2),
3017 4 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
3018 4 : BATiter bi;
3019 :
3020 4 : (void) cntxt;
3021 4 : (void) mb;
3022 4 : if (!buf) {
3023 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3024 0 : goto bailout;
3025 : }
3026 4 : if (!(b = BATdescriptor(*l))) {
3027 0 : msg = createException(MAL, name,
3028 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3029 0 : goto bailout;
3030 : }
3031 4 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3032 0 : msg = createException(MAL, name,
3033 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3034 0 : goto bailout;
3035 : }
3036 4 : canditer_init(&ci1, b, bs);
3037 4 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3038 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3039 0 : goto bailout;
3040 : }
3041 :
3042 4 : off1 = b->hseqbase;
3043 4 : bi = bat_iterator(b);
3044 4 : vals = bi.base;
3045 4 : if (ci1.tpe == cand_dense) {
3046 9 : for (BUN i = 0; i < ci1.ncand; i++) {
3047 5 : oid p1 = (canditer_next_dense(&ci1) - off1);
3048 5 : y = vals[p1];
3049 :
3050 10 : if (strNil(x) || is_int_nil(y)) {
3051 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3052 0 : msg = createException(MAL, name,
3053 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3054 0 : goto bailout1;
3055 : }
3056 : nils = true;
3057 : } else {
3058 5 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3059 0 : goto bailout1;
3060 5 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3061 0 : msg = createException(MAL, name,
3062 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3063 0 : goto bailout1;
3064 : }
3065 : }
3066 : }
3067 : } else {
3068 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3069 0 : oid p1 = (canditer_next(&ci1) - off1);
3070 0 : y = vals[p1];
3071 :
3072 0 : if (strNil(x) || is_int_nil(y)) {
3073 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3074 0 : msg = createException(MAL, name,
3075 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3076 0 : goto bailout1;
3077 : }
3078 : nils = true;
3079 : } else {
3080 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3081 0 : goto bailout1;
3082 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3083 0 : msg = createException(MAL, name,
3084 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3085 0 : goto bailout1;
3086 : }
3087 : }
3088 : }
3089 : }
3090 0 : bailout1:
3091 4 : bat_iterator_end(&bi);
3092 4 : bailout:
3093 4 : GDKfree(buf);
3094 4 : finalize_output(res, bn, msg, nils, ci1.ncand);
3095 4 : unfix_inputs(2, b, bs);
3096 4 : return msg;
3097 : }
3098 :
3099 : static str
3100 4 : STRbatprefix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3101 : {
3102 4 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.prefix", str_prefix);
3103 : }
3104 :
3105 : static str
3106 0 : STRbatsuffix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3107 : {
3108 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.suffix", str_suffix);
3109 : }
3110 :
3111 : static str
3112 0 : STRbatTail_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3113 : {
3114 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.tail", str_tail);
3115 : }
3116 :
3117 : static str
3118 0 : STRbatsubstringTail_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3119 : InstrPtr pci)
3120 : {
3121 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.substring",
3122 : str_substring_tail);
3123 : }
3124 :
3125 : static str
3126 0 : STRbatrepeat_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3127 : {
3128 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3129 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3130 0 : int *restrict vals, y;
3131 0 : const char *x = *getArgReference_str(stk, pci, 1);
3132 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3133 0 : bool nils = false;
3134 0 : struct canditer ci1 = { 0 };
3135 0 : oid off1;
3136 0 : bat *res = getArgReference_bat(stk, pci, 0),
3137 0 : *l = getArgReference_bat(stk, pci, 2),
3138 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
3139 0 : BATiter bi;
3140 :
3141 0 : (void) cntxt;
3142 0 : (void) mb;
3143 0 : if (!buf) {
3144 0 : msg = createException(MAL, "batstr.repeat",
3145 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3146 0 : goto bailout;
3147 : }
3148 0 : if (!(b = BATdescriptor(*l))) {
3149 0 : msg = createException(MAL, "batstr.repeat",
3150 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3151 0 : goto bailout;
3152 : }
3153 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3154 0 : msg = createException(MAL, "batstr.repeat",
3155 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3156 0 : goto bailout;
3157 : }
3158 0 : canditer_init(&ci1, b, bs);
3159 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3160 0 : msg = createException(MAL, "batstr.repeat",
3161 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3162 0 : goto bailout;
3163 : }
3164 :
3165 0 : off1 = b->hseqbase;
3166 0 : bi = bat_iterator(b);
3167 0 : vals = bi.base;
3168 0 : if (ci1.tpe == cand_dense) {
3169 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3170 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
3171 0 : y = vals[p1];
3172 :
3173 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3174 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3175 0 : msg = createException(MAL, "batstr.repeat",
3176 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3177 0 : goto bailout1;
3178 : }
3179 : nils = true;
3180 : } else {
3181 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3182 0 : goto bailout1;
3183 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3184 0 : msg = createException(MAL, "batstr.repeat",
3185 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3186 0 : goto bailout1;
3187 : }
3188 : }
3189 : }
3190 : } else {
3191 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3192 0 : oid p1 = (canditer_next(&ci1) - off1);
3193 0 : y = vals[p1];
3194 :
3195 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3196 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3197 0 : msg = createException(MAL, "batstr.repeat",
3198 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3199 0 : goto bailout1;
3200 : }
3201 : nils = true;
3202 : } else {
3203 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3204 0 : goto bailout1;
3205 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3206 0 : msg = createException(MAL, "batstr.repeat",
3207 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3208 0 : goto bailout1;
3209 : }
3210 : }
3211 : }
3212 : }
3213 0 : bailout1:
3214 0 : bat_iterator_end(&bi);
3215 0 : bailout:
3216 0 : GDKfree(buf);
3217 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3218 0 : unfix_inputs(2, b, bs);
3219 0 : return msg;
3220 : }
3221 :
3222 : static str
3223 32 : do_batstr_str_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3224 : const char *name, str (*func)(str *, size_t *, const char *,
3225 : int))
3226 : {
3227 32 : BATiter lefti;
3228 32 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
3229 32 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3230 32 : int *restrict righti, y;
3231 32 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3232 32 : bool nils = false;
3233 32 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3234 32 : oid off1, off2;
3235 32 : bat *res = getArgReference_bat(stk, pci, 0),
3236 32 : *l = getArgReference_bat(stk, pci, 1),
3237 32 : *r = getArgReference_bat(stk, pci, 2),
3238 32 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
3239 32 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3240 32 : BATiter bi;
3241 :
3242 32 : (void) cntxt;
3243 32 : (void) mb;
3244 32 : if (!buf) {
3245 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3246 0 : goto bailout;
3247 : }
3248 32 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
3249 0 : msg = createException(MAL, name,
3250 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3251 0 : goto bailout;
3252 : }
3253 32 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
3254 32 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
3255 0 : msg = createException(MAL, name,
3256 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3257 0 : goto bailout;
3258 : }
3259 32 : canditer_init(&ci1, left, lefts);
3260 32 : canditer_init(&ci2, right, rights);
3261 32 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3262 0 : msg = createException(MAL, name,
3263 : ILLEGAL_ARGUMENT
3264 : " Requires bats of identical size");
3265 0 : goto bailout;
3266 : }
3267 32 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3268 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3269 0 : goto bailout;
3270 : }
3271 :
3272 32 : off1 = left->hseqbase;
3273 32 : off2 = right->hseqbase;
3274 32 : lefti = bat_iterator(left);
3275 32 : bi = bat_iterator(right);
3276 32 : righti = bi.base;
3277 32 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3278 31419 : for (BUN i = 0; i < ci1.ncand; i++) {
3279 31387 : oid p1 = (canditer_next_dense(&ci1) - off1),
3280 31387 : p2 = (canditer_next_dense(&ci2) - off2);
3281 31387 : const char *x = BUNtvar(lefti, p1);
3282 31387 : y = righti[p2];
3283 :
3284 35621 : if (strNil(x) || is_int_nil(y)) {
3285 27153 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3286 0 : msg = createException(MAL, name,
3287 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3288 0 : goto bailout1;
3289 : }
3290 : nils = true;
3291 : } else {
3292 4234 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3293 0 : goto bailout1;
3294 4234 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3295 0 : msg = createException(MAL, name,
3296 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3297 0 : goto bailout1;
3298 : }
3299 : }
3300 : }
3301 : } else {
3302 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3303 0 : oid p1 = (canditer_next(&ci1) - off1),
3304 0 : p2 = (canditer_next(&ci2) - off2);
3305 0 : const char *x = BUNtvar(lefti, p1);
3306 0 : y = righti[p2];
3307 :
3308 0 : if (strNil(x) || is_int_nil(y)) {
3309 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3310 0 : msg = createException(MAL, name,
3311 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3312 0 : goto bailout1;
3313 : }
3314 : nils = true;
3315 : } else {
3316 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3317 0 : goto bailout1;
3318 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3319 0 : msg = createException(MAL, name,
3320 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3321 0 : goto bailout1;
3322 : }
3323 : }
3324 : }
3325 : }
3326 0 : bailout1:
3327 32 : bat_iterator_end(&bi);
3328 32 : bat_iterator_end(&lefti);
3329 32 : bailout:
3330 32 : GDKfree(buf);
3331 32 : finalize_output(res, bn, msg, nils, ci1.ncand);
3332 32 : unfix_inputs(4, left, lefts, right, rights);
3333 32 : return msg;
3334 : }
3335 :
3336 : static str
3337 0 : STRbatprefix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3338 : {
3339 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.prefix", str_prefix);
3340 : }
3341 :
3342 : static str
3343 0 : STRbatsuffix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3344 : {
3345 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.suffix", str_suffix);
3346 : }
3347 :
3348 : static str
3349 0 : STRbatTail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3350 : {
3351 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.tail", str_tail);
3352 : }
3353 :
3354 : static str
3355 32 : STRbatsubstringTail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3356 : {
3357 32 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.substring",
3358 : str_substring_tail);
3359 : }
3360 :
3361 : static str
3362 0 : STRbatrepeat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3363 : {
3364 0 : BATiter lefti;
3365 0 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
3366 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3367 0 : int *restrict righti, y;
3368 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3369 0 : bool nils = false;
3370 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3371 0 : oid off1, off2;
3372 0 : bat *res = getArgReference_bat(stk, pci, 0),
3373 0 : *l = getArgReference_bat(stk, pci, 1),
3374 0 : *r = getArgReference_bat(stk, pci, 2),
3375 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
3376 0 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3377 0 : BATiter bi;
3378 :
3379 0 : (void) cntxt;
3380 0 : (void) mb;
3381 0 : if (!buf) {
3382 0 : msg = createException(MAL, "batstr.repeat",
3383 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3384 0 : goto bailout;
3385 : }
3386 0 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
3387 0 : msg = createException(MAL, "batstr.repeat",
3388 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3389 0 : goto bailout;
3390 : }
3391 0 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
3392 0 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
3393 0 : msg = createException(MAL, "batstr.repeat",
3394 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3395 0 : goto bailout;
3396 : }
3397 0 : canditer_init(&ci1, left, lefts);
3398 0 : canditer_init(&ci2, right, rights);
3399 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3400 0 : msg = createException(MAL, "batstr.repeat",
3401 : ILLEGAL_ARGUMENT
3402 : " Requires bats of identical size");
3403 0 : goto bailout;
3404 : }
3405 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3406 0 : msg = createException(MAL, "batstr.repeat",
3407 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3408 0 : goto bailout;
3409 : }
3410 :
3411 0 : off1 = left->hseqbase;
3412 0 : off2 = right->hseqbase;
3413 0 : lefti = bat_iterator(left);
3414 0 : bi = bat_iterator(right);
3415 0 : righti = bi.base;
3416 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3417 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3418 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3419 0 : p2 = (canditer_next_dense(&ci2) - off2);
3420 0 : const char *x = BUNtvar(lefti, p1);
3421 0 : y = righti[p2];
3422 :
3423 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3424 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3425 0 : msg = createException(MAL, "batstr.repeat",
3426 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3427 0 : goto bailout1;
3428 : }
3429 : nils = true;
3430 : } else {
3431 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3432 0 : goto bailout1;
3433 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3434 0 : msg = createException(MAL, "batstr.repeat",
3435 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3436 0 : goto bailout1;
3437 : }
3438 : }
3439 : }
3440 : } else {
3441 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3442 0 : oid p1 = (canditer_next(&ci1) - off1),
3443 0 : p2 = (canditer_next(&ci2) - off2);
3444 0 : const char *x = BUNtvar(lefti, p1);
3445 0 : y = righti[p2];
3446 :
3447 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3448 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3449 0 : msg = createException(MAL, "batstr.repeat",
3450 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3451 0 : goto bailout1;
3452 : }
3453 : nils = true;
3454 : } else {
3455 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3456 0 : goto bailout1;
3457 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3458 0 : msg = createException(MAL, "batstr.repeat",
3459 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3460 0 : goto bailout1;
3461 : }
3462 : }
3463 : }
3464 : }
3465 0 : bailout1:
3466 0 : bat_iterator_end(&bi);
3467 0 : bat_iterator_end(&lefti);
3468 0 : bailout:
3469 0 : GDKfree(buf);
3470 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3471 0 : unfix_inputs(4, left, lefts, right, rights);
3472 0 : return msg;
3473 : }
3474 :
3475 : static str
3476 426 : STRbatSubstitutecst_imp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3477 : int cand_nargs, const bit *rep)
3478 : {
3479 426 : BATiter bi;
3480 426 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3481 426 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3482 426 : const char *y = *getArgReference_str(stk, pci, 2),
3483 426 : *z = *getArgReference_str(stk, pci, 3);
3484 426 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3485 426 : bool nils = false;
3486 426 : bit w = *rep;
3487 426 : struct canditer ci1 = { 0 };
3488 426 : oid off1;
3489 426 : bat *res = getArgReference_bat(stk, pci, 0),
3490 426 : *bid = getArgReference_bat(stk, pci, 1),
3491 426 : *sid1 = pci->argc == cand_nargs ? getArgReference_bat(stk, pci, cand_nargs - 1) : NULL;
3492 :
3493 426 : if (!buf) {
3494 0 : msg = createException(MAL, "batstr.substritute",
3495 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3496 0 : goto bailout;
3497 : }
3498 426 : if (!(b = BATdescriptor(*bid))) {
3499 0 : msg = createException(MAL, "batstr.substritute",
3500 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3501 0 : goto bailout;
3502 : }
3503 426 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3504 0 : msg = createException(MAL, "batstr.splitpart",
3505 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3506 0 : goto bailout;
3507 : }
3508 426 : canditer_init(&ci1, b, bs);
3509 426 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3510 0 : msg = createException(MAL, "batstr.substritute",
3511 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3512 0 : goto bailout;
3513 : }
3514 :
3515 426 : (void) cntxt;
3516 426 : (void) mb;
3517 426 : off1 = b->hseqbase;
3518 426 : bi = bat_iterator(b);
3519 426 : if (ci1.tpe == cand_dense) {
3520 101277 : for (BUN i = 0; i < ci1.ncand; i++) {
3521 100851 : oid p1 = (canditer_next_dense(&ci1) - off1);
3522 100851 : const char *x = BUNtvar(bi, p1);
3523 :
3524 401766 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3525 470 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3526 0 : msg = createException(MAL, "batstr.substritute",
3527 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3528 0 : goto bailout1;
3529 : }
3530 : nils = true;
3531 : } else {
3532 100324 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3533 0 : goto bailout1;
3534 100301 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3535 0 : msg = createException(MAL, "batstr.substritute",
3536 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3537 0 : goto bailout1;
3538 : }
3539 : }
3540 : }
3541 : } else {
3542 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3543 0 : oid p1 = (canditer_next(&ci1) - off1);
3544 0 : const char *x = BUNtvar(bi, p1);
3545 :
3546 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3547 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3548 0 : msg = createException(MAL, "batstr.substritute",
3549 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3550 0 : goto bailout1;
3551 : }
3552 : nils = true;
3553 : } else {
3554 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3555 0 : goto bailout1;
3556 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3557 0 : msg = createException(MAL, "batstr.substritute",
3558 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3559 0 : goto bailout1;
3560 : }
3561 : }
3562 : }
3563 : }
3564 0 : bailout1:
3565 426 : bat_iterator_end(&bi);
3566 426 : bailout:
3567 426 : GDKfree(buf);
3568 426 : finalize_output(res, bn, msg, nils, ci1.ncand);
3569 426 : unfix_inputs(2, b, bs);
3570 426 : return msg;
3571 : }
3572 :
3573 : static str
3574 0 : STRbatSubstitutecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3575 : {
3576 0 : const bit *rep = getArgReference_bit(stk, pci, 4);
3577 0 : return STRbatSubstitutecst_imp(cntxt, mb, stk, pci, 6, rep);
3578 : }
3579 :
3580 : static str
3581 0 : STRbatSubstitute(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3582 : {
3583 0 : BATiter arg1i, arg2i, arg3i;
3584 0 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL, *arg2s = NULL,
3585 0 : *arg3 = NULL, *arg3s = NULL, *arg4 = NULL, *arg4s = NULL;
3586 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3587 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3588 0 : bool nils = false;
3589 0 : bit *restrict arg4i, w;
3590 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 }, ci4 = { 0 };
3591 0 : oid off1, off2, off3, off4;
3592 0 : bat *res = getArgReference_bat(stk, pci, 0),
3593 0 : *l = getArgReference_bat(stk, pci, 1),
3594 0 : *r = getArgReference_bat(stk, pci, 2),
3595 0 : *s = getArgReference_bat(stk, pci, 3),
3596 0 : *rep = getArgReference_bat(stk, pci, 4),
3597 0 : *sid1 = pci->argc == 9 ? getArgReference_bat(stk, pci, 5) : NULL,
3598 0 : *sid2 = pci->argc == 9 ? getArgReference_bat(stk, pci, 6) : NULL,
3599 0 : *sid3 = pci->argc == 9 ? getArgReference_bat(stk, pci, 7) : NULL,
3600 0 : *sid4 = pci->argc == 9 ? getArgReference_bat(stk, pci, 8) : NULL;
3601 0 : BATiter bi;
3602 :
3603 0 : if (!buf) {
3604 0 : msg = createException(MAL, "batstr.substritute",
3605 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3606 0 : goto bailout;
3607 : }
3608 0 : if (!(arg1 = BATdescriptor(*l)) || !(arg2 = BATdescriptor(*r))
3609 0 : || !(arg3 = BATdescriptor(*s)) || !(arg4 = BATdescriptor(*rep))) {
3610 0 : msg = createException(MAL, "batstr.substritute",
3611 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3612 0 : goto bailout;
3613 : }
3614 0 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1)))
3615 0 : || (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2)))
3616 0 : || (sid3 && !is_bat_nil(*sid3) && !(arg2s = BATdescriptor(*sid3)))
3617 0 : || (sid4 && !is_bat_nil(*sid4) && !(arg4s = BATdescriptor(*sid4)))) {
3618 0 : msg = createException(MAL, "batstr.substritute",
3619 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3620 0 : goto bailout;
3621 : }
3622 0 : canditer_init(&ci1, arg1, arg1s);
3623 0 : canditer_init(&ci2, arg2, arg2s);
3624 0 : canditer_init(&ci3, arg3, arg3s);
3625 0 : canditer_init(&ci4, arg4, arg4s);
3626 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
3627 0 : || ci2.hseq != ci3.hseq || ci4.ncand != ci1.ncand
3628 0 : || ci3.hseq != ci4.hseq) {
3629 0 : msg = createException(MAL, "batstr.substritute",
3630 : ILLEGAL_ARGUMENT
3631 : " Requires bats of identical size");
3632 0 : goto bailout;
3633 : }
3634 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3635 0 : msg = createException(MAL, "batstr.substritute",
3636 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3637 0 : goto bailout;
3638 : }
3639 :
3640 0 : (void) cntxt;
3641 0 : (void) mb;
3642 0 : off1 = arg1->hseqbase;
3643 0 : off2 = arg2->hseqbase;
3644 0 : off3 = arg3->hseqbase;
3645 0 : off4 = arg4->hseqbase;
3646 0 : arg1i = bat_iterator(arg1);
3647 0 : arg2i = bat_iterator(arg2);
3648 0 : arg3i = bat_iterator(arg3);
3649 0 : bi = bat_iterator(arg4);
3650 0 : arg4i = bi.base;
3651 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense
3652 0 : && ci4.tpe == cand_dense) {
3653 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3654 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3655 0 : p2 = (canditer_next_dense(&ci2) - off2),
3656 0 : p3 = (canditer_next_dense(&ci3) - off3),
3657 0 : p4 = (canditer_next_dense(&ci4) - off4);
3658 0 : const char *x = BUNtvar(arg1i, p1);
3659 0 : const char *y = BUNtvar(arg2i, p2);
3660 0 : const char *z = BUNtvar(arg3i, p3);
3661 0 : w = arg4i[p4];
3662 :
3663 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3664 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3665 0 : msg = createException(MAL, "batstr.substritute",
3666 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3667 0 : goto bailout1;
3668 : }
3669 : nils = true;
3670 : } else {
3671 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3672 0 : goto bailout1;
3673 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3674 0 : msg = createException(MAL, "batstr.substritute",
3675 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3676 0 : goto bailout1;
3677 : }
3678 : }
3679 : }
3680 : } else {
3681 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3682 0 : oid p1 = (canditer_next(&ci1) - off1),
3683 0 : p2 = (canditer_next(&ci2) - off2),
3684 0 : p3 = (canditer_next(&ci3) - off3),
3685 0 : p4 = (canditer_next(&ci4) - off4);
3686 0 : const char *x = BUNtvar(arg1i, p1);
3687 0 : const char *y = BUNtvar(arg2i, p2);
3688 0 : const char *z = BUNtvar(arg3i, p3);
3689 0 : w = arg4i[p4];
3690 :
3691 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3692 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3693 0 : msg = createException(MAL, "batstr.substritute",
3694 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3695 0 : goto bailout1;
3696 : }
3697 : nils = true;
3698 : } else {
3699 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3700 0 : goto bailout1;
3701 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3702 0 : msg = createException(MAL, "batstr.substritute",
3703 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3704 0 : goto bailout1;
3705 : }
3706 : }
3707 : }
3708 : }
3709 0 : bailout1:
3710 0 : bat_iterator_end(&bi);
3711 0 : bat_iterator_end(&arg1i);
3712 0 : bat_iterator_end(&arg2i);
3713 0 : bat_iterator_end(&arg3i);
3714 0 : bailout:
3715 0 : GDKfree(buf);
3716 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3717 0 : unfix_inputs(8, arg1, arg1, arg2, arg2s, arg3, arg3s, arg4, arg4s);
3718 0 : return msg;
3719 : }
3720 :
3721 : static str
3722 2 : STRbatsplitpartcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3723 : {
3724 2 : BATiter bi;
3725 2 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3726 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3727 2 : int z = *getArgReference_int(stk, pci, 3);
3728 2 : const char *y = *getArgReference_str(stk, pci, 2);
3729 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3730 2 : bool nils = false;
3731 2 : struct canditer ci1 = { 0 };
3732 2 : oid off1;
3733 2 : bat *res = getArgReference_bat(stk, pci, 0),
3734 2 : *bid = getArgReference_bat(stk, pci, 1),
3735 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3736 :
3737 2 : (void) cntxt;
3738 2 : (void) mb;
3739 2 : if (!buf) {
3740 0 : msg = createException(MAL, "batstr.splitpart",
3741 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3742 0 : goto bailout;
3743 : }
3744 2 : if (!(b = BATdescriptor(*bid))) {
3745 0 : msg = createException(MAL, "batstr.splitpart",
3746 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3747 0 : goto bailout;
3748 : }
3749 2 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3750 0 : msg = createException(MAL, "batstr.splitpart",
3751 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3752 0 : goto bailout;
3753 : }
3754 2 : canditer_init(&ci1, b, bs);
3755 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3756 0 : msg = createException(MAL, "batstr.splitpart",
3757 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3758 0 : goto bailout;
3759 : }
3760 :
3761 2 : off1 = b->hseqbase;
3762 2 : bi = bat_iterator(b);
3763 2 : if (ci1.tpe == cand_dense) {
3764 16 : for (BUN i = 0; i < ci1.ncand; i++) {
3765 14 : oid p1 = (canditer_next_dense(&ci1) - off1);
3766 14 : const char *x = BUNtvar(bi, p1);
3767 :
3768 42 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3769 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3770 0 : msg = createException(MAL, "batstr.splitpart",
3771 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3772 0 : goto bailout1;
3773 : }
3774 : nils = true;
3775 : } else {
3776 14 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3777 0 : goto bailout1;
3778 14 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3779 0 : msg = createException(MAL, "batstr.splitpart",
3780 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3781 0 : goto bailout1;
3782 : }
3783 : }
3784 : }
3785 : } else {
3786 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3787 0 : oid p1 = (canditer_next(&ci1) - off1);
3788 0 : const char *x = BUNtvar(bi, p1);
3789 :
3790 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3791 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3792 0 : msg = createException(MAL, "batstr.splitpart",
3793 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3794 0 : goto bailout1;
3795 : }
3796 : nils = true;
3797 : } else {
3798 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3799 0 : goto bailout1;
3800 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3801 0 : msg = createException(MAL, "batstr.splitpart",
3802 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3803 0 : goto bailout1;
3804 : }
3805 : }
3806 : }
3807 : }
3808 0 : bailout1:
3809 2 : bat_iterator_end(&bi);
3810 2 : bailout:
3811 2 : GDKfree(buf);
3812 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
3813 2 : unfix_inputs(2, b, bs);
3814 2 : return msg;
3815 : }
3816 :
3817 : static str
3818 0 : STRbatsplitpart_needlecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3819 : InstrPtr pci)
3820 : {
3821 0 : BATiter bi, fi;
3822 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *f = NULL, *fs = NULL;
3823 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3824 0 : int *restrict field, z;
3825 0 : const char *y = *getArgReference_str(stk, pci, 2);
3826 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3827 0 : bool nils = false;
3828 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3829 0 : oid off1, off2;
3830 0 : bat *res = getArgReference_bat(stk, pci, 0),
3831 0 : *bid = getArgReference_bat(stk, pci, 1),
3832 0 : *fid = getArgReference_bat(stk, pci, 3),
3833 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
3834 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
3835 :
3836 0 : if (!buf) {
3837 0 : msg = createException(MAL, "batstr.splitpart",
3838 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3839 0 : goto bailout;
3840 : }
3841 0 : if (!(b = BATdescriptor(*bid)) || !(f = BATdescriptor(*fid))) {
3842 0 : msg = createException(MAL, "batstr.splitpart",
3843 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3844 0 : goto bailout;
3845 : }
3846 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
3847 0 : || (sid2 && !is_bat_nil(*sid2) && !(fs = BATdescriptor(*sid2)))) {
3848 0 : msg = createException(MAL, "batstr.splitpart",
3849 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3850 0 : goto bailout;
3851 : }
3852 0 : canditer_init(&ci1, b, bs);
3853 0 : canditer_init(&ci2, f, fs);
3854 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3855 0 : msg = createException(MAL, "batstr.splitpart",
3856 : ILLEGAL_ARGUMENT
3857 : " Requires bats of identical size");
3858 0 : goto bailout;
3859 : }
3860 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3861 0 : msg = createException(MAL, "batstr.splitpart",
3862 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3863 0 : goto bailout;
3864 : }
3865 :
3866 0 : (void) cntxt;
3867 0 : (void) mb;
3868 0 : off1 = b->hseqbase;
3869 0 : off2 = f->hseqbase;
3870 0 : bi = bat_iterator(b);
3871 0 : fi = bat_iterator(f);
3872 0 : field = fi.base;
3873 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3874 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3875 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3876 0 : p2 = (canditer_next_dense(&ci2) - off2);
3877 0 : const char *x = BUNtvar(bi, p1);
3878 0 : z = field[p2];
3879 :
3880 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3881 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3882 0 : msg = createException(MAL, "batstr.splitpart",
3883 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3884 0 : goto bailout1;
3885 : }
3886 : nils = true;
3887 : } else {
3888 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3889 0 : goto bailout1;
3890 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3891 0 : msg = createException(MAL, "batstr.splitpart",
3892 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3893 0 : goto bailout1;
3894 : }
3895 : }
3896 : }
3897 : } else {
3898 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3899 0 : oid p1 = (canditer_next(&ci1) - off1),
3900 0 : p2 = (canditer_next(&ci2) - off2);
3901 0 : const char *x = BUNtvar(bi, p1);
3902 0 : z = field[p2];
3903 :
3904 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3905 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3906 0 : msg = createException(MAL, "batstr.splitpart",
3907 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3908 0 : goto bailout1;
3909 : }
3910 : nils = true;
3911 : } else {
3912 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3913 0 : goto bailout1;
3914 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3915 0 : msg = createException(MAL, "batstr.splitpart",
3916 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3917 0 : goto bailout1;
3918 : }
3919 : }
3920 : }
3921 : }
3922 0 : bailout1:
3923 0 : bat_iterator_end(&fi);
3924 0 : bat_iterator_end(&bi);
3925 0 : bailout:
3926 0 : GDKfree(buf);
3927 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3928 0 : unfix_inputs(4, b, bs, f, fs);
3929 0 : return msg;
3930 : }
3931 :
3932 : static str
3933 0 : STRbatsplitpart_fieldcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3934 : InstrPtr pci)
3935 : {
3936 0 : BATiter bi, ni;
3937 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *n = NULL, *ns = NULL;
3938 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3939 0 : int z = *getArgReference_int(stk, pci, 3);
3940 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3941 0 : bool nils = false;
3942 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3943 0 : oid off1, off2;
3944 0 : bat *res = getArgReference_bat(stk, pci, 0),
3945 0 : *bid = getArgReference_bat(stk, pci, 1),
3946 0 : *nid = getArgReference_bat(stk, pci, 2),
3947 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
3948 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
3949 :
3950 0 : (void) cntxt;
3951 0 : (void) mb;
3952 0 : if (!buf) {
3953 0 : msg = createException(MAL, "batstr.splitpart",
3954 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3955 0 : goto bailout;
3956 : }
3957 0 : if (!(b = BATdescriptor(*bid)) || !(n = BATdescriptor(*nid))) {
3958 0 : msg = createException(MAL, "batstr.splitpart",
3959 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3960 0 : goto bailout;
3961 : }
3962 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
3963 0 : || (sid2 && !is_bat_nil(*sid2) && !(ns = BATdescriptor(*sid2)))) {
3964 0 : msg = createException(MAL, "batstr.splitpart",
3965 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3966 0 : goto bailout;
3967 : }
3968 0 : canditer_init(&ci1, b, bs);
3969 0 : canditer_init(&ci2, n, ns);
3970 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3971 0 : msg = createException(MAL, "batstr.splitpart",
3972 : ILLEGAL_ARGUMENT
3973 : " Requires bats of identical size");
3974 0 : goto bailout;
3975 : }
3976 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3977 0 : msg = createException(MAL, "batstr.splitpart",
3978 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3979 0 : goto bailout;
3980 : }
3981 :
3982 0 : off1 = b->hseqbase;
3983 0 : off2 = n->hseqbase;
3984 0 : bi = bat_iterator(b);
3985 0 : ni = bat_iterator(n);
3986 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3987 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3988 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3989 0 : p2 = (canditer_next_dense(&ci2) - off2);
3990 0 : const char *x = BUNtvar(bi, p1);
3991 0 : const char *y = BUNtvar(ni, p2);
3992 :
3993 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3994 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3995 0 : msg = createException(MAL, "batstr.splitpart",
3996 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3997 0 : goto bailout1;
3998 : }
3999 : nils = true;
4000 : } else {
4001 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4002 0 : goto bailout1;
4003 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4004 0 : msg = createException(MAL, "batstr.splitpart",
4005 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4006 0 : goto bailout1;
4007 : }
4008 : }
4009 : }
4010 : } else {
4011 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4012 0 : oid p1 = (canditer_next(&ci1) - off1),
4013 0 : p2 = (canditer_next(&ci2) - off2);
4014 0 : const char *x = BUNtvar(bi, p1);
4015 0 : const char *y = BUNtvar(ni, p2);
4016 :
4017 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4018 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4019 0 : msg = createException(MAL, "batstr.splitpart",
4020 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4021 0 : goto bailout1;
4022 : }
4023 : nils = true;
4024 : } else {
4025 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4026 0 : goto bailout1;
4027 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4028 0 : msg = createException(MAL, "batstr.splitpart",
4029 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4030 0 : goto bailout1;
4031 : }
4032 : }
4033 : }
4034 : }
4035 0 : bailout1:
4036 0 : bat_iterator_end(&bi);
4037 0 : bat_iterator_end(&ni);
4038 0 : bailout:
4039 0 : GDKfree(buf);
4040 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4041 0 : unfix_inputs(4, b, bs, n, ns);
4042 0 : return msg;
4043 : }
4044 :
4045 : static str
4046 0 : STRbatsplitpart(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4047 : {
4048 0 : BATiter arg1i, arg2i;
4049 0 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL,
4050 0 : *arg2s = NULL, *arg3 = NULL, *arg3s = NULL;
4051 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4052 0 : int *restrict arg3i, z;
4053 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4054 0 : bool nils = false;
4055 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
4056 0 : oid off1, off2, off3;
4057 0 : bat *res = getArgReference_bat(stk, pci, 0),
4058 0 : *l = getArgReference_bat(stk, pci, 1),
4059 0 : *r = getArgReference_bat(stk, pci, 2),
4060 0 : *t = getArgReference_bat(stk, pci, 3),
4061 0 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
4062 0 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
4063 0 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
4064 0 : BATiter bi;
4065 :
4066 0 : (void) cntxt;
4067 0 : (void) mb;
4068 0 : if (!buf) {
4069 0 : msg = createException(MAL, "batstr.splitpart",
4070 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4071 0 : goto bailout;
4072 : }
4073 0 : if (!(arg1 = BATdescriptor(*l)) || !(arg2 = BATdescriptor(*r))
4074 0 : || !(arg3 = BATdescriptor(*t))) {
4075 0 : msg = createException(MAL, "batstr.splitpart",
4076 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4077 0 : goto bailout;
4078 : }
4079 0 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) ||
4080 0 : (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) ||
4081 0 : (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3))))
4082 : {
4083 0 : msg = createException(MAL, "batstr.splitpart",
4084 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4085 0 : goto bailout;
4086 : }
4087 0 : canditer_init(&ci1, arg1, arg1s);
4088 0 : canditer_init(&ci2, arg2, arg2s);
4089 0 : canditer_init(&ci3, arg3, arg3s);
4090 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4091 0 : || ci2.hseq != ci3.hseq) {
4092 0 : msg = createException(MAL, "batstr.splitpart",
4093 : ILLEGAL_ARGUMENT
4094 : " Requires bats of identical size");
4095 0 : goto bailout;
4096 : }
4097 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4098 0 : msg = createException(MAL, "batstr.splitpart",
4099 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4100 0 : goto bailout;
4101 : }
4102 :
4103 0 : off1 = arg1->hseqbase;
4104 0 : off2 = arg2->hseqbase;
4105 0 : off3 = arg3->hseqbase;
4106 0 : arg1i = bat_iterator(arg1);
4107 0 : arg2i = bat_iterator(arg2);
4108 0 : bi = bat_iterator(arg3);
4109 0 : arg3i = bi.base;
4110 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
4111 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4112 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4113 0 : p2 = (canditer_next_dense(&ci2) - off2),
4114 0 : p3 = (canditer_next_dense(&ci3) - off3);
4115 0 : const char *x = BUNtvar(arg1i, p1);
4116 0 : const char *y = BUNtvar(arg2i, p2);
4117 0 : z = arg3i[p3];
4118 :
4119 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4120 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4121 0 : msg = createException(MAL, "batstr.splitpart",
4122 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4123 0 : goto bailout1;
4124 : }
4125 : nils = true;
4126 : } else {
4127 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4128 0 : goto bailout1;
4129 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4130 0 : msg = createException(MAL, "batstr.splitpart",
4131 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4132 0 : goto bailout1;
4133 : }
4134 : }
4135 : }
4136 : } else {
4137 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4138 0 : oid p1 = (canditer_next(&ci1) - off1),
4139 0 : p2 = (canditer_next(&ci2) - off2),
4140 0 : p3 = (canditer_next(&ci3) - off3);
4141 0 : const char *x = BUNtvar(arg1i, p1);
4142 0 : const char *y = BUNtvar(arg2i, p2);
4143 0 : z = arg3i[p3];
4144 :
4145 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4146 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4147 0 : msg = createException(MAL, "batstr.splitpart",
4148 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4149 0 : goto bailout1;
4150 : }
4151 : nils = true;
4152 : } else {
4153 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4154 0 : goto bailout1;
4155 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4156 0 : msg = createException(MAL, "batstr.splitpart",
4157 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4158 0 : goto bailout1;
4159 : }
4160 : }
4161 : }
4162 : }
4163 0 : bailout1:
4164 0 : bat_iterator_end(&bi);
4165 0 : bat_iterator_end(&arg1i);
4166 0 : bat_iterator_end(&arg2i);
4167 0 : bailout:
4168 0 : GDKfree(buf);
4169 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4170 0 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
4171 0 : return msg;
4172 : }
4173 :
4174 : static str
4175 426 : STRbatReplacecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4176 : {
4177 426 : bit rep = TRUE;
4178 :
4179 426 : return STRbatSubstitutecst_imp(cntxt, mb, stk, pci, 5, &rep);
4180 : }
4181 :
4182 : static str
4183 2 : STRbatReplace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4184 : {
4185 2 : BATiter arg1i, arg2i, arg3i;
4186 2 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL,
4187 2 : *arg2s = NULL, *arg3 = NULL, *arg3s = NULL;
4188 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4189 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4190 2 : bool nils = false;
4191 2 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
4192 2 : oid off1, off2, off3;
4193 2 : bat *res = getArgReference_bat(stk, pci, 0),
4194 2 : *l = getArgReference_bat(stk, pci, 1),
4195 2 : *s = getArgReference_bat(stk, pci, 2),
4196 2 : *s2 = getArgReference_bat(stk, pci, 3),
4197 2 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
4198 2 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
4199 2 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
4200 :
4201 2 : (void) cntxt;
4202 2 : (void) mb;
4203 2 : if (!buf) {
4204 0 : msg = createException(MAL, "batstr.replace",
4205 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4206 0 : goto bailout;
4207 : }
4208 2 : if (!(arg1 = BATdescriptor(*l)) || !(arg2 = BATdescriptor(*s))
4209 2 : || !(arg3 = BATdescriptor(*s2))) {
4210 0 : msg = createException(MAL, "batstr.replace",
4211 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4212 0 : goto bailout;
4213 : }
4214 2 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) ||
4215 2 : (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) ||
4216 0 : (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3))))
4217 : {
4218 0 : msg = createException(MAL, "batstr.replace",
4219 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4220 0 : goto bailout;
4221 : }
4222 2 : canditer_init(&ci1, arg1, arg1s);
4223 2 : canditer_init(&ci2, arg2, arg2s);
4224 2 : canditer_init(&ci3, arg3, arg3s);
4225 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4226 2 : || ci2.hseq != ci3.hseq) {
4227 0 : msg = createException(MAL, "batstr.replace",
4228 : ILLEGAL_ARGUMENT
4229 : " Requires bats of identical size");
4230 0 : goto bailout;
4231 : }
4232 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4233 0 : msg = createException(MAL, "batstr.replace",
4234 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4235 0 : goto bailout;
4236 : }
4237 :
4238 2 : off1 = arg1->hseqbase;
4239 2 : off2 = arg2->hseqbase;
4240 2 : off3 = arg3->hseqbase;
4241 2 : arg1i = bat_iterator(arg1);
4242 2 : arg2i = bat_iterator(arg2);
4243 2 : arg3i = bat_iterator(arg3);
4244 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
4245 6 : for (BUN i = 0; i < ci1.ncand; i++) {
4246 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
4247 4 : p2 = (canditer_next_dense(&ci2) - off2),
4248 4 : p3 = (canditer_next_dense(&ci3) - off3);
4249 4 : const char *x = BUNtvar(arg1i, p1);
4250 4 : const char *y = BUNtvar(arg2i, p2);
4251 4 : const char *z = BUNtvar(arg3i, p3);
4252 :
4253 12 : if (strNil(x) || strNil(y) || strNil(z)) {
4254 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4255 0 : msg = createException(MAL, "batstr.replace",
4256 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4257 0 : goto bailout1;
4258 : }
4259 : nils = true;
4260 : } else {
4261 4 : if ((msg = str_substitute(&buf, &buflen, x, y, z, TRUE)) != MAL_SUCCEED)
4262 0 : goto bailout1;
4263 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4264 0 : msg = createException(MAL, "batstr.replace",
4265 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4266 0 : goto bailout1;
4267 : }
4268 : }
4269 : }
4270 : } else {
4271 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4272 0 : oid p1 = (canditer_next(&ci1) - off1),
4273 0 : p2 = (canditer_next(&ci2) - off2),
4274 0 : p3 = (canditer_next(&ci3) - off3);
4275 0 : const char *x = BUNtvar(arg1i, p1);
4276 0 : const char *y = BUNtvar(arg2i, p2);
4277 0 : const char *z = BUNtvar(arg3i, p3);
4278 :
4279 0 : if (strNil(x) || strNil(y) || strNil(z)) {
4280 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4281 0 : msg = createException(MAL, "batstr.replace",
4282 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4283 0 : goto bailout1;
4284 : }
4285 : nils = true;
4286 : } else {
4287 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, TRUE)) != MAL_SUCCEED)
4288 0 : goto bailout1;
4289 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4290 0 : msg = createException(MAL, "batstr.replace",
4291 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4292 0 : goto bailout1;
4293 : }
4294 : }
4295 : }
4296 : }
4297 0 : bailout1:
4298 2 : bat_iterator_end(&arg1i);
4299 2 : bat_iterator_end(&arg2i);
4300 2 : bat_iterator_end(&arg3i);
4301 2 : bailout:
4302 2 : GDKfree(buf);
4303 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
4304 2 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
4305 2 : return msg;
4306 : }
4307 :
4308 : static str
4309 0 : STRbatInsert(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4310 : {
4311 0 : BATiter lefti, righti, starti, ncharsi;
4312 0 : BAT *bn = NULL, *left = NULL, *ls = NULL, *start = NULL,
4313 0 : *ss = NULL, *nchars = NULL, *ns = NULL, *right = NULL, *rs = NULL;
4314 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4315 0 : int *sval, *lval, y, z;
4316 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4317 0 : bool nils = false;
4318 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 }, ci4 = { 0 };
4319 0 : oid off1, off2, off3, off4;
4320 0 : bat *res = getArgReference_bat(stk, pci, 0),
4321 0 : *l = getArgReference_bat(stk, pci, 1),
4322 0 : *s = getArgReference_bat(stk, pci, 2),
4323 0 : *chars = getArgReference_bat(stk, pci, 3),
4324 0 : *s2 = getArgReference_bat(stk, pci, 4),
4325 0 : *sid1 = pci->argc == 9 ? getArgReference_bat(stk, pci, 5) : NULL,
4326 0 : *sid2 = pci->argc == 9 ? getArgReference_bat(stk, pci, 6) : NULL,
4327 0 : *sid3 = pci->argc == 9 ? getArgReference_bat(stk, pci, 7) : NULL,
4328 0 : *sid4 = pci->argc == 9 ? getArgReference_bat(stk, pci, 8) : NULL;
4329 :
4330 0 : (void) cntxt;
4331 0 : (void) mb;
4332 0 : if (!buf) {
4333 0 : msg = createException(MAL, "batstr.insert",
4334 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4335 0 : goto bailout;
4336 : }
4337 0 : if (!(left = BATdescriptor(*l)) || !(start = BATdescriptor(*s))
4338 0 : || !(nchars = BATdescriptor(*chars)) || !(right = BATdescriptor(*s2))) {
4339 0 : msg = createException(MAL, "batstr.insert",
4340 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4341 0 : goto bailout;
4342 : }
4343 0 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1)))
4344 0 : || (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))
4345 0 : || (sid3 && !is_bat_nil(*sid3) && !(ss = BATdescriptor(*sid3)))
4346 0 : || (sid4 && !is_bat_nil(*sid4) && !(ns = BATdescriptor(*sid4)))) {
4347 0 : msg = createException(MAL, "batstr.insert",
4348 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4349 0 : goto bailout;
4350 : }
4351 0 : canditer_init(&ci1, left, ls);
4352 0 : canditer_init(&ci2, start, ss);
4353 0 : canditer_init(&ci3, nchars, ns);
4354 0 : canditer_init(&ci4, right, rs);
4355 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4356 0 : || ci2.hseq != ci3.hseq || ci4.ncand != ci1.ncand
4357 0 : || ci3.hseq != ci4.hseq) {
4358 0 : msg = createException(MAL, "batstr.insert",
4359 : ILLEGAL_ARGUMENT
4360 : " Requires bats of identical size");
4361 0 : goto bailout;
4362 : }
4363 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4364 0 : msg = createException(MAL, "batstr.insert",
4365 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4366 0 : goto bailout;
4367 : }
4368 :
4369 0 : off1 = left->hseqbase;
4370 0 : off2 = start->hseqbase;
4371 0 : off3 = nchars->hseqbase;
4372 0 : off4 = right->hseqbase;
4373 0 : lefti = bat_iterator(left);
4374 0 : starti = bat_iterator(start);
4375 0 : ncharsi = bat_iterator(nchars);
4376 0 : sval = starti.base;
4377 0 : lval = ncharsi.base;
4378 0 : righti = bat_iterator(right);
4379 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense
4380 0 : && ci4.tpe == cand_dense) {
4381 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4382 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4383 0 : p2 = (canditer_next_dense(&ci2) - off2),
4384 0 : p3 = (canditer_next_dense(&ci3) - off3),
4385 0 : p4 = (canditer_next_dense(&ci4) - off4);
4386 0 : const char *x = BUNtvar(lefti, p1);
4387 0 : y = sval[p2];
4388 0 : z = lval[p3];
4389 0 : const char *w = BUNtvar(righti, p4);
4390 :
4391 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4392 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4393 0 : msg = createException(MAL, "batstr.insert",
4394 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4395 0 : goto bailout1;
4396 : }
4397 : nils = true;
4398 : } else {
4399 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4400 0 : goto bailout1;
4401 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4402 0 : msg = createException(MAL, "batstr.insert",
4403 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4404 0 : goto bailout1;
4405 : }
4406 : }
4407 : }
4408 : } else {
4409 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4410 0 : oid p1 = (canditer_next(&ci1) - off1),
4411 0 : p2 = (canditer_next(&ci2) - off2),
4412 0 : p3 = (canditer_next(&ci3) - off3),
4413 0 : p4 = (canditer_next(&ci4) - off4);
4414 0 : const char *x = BUNtvar(lefti, p1);
4415 0 : y = sval[p2];
4416 0 : z = lval[p3];
4417 0 : const char *w = BUNtvar(righti, p4);
4418 :
4419 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4420 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4421 0 : msg = createException(MAL, "batstr.insert",
4422 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4423 0 : goto bailout1;
4424 : }
4425 : nils = true;
4426 : } else {
4427 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4428 0 : goto bailout1;
4429 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4430 0 : msg = createException(MAL, "batstr.insert",
4431 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4432 0 : goto bailout1;
4433 : }
4434 : }
4435 : }
4436 : }
4437 0 : bailout1:
4438 0 : bat_iterator_end(&starti);
4439 0 : bat_iterator_end(&ncharsi);
4440 0 : bat_iterator_end(&lefti);
4441 0 : bat_iterator_end(&righti);
4442 0 : bailout:
4443 0 : GDKfree(buf);
4444 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4445 0 : unfix_inputs(8, left, ls, start, ss, nchars, ns, right, rs);
4446 0 : return msg;
4447 : }
4448 :
4449 : static str
4450 0 : STRbatInsertcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4451 : {
4452 0 : BATiter bi;
4453 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4454 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4455 0 : int y = *getArgReference_int(stk, pci, 2),
4456 0 : z = *getArgReference_int(stk, pci, 3);
4457 0 : const char *w = *getArgReference_str(stk, pci, 4);
4458 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4459 0 : bool nils = false;
4460 0 : struct canditer ci1 = { 0 };
4461 0 : oid off1;
4462 0 : bat *res = getArgReference_bat(stk, pci, 0),
4463 0 : *bid = getArgReference_bat(stk, pci, 1),
4464 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4465 :
4466 0 : (void) cntxt;
4467 0 : (void) mb;
4468 0 : if (!buf) {
4469 0 : msg = createException(MAL, "batstr.insert",
4470 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4471 0 : goto bailout;
4472 : }
4473 0 : if (!(b = BATdescriptor(*bid))) {
4474 0 : msg = createException(MAL, "batstr.insert",
4475 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4476 0 : goto bailout;
4477 : }
4478 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4479 0 : msg = createException(MAL, "batstr.insert",
4480 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4481 0 : goto bailout;
4482 : }
4483 0 : canditer_init(&ci1, b, bs);
4484 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4485 0 : msg = createException(MAL, "batstr.insert",
4486 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4487 0 : goto bailout;
4488 : }
4489 :
4490 0 : off1 = b->hseqbase;
4491 0 : bi = bat_iterator(b);
4492 0 : if (ci1.tpe == cand_dense) {
4493 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4494 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
4495 0 : const char *x = BUNtvar(bi, p1);
4496 :
4497 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4498 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4499 0 : msg = createException(MAL, "batstr.insert",
4500 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4501 0 : goto bailout1;
4502 : }
4503 : nils = true;
4504 : } else {
4505 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4506 0 : goto bailout1;
4507 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4508 0 : msg = createException(MAL, "batstr.insert",
4509 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4510 0 : goto bailout1;
4511 : }
4512 : }
4513 : }
4514 : } else {
4515 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4516 0 : oid p1 = (canditer_next(&ci1) - off1);
4517 0 : const char *x = BUNtvar(bi, p1);
4518 :
4519 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4520 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4521 0 : msg = createException(MAL, "batstr.insert",
4522 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4523 0 : goto bailout1;
4524 : }
4525 : nils = true;
4526 : } else {
4527 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4528 0 : goto bailout1;
4529 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4530 0 : msg = createException(MAL, "batstr.insert",
4531 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4532 0 : goto bailout1;
4533 : }
4534 : }
4535 : }
4536 : }
4537 0 : bailout1:
4538 0 : bat_iterator_end(&bi);
4539 0 : bailout:
4540 0 : GDKfree(buf);
4541 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4542 0 : unfix_inputs(2, b, bs);
4543 0 : return msg;
4544 : }
4545 :
4546 : /*
4547 : * The substring functions require slightly different arguments
4548 : */
4549 : static str
4550 83 : STRbatsubstring_2nd_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4551 : InstrPtr pci)
4552 : {
4553 83 : BATiter bi;
4554 83 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4555 83 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4556 83 : int y = *getArgReference_int(stk, pci, 2),
4557 83 : z = *getArgReference_int(stk, pci, 3);
4558 83 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4559 83 : bool nils = false;
4560 83 : struct canditer ci1 = { 0 };
4561 83 : oid off1;
4562 83 : bat *res = getArgReference_bat(stk, pci, 0),
4563 83 : *bid = getArgReference_bat(stk, pci, 1),
4564 83 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4565 :
4566 83 : (void) cntxt;
4567 83 : (void) mb;
4568 83 : if (!buf) {
4569 0 : msg = createException(MAL, "batstr.substring",
4570 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4571 0 : goto bailout;
4572 : }
4573 83 : if (!(b = BATdescriptor(*bid))) {
4574 0 : msg = createException(MAL, "batstr.substring",
4575 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4576 0 : goto bailout;
4577 : }
4578 83 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4579 0 : msg = createException(MAL, "batstr.substring",
4580 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4581 0 : goto bailout;
4582 : }
4583 83 : canditer_init(&ci1, b, bs);
4584 83 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4585 0 : msg = createException(MAL, "batstr.substring",
4586 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4587 0 : goto bailout;
4588 : }
4589 :
4590 83 : off1 = b->hseqbase;
4591 83 : bi = bat_iterator(b);
4592 83 : if (ci1.tpe == cand_dense) {
4593 3922647 : for (BUN i = 0; i < ci1.ncand; i++) {
4594 3922564 : oid p1 = (canditer_next_dense(&ci1) - off1);
4595 3922564 : const char *x = BUNtvar(bi, p1);
4596 :
4597 7705774 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4598 96579 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4599 0 : msg = createException(MAL, "batstr.substring",
4600 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4601 0 : goto bailout1;
4602 : }
4603 : nils = true;
4604 : } else {
4605 3806012 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4606 0 : goto bailout1;
4607 3845965 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4608 0 : msg = createException(MAL, "batstr.substring",
4609 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4610 0 : goto bailout1;
4611 : }
4612 : }
4613 : }
4614 : } else {
4615 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4616 0 : oid p1 = (canditer_next(&ci1) - off1);
4617 0 : const char *x = BUNtvar(bi, p1);
4618 :
4619 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4620 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4621 0 : msg = createException(MAL, "batstr.substring",
4622 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4623 0 : goto bailout1;
4624 : }
4625 : nils = true;
4626 : } else {
4627 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4628 0 : goto bailout1;
4629 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4630 0 : msg = createException(MAL, "batstr.substring",
4631 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4632 0 : goto bailout1;
4633 : }
4634 : }
4635 : }
4636 : }
4637 0 : bailout1:
4638 83 : bat_iterator_end(&bi);
4639 83 : bailout:
4640 83 : GDKfree(buf);
4641 83 : finalize_output(res, bn, msg, nils, ci1.ncand);
4642 83 : unfix_inputs(2, b, bs);
4643 83 : return msg;
4644 : }
4645 :
4646 : static str
4647 1 : STRbatsubstring_1st_2nd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4648 : InstrPtr pci)
4649 : {
4650 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4651 1 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4652 1 : int y = *getArgReference_int(stk, pci, 2), z, *restrict input;
4653 1 : const char *x = *getArgReference_str(stk, pci, 1);
4654 1 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4655 1 : bool nils = false;
4656 1 : struct canditer ci1 = { 0 };
4657 1 : oid off1;
4658 1 : bat *res = getArgReference_bat(stk, pci, 0),
4659 1 : *bid = getArgReference_bat(stk, pci, 3),
4660 1 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4661 1 : BATiter bi;
4662 :
4663 1 : (void) cntxt;
4664 1 : (void) mb;
4665 1 : if (!buf) {
4666 0 : msg = createException(MAL, "batstr.substring",
4667 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4668 0 : goto bailout;
4669 : }
4670 1 : if (!(b = BATdescriptor(*bid))) {
4671 0 : msg = createException(MAL, "batstr.substring",
4672 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4673 0 : goto bailout;
4674 : }
4675 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4676 0 : msg = createException(MAL, "batstr.substring",
4677 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4678 0 : goto bailout;
4679 : }
4680 1 : canditer_init(&ci1, b, bs);
4681 1 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4682 0 : msg = createException(MAL, "batstr.substring",
4683 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4684 0 : goto bailout;
4685 : }
4686 :
4687 1 : off1 = b->hseqbase;
4688 1 : bi = bat_iterator(b);
4689 1 : input = bi.base;
4690 1 : if (ci1.tpe == cand_dense) {
4691 2 : for (BUN i = 0; i < ci1.ncand; i++) {
4692 1 : oid p1 = (canditer_next_dense(&ci1) - off1);
4693 1 : z = input[p1];
4694 :
4695 2 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4696 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4697 0 : msg = createException(MAL, "batstr.substring",
4698 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4699 0 : goto bailout1;
4700 : }
4701 : nils = true;
4702 : } else {
4703 1 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4704 0 : goto bailout1;
4705 1 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4706 0 : msg = createException(MAL, "batstr.substring",
4707 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4708 0 : goto bailout1;
4709 : }
4710 : }
4711 : }
4712 : } else {
4713 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4714 0 : oid p1 = (canditer_next(&ci1) - off1);
4715 0 : z = input[p1];
4716 :
4717 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4718 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4719 0 : msg = createException(MAL, "batstr.substring",
4720 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4721 0 : goto bailout1;
4722 : }
4723 : nils = true;
4724 : } else {
4725 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4726 0 : goto bailout1;
4727 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4728 0 : msg = createException(MAL, "batstr.substring",
4729 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4730 0 : goto bailout1;
4731 : }
4732 : }
4733 : }
4734 : }
4735 0 : bailout1:
4736 1 : bat_iterator_end(&bi);
4737 1 : bailout:
4738 1 : GDKfree(buf);
4739 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
4740 1 : unfix_inputs(2, b, bs);
4741 1 : return msg;
4742 : }
4743 :
4744 : static str
4745 4 : STRbatsubstring_1st_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4746 : InstrPtr pci)
4747 : {
4748 4 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4749 4 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4750 4 : int y, z = *getArgReference_int(stk, pci, 3), *restrict input;
4751 4 : const char *x = *getArgReference_str(stk, pci, 1);
4752 4 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4753 4 : bool nils = false;
4754 4 : struct canditer ci1 = { 0 };
4755 4 : oid off1;
4756 4 : bat *res = getArgReference_bat(stk, pci, 0),
4757 4 : *bid = getArgReference_bat(stk, pci, 2),
4758 4 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4759 4 : BATiter bi;
4760 :
4761 4 : (void) cntxt;
4762 4 : (void) mb;
4763 4 : if (!buf) {
4764 0 : msg = createException(MAL, "batstr.substring",
4765 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4766 0 : goto bailout;
4767 : }
4768 4 : if (!(b = BATdescriptor(*bid))) {
4769 0 : msg = createException(MAL, "batstr.substring",
4770 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4771 0 : goto bailout;
4772 : }
4773 4 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4774 0 : msg = createException(MAL, "batstr.substring",
4775 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4776 0 : goto bailout;
4777 : }
4778 4 : canditer_init(&ci1, b, bs);
4779 4 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4780 0 : msg = createException(MAL, "batstr.substring",
4781 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4782 0 : goto bailout;
4783 : }
4784 :
4785 4 : off1 = b->hseqbase;
4786 4 : bi = bat_iterator(b);
4787 4 : input = bi.base;
4788 4 : if (ci1.tpe == cand_dense) {
4789 8 : for (BUN i = 0; i < ci1.ncand; i++) {
4790 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
4791 4 : y = input[p1];
4792 :
4793 8 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4794 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4795 0 : msg = createException(MAL, "batstr.substring",
4796 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4797 0 : goto bailout1;
4798 : }
4799 : nils = true;
4800 : } else {
4801 4 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4802 0 : goto bailout1;
4803 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4804 0 : msg = createException(MAL, "batstr.substring",
4805 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4806 0 : goto bailout1;
4807 : }
4808 : }
4809 : }
4810 : } else {
4811 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4812 0 : oid p1 = (canditer_next(&ci1) - off1);
4813 0 : y = input[p1];
4814 :
4815 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4816 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4817 0 : msg = createException(MAL, "batstr.substring",
4818 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4819 0 : goto bailout1;
4820 : }
4821 : nils = true;
4822 : } else {
4823 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4824 0 : goto bailout1;
4825 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4826 0 : msg = createException(MAL, "batstr.substring",
4827 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4828 0 : goto bailout1;
4829 : }
4830 : }
4831 : }
4832 : }
4833 0 : bailout1:
4834 4 : bat_iterator_end(&bi);
4835 4 : bailout:
4836 4 : GDKfree(buf);
4837 4 : finalize_output(res, bn, msg, nils, ci1.ncand);
4838 4 : unfix_inputs(2, b, bs);
4839 4 : return msg;
4840 : }
4841 :
4842 : static str
4843 4 : STRbatsubstring_1st_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4844 : {
4845 4 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
4846 4 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4847 4 : int y, z, *vals1, *vals2;
4848 4 : const char *x = *getArgReference_str(stk, pci, 1);
4849 4 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4850 4 : bool nils = false;
4851 4 : struct canditer ci1 = { 0 }, ci2 = { 0 };
4852 4 : oid off1, off2;
4853 4 : bat *res = getArgReference_bat(stk, pci, 0),
4854 4 : *bid = getArgReference_bat(stk, pci, 2),
4855 4 : *l = getArgReference_bat(stk, pci, 3),
4856 4 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
4857 4 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4858 4 : BATiter bi;
4859 4 : BATiter lbi;
4860 :
4861 4 : (void) cntxt;
4862 4 : (void) mb;
4863 4 : if (!buf) {
4864 0 : msg = createException(MAL, "batstr.substring",
4865 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4866 0 : goto bailout;
4867 : }
4868 4 : if (!(b = BATdescriptor(*bid)) || !(lb = BATdescriptor(*l))) {
4869 0 : msg = createException(MAL, "batstr.substring",
4870 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4871 0 : goto bailout;
4872 : }
4873 4 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
4874 4 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
4875 0 : msg = createException(MAL, "batstr.substring",
4876 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4877 0 : goto bailout;
4878 : }
4879 4 : canditer_init(&ci1, b, bs);
4880 4 : canditer_init(&ci2, lb, lbs);
4881 4 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
4882 0 : msg = createException(MAL, "batstr.substring",
4883 : ILLEGAL_ARGUMENT
4884 : " Requires bats of identical size");
4885 0 : goto bailout;
4886 : }
4887 4 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4888 0 : msg = createException(MAL, "batstr.substring",
4889 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4890 0 : goto bailout;
4891 : }
4892 :
4893 4 : off1 = b->hseqbase;
4894 4 : off2 = lb->hseqbase;
4895 4 : bi = bat_iterator(b);
4896 4 : lbi = bat_iterator(lb);
4897 4 : vals1 = bi.base;
4898 4 : vals2 = lbi.base;
4899 4 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
4900 12 : for (BUN i = 0; i < ci1.ncand; i++) {
4901 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
4902 8 : p2 = (canditer_next_dense(&ci2) - off2);
4903 8 : y = vals1[p1];
4904 8 : z = vals2[p2];
4905 :
4906 16 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4907 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4908 0 : msg = createException(MAL, "batstr.substring",
4909 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4910 0 : goto bailout1;
4911 : }
4912 : nils = true;
4913 : } else {
4914 8 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4915 0 : goto bailout1;
4916 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4917 0 : msg = createException(MAL, "batstr.substring",
4918 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4919 0 : goto bailout1;
4920 : }
4921 : }
4922 : }
4923 : } else {
4924 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4925 0 : oid p1 = (canditer_next(&ci1) - off1),
4926 0 : p2 = (canditer_next(&ci2) - off2);
4927 0 : y = vals1[p1];
4928 0 : z = vals2[p2];
4929 :
4930 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4931 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4932 0 : msg = createException(MAL, "batstr.substring",
4933 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4934 0 : goto bailout1;
4935 : }
4936 : nils = true;
4937 : } else {
4938 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4939 0 : goto bailout1;
4940 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4941 0 : msg = createException(MAL, "batstr.substring",
4942 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4943 0 : goto bailout1;
4944 : }
4945 : }
4946 : }
4947 : }
4948 0 : bailout1:
4949 4 : bat_iterator_end(&bi);
4950 4 : bat_iterator_end(&lbi);
4951 4 : bailout:
4952 4 : GDKfree(buf);
4953 4 : finalize_output(res, bn, msg, nils, ci1.ncand);
4954 4 : unfix_inputs(4, b, bs, lb, lbs);
4955 4 : return msg;
4956 : }
4957 :
4958 : static str
4959 16 : STRbatsubstring_2nd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4960 : {
4961 16 : BATiter bi;
4962 16 : BATiter lbi;
4963 16 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
4964 16 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4965 16 : int y = *getArgReference_int(stk, pci, 2), *len, z;
4966 16 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4967 16 : bool nils = false;
4968 16 : struct canditer ci1 = { 0 }, ci2 = { 0 };
4969 16 : oid off1, off2;
4970 16 : bat *res = getArgReference_bat(stk, pci, 0),
4971 16 : *bid = getArgReference_bat(stk, pci, 1),
4972 16 : *l = getArgReference_bat(stk, pci, 3),
4973 16 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
4974 16 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4975 :
4976 16 : (void) cntxt;
4977 16 : (void) mb;
4978 16 : if (!buf) {
4979 0 : msg = createException(MAL, "batstr.substring",
4980 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4981 0 : goto bailout;
4982 : }
4983 16 : if (!(b = BATdescriptor(*bid)) || !(lb = BATdescriptor(*l))) {
4984 0 : msg = createException(MAL, "batstr.substring",
4985 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4986 0 : goto bailout;
4987 : }
4988 16 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
4989 16 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
4990 0 : msg = createException(MAL, "batstr.substring",
4991 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4992 0 : goto bailout;
4993 : }
4994 16 : canditer_init(&ci1, b, bs);
4995 16 : canditer_init(&ci2, lb, lbs);
4996 16 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
4997 0 : msg = createException(MAL, "batstr.substring",
4998 : ILLEGAL_ARGUMENT
4999 : " Requires bats of identical size");
5000 0 : goto bailout;
5001 : }
5002 16 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5003 0 : msg = createException(MAL, "batstr.substring",
5004 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5005 0 : goto bailout;
5006 : }
5007 :
5008 16 : off1 = b->hseqbase;
5009 16 : off2 = lb->hseqbase;
5010 16 : bi = bat_iterator(b);
5011 16 : lbi = bat_iterator(lb);
5012 16 : len = lbi.base;
5013 16 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5014 20 : for (BUN i = 0; i < ci1.ncand; i++) {
5015 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
5016 4 : p2 = (canditer_next_dense(&ci2) - off2);
5017 4 : const char *x = BUNtvar(bi, p1);
5018 4 : z = len[p2];
5019 :
5020 8 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5021 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5022 0 : msg = createException(MAL, "batstr.substring",
5023 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5024 0 : goto bailout1;
5025 : }
5026 : nils = true;
5027 : } else {
5028 4 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5029 0 : goto bailout1;
5030 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5031 0 : msg = createException(MAL, "batstr.substring",
5032 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5033 0 : goto bailout1;
5034 : }
5035 : }
5036 : }
5037 : } else {
5038 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5039 0 : oid p1 = (canditer_next(&ci1) - off1),
5040 0 : p2 = (canditer_next(&ci2) - off2);
5041 0 : const char *x = BUNtvar(bi, p1);
5042 0 : z = len[p2];
5043 :
5044 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5045 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5046 0 : msg = createException(MAL, "batstr.substring",
5047 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5048 0 : goto bailout1;
5049 : }
5050 : nils = true;
5051 : } else {
5052 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5053 0 : goto bailout1;
5054 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5055 0 : msg = createException(MAL, "batstr.substring",
5056 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5057 0 : goto bailout1;
5058 : }
5059 : }
5060 : }
5061 : }
5062 0 : bailout1:
5063 16 : bat_iterator_end(&lbi);
5064 16 : bat_iterator_end(&bi);
5065 16 : bailout:
5066 16 : GDKfree(buf);
5067 16 : finalize_output(res, bn, msg, nils, ci1.ncand);
5068 16 : unfix_inputs(4, b, bs, lb, lbs);
5069 16 : return msg;
5070 : }
5071 :
5072 : static str
5073 0 : STRbatsubstring_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5074 : {
5075 0 : BATiter bi, lbi;
5076 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
5077 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
5078 0 : int *start, y, z = *getArgReference_int(stk, pci, 3);
5079 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
5080 0 : bool nils = false;
5081 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
5082 0 : oid off1, off2;
5083 0 : bat *res = getArgReference_bat(stk, pci, 0),
5084 0 : *bid = getArgReference_bat(stk, pci, 1),
5085 0 : *l = getArgReference_bat(stk, pci, 2),
5086 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
5087 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
5088 :
5089 0 : (void) cntxt;
5090 0 : (void) mb;
5091 0 : if (!buf) {
5092 0 : msg = createException(MAL, "batstr.substring",
5093 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5094 0 : goto bailout;
5095 : }
5096 0 : if (!(b = BATdescriptor(*bid)) || !(lb = BATdescriptor(*l))) {
5097 0 : msg = createException(MAL, "batstr.substring",
5098 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5099 0 : goto bailout;
5100 : }
5101 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
5102 0 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
5103 0 : msg = createException(MAL, "batstr.substring",
5104 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5105 0 : goto bailout;
5106 : }
5107 0 : canditer_init(&ci1, b, bs);
5108 0 : canditer_init(&ci2, lb, lbs);
5109 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5110 0 : msg = createException(MAL, "batstr.substring",
5111 : ILLEGAL_ARGUMENT
5112 : " Requires bats of identical size");
5113 0 : goto bailout;
5114 : }
5115 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5116 0 : msg = createException(MAL, "batstr.substring",
5117 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5118 0 : goto bailout;
5119 : }
5120 :
5121 0 : off1 = b->hseqbase;
5122 0 : off2 = lb->hseqbase;
5123 0 : bi = bat_iterator(b);
5124 0 : lbi = bat_iterator(lb);
5125 0 : start = lbi.base;
5126 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5127 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5128 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
5129 0 : p2 = (canditer_next_dense(&ci2) - off2);
5130 0 : const char *x = BUNtvar(bi, p1);
5131 0 : y = start[p2];
5132 :
5133 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5134 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5135 0 : msg = createException(MAL, "batstr.substring",
5136 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5137 0 : goto bailout1;
5138 : }
5139 : nils = true;
5140 : } else {
5141 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5142 0 : goto bailout1;
5143 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5144 0 : msg = createException(MAL, "batstr.substring",
5145 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5146 0 : goto bailout1;
5147 : }
5148 : }
5149 : }
5150 : } else {
5151 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5152 0 : oid p1 = (canditer_next(&ci1) - off1),
5153 0 : p2 = (canditer_next(&ci2) - off2);
5154 0 : const char *x = BUNtvar(bi, p1);
5155 0 : y = start[p2];
5156 :
5157 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5158 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5159 0 : msg = createException(MAL, "batstr.substring",
5160 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5161 0 : goto bailout1;
5162 : }
5163 : nils = true;
5164 : } else {
5165 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5166 0 : goto bailout1;
5167 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5168 0 : msg = createException(MAL, "batstr.substring",
5169 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5170 0 : goto bailout1;
5171 : }
5172 : }
5173 : }
5174 : }
5175 0 : bailout1:
5176 0 : bat_iterator_end(&lbi);
5177 0 : bat_iterator_end(&bi);
5178 0 : bailout:
5179 0 : GDKfree(buf);
5180 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5181 0 : unfix_inputs(4, b, bs, lb, lbs);
5182 0 : return msg;
5183 : }
5184 :
5185 : static str
5186 16 : STRbatsubstring(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5187 : {
5188 16 : BATiter lefti, starti, lengthi;
5189 16 : BAT *bn = NULL, *left = NULL, *ls = NULL, *start = NULL,
5190 16 : *ss = NULL, *length = NULL, *lens = NULL;
5191 16 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
5192 16 : int *svals, *lvals, y, z;
5193 16 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
5194 16 : bool nils = false;
5195 16 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
5196 16 : oid off1, off2, off3;
5197 16 : bat *res = getArgReference_bat(stk, pci, 0),
5198 16 : *l = getArgReference_bat(stk, pci, 1),
5199 16 : *r = getArgReference_bat(stk, pci, 2),
5200 16 : *t = getArgReference_bat(stk, pci, 3),
5201 16 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
5202 16 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
5203 16 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
5204 :
5205 16 : (void) cntxt;
5206 16 : (void) mb;
5207 16 : if (!buf) {
5208 0 : msg = createException(MAL, "batstr.substring",
5209 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5210 0 : goto bailout;
5211 : }
5212 16 : if (!(left = BATdescriptor(*l)) || !(start = BATdescriptor(*r))
5213 16 : || !(length = BATdescriptor(*t))) {
5214 0 : msg = createException(MAL, "batstr.substring",
5215 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5216 0 : goto bailout;
5217 : }
5218 16 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5219 16 : (sid2 && !is_bat_nil(*sid2) && !(ss = BATdescriptor(*sid2))) ||
5220 0 : (sid3 && !is_bat_nil(*sid3) && !(lens = BATdescriptor(*sid3)))) {
5221 0 : msg = createException(MAL, "batstr.substring",
5222 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5223 0 : goto bailout;
5224 : }
5225 16 : canditer_init(&ci1, left, ls);
5226 16 : canditer_init(&ci2, start, ss);
5227 16 : canditer_init(&ci3, length, lens);
5228 16 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
5229 16 : || ci2.hseq != ci3.hseq) {
5230 0 : msg = createException(MAL, "batstr.substring",
5231 : ILLEGAL_ARGUMENT
5232 : " Requires bats of identical size");
5233 0 : goto bailout;
5234 : }
5235 16 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5236 0 : msg = createException(MAL, "batstr.substring",
5237 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5238 0 : goto bailout;
5239 : }
5240 :
5241 16 : off1 = left->hseqbase;
5242 16 : off2 = start->hseqbase;
5243 16 : off3 = length->hseqbase;
5244 16 : lefti = bat_iterator(left);
5245 16 : starti = bat_iterator(start);
5246 16 : lengthi = bat_iterator(length);
5247 16 : svals = starti.base;
5248 16 : lvals = lengthi.base;
5249 16 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
5250 4237 : for (BUN i = 0; i < ci1.ncand; i++) {
5251 4221 : oid p1 = (canditer_next_dense(&ci1) - off1),
5252 4221 : p2 = (canditer_next_dense(&ci2) - off2),
5253 4221 : p3 = (canditer_next_dense(&ci3) - off3);
5254 4221 : const char *x = BUNtvar(lefti, p1);
5255 4223 : y = svals[p2];
5256 4223 : z = lvals[p3];
5257 :
5258 8416 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5259 48 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5260 0 : msg = createException(MAL, "batstr.substring",
5261 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5262 0 : goto bailout1;
5263 : }
5264 : nils = true;
5265 : } else {
5266 4175 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5267 0 : goto bailout1;
5268 4187 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5269 0 : msg = createException(MAL, "batstr.substring",
5270 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5271 0 : goto bailout1;
5272 : }
5273 : }
5274 : }
5275 : } else {
5276 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5277 0 : oid p1 = (canditer_next(&ci1) - off1),
5278 0 : p2 = (canditer_next(&ci2) - off2),
5279 0 : p3 = (canditer_next(&ci3) - off3);
5280 0 : const char *x = BUNtvar(lefti, p1);
5281 0 : y = svals[p2];
5282 0 : z = lvals[p3];
5283 :
5284 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5285 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5286 0 : msg = createException(MAL, "batstr.substring",
5287 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5288 0 : goto bailout1;
5289 : }
5290 : nils = true;
5291 : } else {
5292 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5293 0 : goto bailout1;
5294 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5295 0 : msg = createException(MAL, "batstr.substring",
5296 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5297 0 : goto bailout1;
5298 : }
5299 : }
5300 : }
5301 : }
5302 0 : bailout1:
5303 16 : bat_iterator_end(&lefti);
5304 16 : bat_iterator_end(&starti);
5305 16 : bat_iterator_end(&lengthi);
5306 16 : bailout:
5307 16 : GDKfree(buf);
5308 16 : finalize_output(res, bn, msg, nils, ci1.ncand);
5309 16 : unfix_inputs(6, left, ls, start, ss, length, lens);
5310 16 : return msg;
5311 : }
5312 :
5313 : static str
5314 0 : STRbatstrLocatecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5315 : {
5316 0 : BATiter bi;
5317 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
5318 0 : int *restrict vals;
5319 0 : const char *y = *getArgReference_str(stk, pci, 2);
5320 0 : str msg = MAL_SUCCEED;
5321 0 : bool nils = false;
5322 0 : struct canditer ci1 = { 0 };
5323 0 : oid off1;
5324 0 : bat *res = getArgReference_bat(stk, pci, 0),
5325 0 : *l = getArgReference_bat(stk, pci, 1),
5326 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
5327 :
5328 0 : (void) cntxt;
5329 0 : (void) mb;
5330 0 : if (!(b = BATdescriptor(*l))) {
5331 0 : msg = createException(MAL, "batstr.locate",
5332 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5333 0 : goto bailout;
5334 : }
5335 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
5336 0 : msg = createException(MAL, "batstr.locate",
5337 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5338 0 : goto bailout;
5339 : }
5340 0 : canditer_init(&ci1, b, bs);
5341 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5342 0 : msg = createException(MAL, "batstr.locate",
5343 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5344 0 : goto bailout;
5345 : }
5346 :
5347 0 : off1 = b->hseqbase;
5348 0 : bi = bat_iterator(b);
5349 0 : vals = Tloc(bn, 0);
5350 0 : if (ci1.tpe == cand_dense) {
5351 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5352 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
5353 0 : const char *x = BUNtvar(bi, p1);
5354 :
5355 0 : if (strNil(x) || strNil(y)) {
5356 0 : vals[i] = int_nil;
5357 0 : nils = true;
5358 : } else {
5359 0 : vals[i] = str_locate2(x, y, 1);
5360 : }
5361 : }
5362 : } else {
5363 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5364 0 : oid p1 = (canditer_next(&ci1) - off1);
5365 0 : const char *x = BUNtvar(bi, p1);
5366 :
5367 0 : if (strNil(x) || strNil(y)) {
5368 0 : vals[i] = int_nil;
5369 0 : nils = true;
5370 : } else {
5371 0 : vals[i] = str_locate2(x, y, 1);
5372 : }
5373 : }
5374 : }
5375 0 : bat_iterator_end(&bi);
5376 0 : bailout:
5377 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5378 0 : unfix_inputs(2, b, bs);
5379 0 : return msg;
5380 : }
5381 :
5382 : static str
5383 28 : STRbatstrLocate_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5384 : {
5385 28 : BATiter bi;
5386 28 : BAT *bn = NULL, *b = NULL, *bs = NULL;
5387 28 : int *restrict vals;
5388 28 : const char *x = *getArgReference_str(stk, pci, 1);
5389 28 : str msg = MAL_SUCCEED;
5390 28 : bool nils = false;
5391 28 : struct canditer ci1 = { 0 };
5392 28 : oid off1;
5393 28 : bat *res = getArgReference_bat(stk, pci, 0),
5394 28 : *l = getArgReference_bat(stk, pci, 2),
5395 28 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
5396 :
5397 28 : (void) cntxt;
5398 28 : (void) mb;
5399 28 : if (!(b = BATdescriptor(*l))) {
5400 0 : msg = createException(MAL, "batstr.locate",
5401 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5402 0 : goto bailout;
5403 : }
5404 28 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
5405 0 : msg = createException(MAL, "batstr.locate",
5406 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5407 0 : goto bailout;
5408 : }
5409 28 : canditer_init(&ci1, b, bs);
5410 28 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5411 0 : msg = createException(MAL, "batstr.locate",
5412 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5413 0 : goto bailout;
5414 : }
5415 :
5416 28 : off1 = b->hseqbase;
5417 28 : bi = bat_iterator(b);
5418 28 : vals = Tloc(bn, 0);
5419 28 : if (ci1.tpe == cand_dense) {
5420 4187 : for (BUN i = 0; i < ci1.ncand; i++) {
5421 4159 : oid p1 = (canditer_next_dense(&ci1) - off1);
5422 4159 : const char *y = BUNtvar(bi, p1);
5423 :
5424 8314 : if (strNil(x) || strNil(y)) {
5425 0 : vals[i] = int_nil;
5426 0 : nils = true;
5427 : } else {
5428 4157 : vals[i] = str_locate2(x, y, 1);
5429 : }
5430 : }
5431 : } else {
5432 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5433 0 : oid p1 = (canditer_next(&ci1) - off1);
5434 0 : const char *y = BUNtvar(bi, p1);
5435 :
5436 0 : if (strNil(x) || strNil(y)) {
5437 0 : vals[i] = int_nil;
5438 0 : nils = true;
5439 : } else {
5440 0 : vals[i] = str_locate2(x, y, 1);
5441 : }
5442 : }
5443 : }
5444 28 : bat_iterator_end(&bi);
5445 28 : bailout:
5446 28 : finalize_output(res, bn, msg, nils, ci1.ncand);
5447 28 : unfix_inputs(2, b, bs);
5448 28 : return msg;
5449 : }
5450 :
5451 : static str
5452 2 : STRbatstrLocate(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5453 : {
5454 2 : BATiter lefti, righti;
5455 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
5456 2 : int *restrict vals;
5457 2 : str msg = MAL_SUCCEED;
5458 2 : bool nils = false;
5459 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
5460 2 : oid off1, off2;
5461 2 : bat *res = getArgReference_bat(stk, pci, 0),
5462 2 : *l = getArgReference_bat(stk, pci, 1),
5463 2 : *r = getArgReference_bat(stk, pci, 2),
5464 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
5465 2 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
5466 :
5467 2 : (void) cntxt;
5468 2 : (void) mb;
5469 2 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
5470 0 : msg = createException(MAL, "batstr.locate",
5471 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5472 0 : goto bailout;
5473 : }
5474 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5475 2 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
5476 0 : msg = createException(MAL, "batstr.locate",
5477 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5478 0 : goto bailout;
5479 : }
5480 2 : canditer_init(&ci1, left, ls);
5481 2 : canditer_init(&ci2, right, rs);
5482 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5483 0 : msg = createException(MAL, "batstr.locate",
5484 : ILLEGAL_ARGUMENT
5485 : " Requires bats of identical size");
5486 0 : goto bailout;
5487 : }
5488 2 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5489 0 : msg = createException(MAL, "batstr.locate",
5490 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5491 0 : goto bailout;
5492 : }
5493 :
5494 2 : off1 = left->hseqbase;
5495 2 : off2 = right->hseqbase;
5496 2 : lefti = bat_iterator(left);
5497 2 : righti = bat_iterator(right);
5498 2 : vals = Tloc(bn, 0);
5499 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5500 10 : for (BUN i = 0; i < ci1.ncand; i++) {
5501 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
5502 8 : p2 = (canditer_next_dense(&ci2) - off2);
5503 8 : const char *x = BUNtvar(lefti, p1);
5504 8 : const char *y = BUNtvar(righti, p2);
5505 :
5506 16 : if (strNil(x) || strNil(y)) {
5507 0 : vals[i] = int_nil;
5508 0 : nils = true;
5509 : } else {
5510 8 : vals[i] = str_locate2(x, y, 1);
5511 : }
5512 : }
5513 : } else {
5514 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5515 0 : oid p1 = (canditer_next(&ci1) - off1),
5516 0 : p2 = (canditer_next(&ci2) - off2);
5517 0 : const char *x = BUNtvar(lefti, p1);
5518 0 : const char *y = BUNtvar(righti, p2);
5519 :
5520 0 : if (strNil(x) || strNil(y)) {
5521 0 : vals[i] = int_nil;
5522 0 : nils = true;
5523 : } else {
5524 0 : vals[i] = str_locate2(x, y, 1);
5525 : }
5526 : }
5527 : }
5528 2 : bat_iterator_end(&lefti);
5529 2 : bat_iterator_end(&righti);
5530 2 : bailout:
5531 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
5532 2 : unfix_inputs(4, left, ls, right, rs);
5533 2 : return msg;
5534 : }
5535 :
5536 : static str
5537 0 : STRbatstrLocate3cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5538 : {
5539 0 : BATiter bi;
5540 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
5541 0 : int *restrict vals, z = *getArgReference_int(stk, pci, 3);
5542 0 : const char *y = *getArgReference_str(stk, pci, 2);
5543 0 : str msg = MAL_SUCCEED;
5544 0 : bool nils = false;
5545 0 : struct canditer ci1 = { 0 };
5546 0 : oid off1;
5547 0 : bat *res = getArgReference_bat(stk, pci, 0),
5548 0 : *l = getArgReference_bat(stk, pci, 1),
5549 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
5550 :
5551 0 : (void) cntxt;
5552 0 : (void) mb;
5553 0 : if (!(b = BATdescriptor(*l))) {
5554 0 : msg = createException(MAL, "batstr.locate2",
5555 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5556 0 : goto bailout;
5557 : }
5558 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
5559 0 : msg = createException(MAL, "batstr.locate2",
5560 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5561 0 : goto bailout;
5562 : }
5563 0 : canditer_init(&ci1, b, bs);
5564 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5565 0 : msg = createException(MAL, "batstr.locate2",
5566 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5567 0 : goto bailout;
5568 : }
5569 :
5570 0 : off1 = b->hseqbase;
5571 0 : bi = bat_iterator(b);
5572 0 : vals = Tloc(bn, 0);
5573 0 : if (ci1.tpe == cand_dense) {
5574 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5575 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
5576 0 : const char *x = BUNtvar(bi, p1);
5577 :
5578 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5579 0 : vals[i] = int_nil;
5580 0 : nils = true;
5581 : } else {
5582 0 : vals[i] = str_locate2(x, y, z);
5583 : }
5584 : }
5585 : } else {
5586 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5587 0 : oid p1 = (canditer_next(&ci1) - off1);
5588 0 : const char *x = BUNtvar(bi, p1);
5589 :
5590 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5591 0 : vals[i] = int_nil;
5592 0 : nils = true;
5593 : } else {
5594 0 : vals[i] = str_locate2(x, y, z);
5595 : }
5596 : }
5597 : }
5598 0 : bat_iterator_end(&bi);
5599 0 : bailout:
5600 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5601 0 : unfix_inputs(2, b, bs);
5602 0 : return msg;
5603 : }
5604 :
5605 : static str
5606 0 : STRbatstrLocate3(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5607 : {
5608 0 : BATiter lefti, righti, starti;
5609 0 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL,
5610 0 : *rs = NULL, *start = NULL, *ss = NULL;
5611 0 : int *restrict vals, *restrict svals, z;
5612 0 : str msg = MAL_SUCCEED;
5613 0 : bool nils = false;
5614 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
5615 0 : oid off1, off2, off3;
5616 0 : bat *res = getArgReference_bat(stk, pci, 0),
5617 0 : *l = getArgReference_bat(stk, pci, 1),
5618 0 : *r = getArgReference_bat(stk, pci, 2),
5619 0 : *s = getArgReference_bat(stk, pci, 3),
5620 0 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
5621 0 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
5622 0 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
5623 :
5624 0 : (void) cntxt;
5625 0 : (void) mb;
5626 0 : if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))
5627 0 : || !(start = BATdescriptor(*s))) {
5628 0 : msg = createException(MAL, "batstr.locate2",
5629 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5630 0 : goto bailout;
5631 : }
5632 0 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5633 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2))) ||
5634 0 : (sid3 && !is_bat_nil(*sid3) && !(ss = BATdescriptor(*sid3)))) {
5635 0 : msg = createException(MAL, "batstr.locate2",
5636 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5637 0 : goto bailout;
5638 : }
5639 0 : canditer_init(&ci1, left, ls);
5640 0 : canditer_init(&ci2, right, rs);
5641 0 : canditer_init(&ci3, start, ss);
5642 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
5643 0 : || ci2.hseq != ci3.hseq) {
5644 0 : msg = createException(MAL, "batstr.locate2",
5645 : ILLEGAL_ARGUMENT
5646 : " Requires bats of identical size");
5647 0 : goto bailout;
5648 : }
5649 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5650 0 : msg = createException(MAL, "batstr.locate2",
5651 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5652 0 : goto bailout;
5653 : }
5654 :
5655 0 : off1 = left->hseqbase;
5656 0 : off2 = right->hseqbase;
5657 0 : off3 = start->hseqbase;
5658 0 : lefti = bat_iterator(left);
5659 0 : righti = bat_iterator(right);
5660 0 : starti = bat_iterator(start);
5661 0 : svals = starti.base;
5662 0 : vals = Tloc(bn, 0);
5663 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
5664 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5665 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
5666 0 : p2 = (canditer_next_dense(&ci2) - off2),
5667 0 : p3 = (canditer_next_dense(&ci3) - off3);
5668 0 : const char *x = BUNtvar(lefti, p1);
5669 0 : const char *y = BUNtvar(righti, p2);
5670 0 : z = svals[p3];
5671 :
5672 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5673 0 : vals[i] = int_nil;
5674 0 : nils = true;
5675 : } else {
5676 0 : vals[i] = str_locate2(x, y, z);
5677 : }
5678 : }
5679 : } else {
5680 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5681 0 : oid p1 = (canditer_next(&ci1) - off1),
5682 0 : p2 = (canditer_next(&ci2) - off2),
5683 0 : p3 = (canditer_next(&ci3) - off3);
5684 0 : const char *x = BUNtvar(lefti, p1);
5685 0 : const char *y = BUNtvar(righti, p2);
5686 0 : z = svals[p3];
5687 :
5688 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5689 0 : vals[i] = int_nil;
5690 0 : nils = true;
5691 : } else {
5692 0 : vals[i] = str_locate2(x, y, z);
5693 : }
5694 : }
5695 : }
5696 0 : bat_iterator_end(&starti);
5697 0 : bat_iterator_end(&lefti);
5698 0 : bat_iterator_end(&righti);
5699 0 : bailout:
5700 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5701 0 : unfix_inputs(6, left, ls, right, rs, start, ss);
5702 0 : return msg;
5703 : }
5704 :
5705 : static str
5706 12 : BATSTRasciify(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5707 : {
5708 : #ifdef HAVE_ICONV
5709 12 : (void) cntxt;
5710 12 : (void) mb;
5711 12 : bat *rid = getArgReference_bat(stk, pci, 0),
5712 12 : *bid = getArgReference_bat(stk, pci, 1),
5713 12 : *sid = pci->argc == 2 ? NULL : getArgReference_bat(stk, pci, 2);
5714 12 : BAT *b = NULL, *bs = NULL, *bn = NULL;
5715 12 : BATiter bi;
5716 12 : struct canditer ci = { 0 };
5717 12 : oid off;
5718 12 : bool nils = false, dense = false;
5719 12 : size_t prev_out_len = 0, in_len = 0, out_len = 0;
5720 12 : str s = NULL, out = NULL, in = NULL, msg = MAL_SUCCEED;
5721 12 : iconv_t cd;
5722 12 : const str f = "UTF-8", t = "ASCII//TRANSLIT";
5723 :
5724 : /* man iconv; /TRANSLIT */
5725 12 : if ((cd = iconv_open(t, f)) == (iconv_t) (-1))
5726 0 : throw(MAL, "batstr.asciify", "ICONV: cannot convert from (%s) to (%s).",
5727 : f, t);
5728 :
5729 12 : if (!(b = BATdescriptor(*bid))) {
5730 0 : iconv_close(cd);
5731 0 : throw(MAL, "batstr.asciify", RUNTIME_OBJECT_MISSING);
5732 : }
5733 :
5734 12 : if (sid && !is_bat_nil(*sid) && !(bs = BATdescriptor(*sid))) {
5735 0 : iconv_close(cd);
5736 0 : BBPreclaim(b);
5737 0 : throw(MAL, "batstr.asciify", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5738 : }
5739 :
5740 12 : canditer_init(&ci, b, bs);
5741 :
5742 12 : if ((bn = COLnew(ci.hseq, TYPE_str, ci.ncand, TRANSIENT)) == NULL) {
5743 0 : iconv_close(cd);
5744 0 : BBPreclaim(b);
5745 0 : BBPreclaim(bs);
5746 0 : throw(MAL, "batstr.asciify", GDK_EXCEPTION);
5747 : }
5748 :
5749 12 : off = b->hseqbase;
5750 12 : bi = bat_iterator(b);
5751 :
5752 12 : if ((s = out = GDKmalloc(64 * 1024)) == NULL) {
5753 0 : msg = createException(MAL, "batstr.asciify", MAL_MALLOC_FAIL);
5754 0 : goto exit;
5755 : }
5756 12 : prev_out_len = 64 * 1024;
5757 :
5758 12 : dense = ci.tpe == cand_dense ? true : false;
5759 4492 : for (BUN i = 0; i < ci.ncand; i++) {
5760 4480 : oid p = dense ? (canditer_next_dense(&ci) - off) : (canditer_next(&ci) -
5761 : off);
5762 4480 : in = BUNtvar(bi, p);
5763 4468 : if (strNil(in)) {
5764 0 : if (BUNappend(bn, str_nil, false) != GDK_SUCCEED) {
5765 0 : msg = createException(MAL, "batstr.asciify",
5766 : "BUNappend failed.");
5767 0 : goto exit;
5768 : }
5769 0 : nils = true;
5770 0 : continue;
5771 : }
5772 : /* over sized as single utf8 symbols change into multiple ascii characters */
5773 4468 : in_len = strlen(in), out_len = in_len * 4;
5774 4468 : if (out_len > prev_out_len) {
5775 0 : if ((out = GDKrealloc(s, out_len)) == NULL) {
5776 0 : msg = createException(MAL, "batstr.asciify", MAL_MALLOC_FAIL);
5777 0 : goto exit;
5778 : }
5779 0 : prev_out_len = out_len;
5780 0 : s = out;
5781 : }
5782 4468 : out = s;
5783 4468 : if (iconv(cd, &in, &in_len, &out, &out_len) == (size_t) -1) {
5784 0 : msg = createException(MAL, "batstr.asciify",
5785 : "ICONV: string conversion failed");
5786 0 : goto exit;
5787 : }
5788 4782 : *out = '\0';
5789 4782 : if (BUNappend(bn, s, false) != GDK_SUCCEED) {
5790 0 : msg = createException(MAL, "batstr.asciify", GDK_EXCEPTION);
5791 0 : goto exit;
5792 : }
5793 : }
5794 :
5795 12 : exit:
5796 12 : GDKfree(s);
5797 12 : bat_iterator_end(&bi);
5798 12 : iconv_close(cd);
5799 12 : finalize_output(rid, bn, msg, nils, ci.ncand);
5800 12 : unfix_inputs(2, b, bs);
5801 12 : return msg;
5802 : #else
5803 : throw(MAL, "batstr.asciify", "ICONV library not available.");
5804 : #endif
5805 : }
5806 :
5807 : #include "mel.h"
5808 : mel_func batstr_init_funcs[] = {
5809 : pattern("batstr", "length", STRbatLength, false, "Return the length of a string.", args(1,2, batarg("",int),batarg("s",str))),
5810 : pattern("batstr", "length", STRbatLength, false, "Return the length of a string.", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5811 : pattern("batstr", "nbytes", STRbatBytes, false, "Return the string length in bytes.", args(1,2, batarg("",int),batarg("s",str))),
5812 : pattern("batstr", "nbytes", STRbatBytes, false, "Return the string length in bytes.", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5813 : pattern("batstr", "toLower", STRbatLower, false, "Convert a string to lower case.", args(1,2, batarg("",str),batarg("s",str))),
5814 : pattern("batstr", "toLower", STRbatLower, false, "Convert a string to lower case.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5815 : pattern("batstr", "toUpper", STRbatUpper, false, "Convert a string to upper case.", args(1,2, batarg("",str),batarg("s",str))),
5816 : pattern("batstr", "toUpper", STRbatUpper, false, "Convert a string to upper case.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5817 : pattern("batstr", "trim", STRbatStrip, false, "Strip whitespaces around a string.", args(1,2, batarg("",str),batarg("s",str))),
5818 : pattern("batstr", "trim", STRbatStrip, false, "Strip whitespaces around a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5819 : pattern("batstr", "ltrim", STRbatLtrim, false, "Strip whitespaces from start of a string.", args(1,2, batarg("",str),batarg("s",str))),
5820 : pattern("batstr", "ltrim", STRbatLtrim, false, "Strip whitespaces from start of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5821 : pattern("batstr", "rtrim", STRbatRtrim, false, "Strip whitespaces from end of a string.", args(1,2, batarg("",str),batarg("s",str))),
5822 : pattern("batstr", "rtrim", STRbatRtrim, false, "Strip whitespaces from end of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5823 : pattern("batstr", "trim2", STRbatStrip2_const, false, "Strip characters in the second string around the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5824 : pattern("batstr", "trim2", STRbatStrip2_const, false, "Strip characters in the second string around the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5825 : pattern("batstr", "trim2", STRbatStrip2_1st_const, false, "Strip characters in the second string around the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5826 : pattern("batstr", "trim2", STRbatStrip2_1st_const, false, "Strip characters in the second string around the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5827 : pattern("batstr", "ltrim2", STRbatLtrim2_const, false, "Strip characters in the second string from start of the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5828 : pattern("batstr", "ltrim2", STRbatLtrim2_const, false, "Strip characters in the second string from start of the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5829 : pattern("batstr", "ltrim2", STRbatLtrim2_1st_const, false, "Strip characters in the second string from start of the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5830 : pattern("batstr", "ltrim2", STRbatLtrim2_1st_const, false, "Strip characters in the second string from start of the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5831 : pattern("batstr", "rtrim2", STRbatRtrim2_const, false, "Strip characters in the second string from end of the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5832 : pattern("batstr", "rtrim2", STRbatRtrim2_const, false, "Strip characters in the second string from end of the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5833 : pattern("batstr", "rtrim2", STRbatRtrim2_1st_const, false, "Strip characters in the second string from end of the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5834 : pattern("batstr", "rtrim2", STRbatRtrim2_1st_const, false, "Strip characters in the second string from end of the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5835 : pattern("batstr", "trim2", STRbatStrip2_bat, false, "Strip characters in the second strings around the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5836 : pattern("batstr", "trim2", STRbatStrip2_bat, false, "Strip characters in the second strings around the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5837 : pattern("batstr", "ltrim2", STRbatLtrim2_bat, false, "Strip characters in the second strings from start of the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5838 : pattern("batstr", "ltrim2", STRbatLtrim2_bat, false, "Strip characters in the second strings from start of the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5839 : pattern("batstr", "rtrim2", STRbatRtrim2_bat, false, "Strip characters in the second strings from end of the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5840 : pattern("batstr", "rtrim2", STRbatRtrim2_bat, false, "Strip characters in the second strings from end of the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5841 : pattern("batstr", "lpad", STRbatLpad_const, false, "Prepend whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,3, batarg("",str),batarg("s",str),arg("n",int))),
5842 : pattern("batstr", "lpad", STRbatLpad_const, false, "Prepend whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s",oid))),
5843 : pattern("batstr", "rpad", STRbatRpad_const, false, "Append whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,3, batarg("",str),batarg("s",str),arg("n",int))),
5844 : pattern("batstr", "rpad", STRbatRpad_const, false, "Append whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s",oid))),
5845 : pattern("batstr", "lpad", STRbatLpad_1st_const, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),arg("s",str),batarg("n",int))),
5846 : pattern("batstr", "lpad", STRbatLpad_1st_const, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),arg("s",str),batarg("n",int),batarg("s",oid))),
5847 : pattern("batstr", "rpad", STRbatRpad_1st_const, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),arg("s",str),batarg("n",int))),
5848 : pattern("batstr", "rpad", STRbatRpad_1st_const, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),arg("s",str),batarg("n",int),batarg("s",oid))),
5849 : pattern("batstr", "lpad", STRbatLpad_bat, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),batarg("s",str),batarg("n",int))),
5850 : pattern("batstr", "lpad", STRbatLpad_bat, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,5, batarg("",str),batarg("s",str),batarg("n",int),batarg("s1",oid),batarg("s2",oid))),
5851 : pattern("batstr", "rpad", STRbatRpad_bat, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),batarg("s",str),batarg("n",int))),
5852 : pattern("batstr", "rpad", STRbatRpad_bat, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,5, batarg("",str),batarg("s",str),batarg("n",int),batarg("s1",oid),batarg("s2",oid))),
5853 : pattern("batstr", "lpad3", STRbatLpad3_const_const, false, "Prepend the second string to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),arg("s2",str))),
5854 : pattern("batstr", "rpad3", STRbatRpad3_const_const, false, "Append the second string to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),arg("s2",str))),
5855 : pattern("batstr", "lpad3", STRbatLpad3_bat_const, false, "Prepend the second string to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),arg("s2",str))),
5856 : pattern("batstr", "rpad3", STRbatRpad3_bat_const, false, "Append the second string to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),arg("s2",str))),
5857 : pattern("batstr", "lpad3", STRbatLpad3_const_bat, false, "Prepend the second strings to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s2",str))),
5858 : pattern("batstr", "rpad3", STRbatRpad3_const_bat, false, "Append the second strings to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s2",str))),
5859 : pattern("batstr", "lpad3", STRbatLpad3_bat_bat, false, "Prepend the second strings to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),batarg("s2",str))),
5860 : pattern("batstr", "rpad3", STRbatRpad3_bat_bat, false, "Append the second strings to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),batarg("s2",str))),
5861 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5862 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5863 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5864 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5865 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string starts with substring.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5866 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string starts with substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5867 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string(with CL) starts with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5868 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string(with CL) starts with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5869 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5870 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5871 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring(with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5872 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring(with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5873 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5874 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5875 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5876 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5877 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string ends with substring.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5878 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string ends with substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5879 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string(with CL) ends with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5880 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string(with CL) ends with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5881 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5882 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5883 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring(with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5884 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring(with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5885 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5886 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5887 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5888 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5889 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5890 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5891 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle (with CL) ends with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5892 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle (with CL) ends with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5893 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5894 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5895 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle (with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5896 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle (with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5897 : pattern("batstr", "splitpart", STRbatsplitpart, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),batarg("needle",str),batarg("field",int))),
5898 : pattern("batstr", "splitpart", STRbatsplitpartcst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),arg("needle",str),arg("field",int))),
5899 : pattern("batstr", "splitpart", STRbatsplitpart_needlecst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),arg("needle",str),batarg("field",int))),
5900 : pattern("batstr", "splitpart", STRbatsplitpart_fieldcst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),batarg("needle",str),arg("field",int))),
5901 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),batarg("c",str))),
5902 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit))),
5903 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),batarg("c",str),batarg("s1",oid),batarg("s2",oid))),
5904 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,6, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5905 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),arg("c",str))),
5906 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit))),
5907 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),batarg("s",oid))),
5908 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,5, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit),batarg("s",oid))),
5909 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),arg("s",str),batarg("c",str))),
5910 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit))),
5911 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),batarg("s",oid))),
5912 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,5, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit),batarg("s",oid))),
5913 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),batarg("c",str))),
5914 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit))),
5915 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring (with CLs). Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),batarg("c",str),batarg("s1",oid),batarg("s2",oid))),
5916 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring (with CLs) + icase flag. Returns position, -1 if not found.", args(1,6, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5917 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),arg("c",str))),
5918 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit))),
5919 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring (with CL). Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),batarg("s",oid))),
5920 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring (with CL) + icase flag. Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit),batarg("s",oid))),
5921 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),arg("s",str),batarg("c",str))),
5922 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit))),
5923 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring (with CL). Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),batarg("s",oid))),
5924 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring (with CL) + icase flag. Returns position, -1 if not found.", args(1,5, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit),batarg("s",oid))),
5925 : pattern("batstr", "string", STRbatTail, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),batarg("b",str),batarg("offset",int))),
5926 : pattern("batstr", "string", STRbatTail, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,5, batarg("",str),batarg("b",str),batarg("offset",int),batarg("s1",oid),batarg("s2",oid))),
5927 : pattern("batstr", "string", STRbatTailcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),batarg("b",str),arg("offset",int))),
5928 : pattern("batstr", "string", STRbatTailcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,4, batarg("",str),batarg("b",str),arg("offset",int),batarg("s",oid))),
5929 : pattern("batstr", "string", STRbatTail_strcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),arg("b",str),batarg("offset",int))),
5930 : pattern("batstr", "string", STRbatTail_strcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,4, batarg("",str),arg("b",str),batarg("offset",int),batarg("s",oid))),
5931 : pattern("batstr", "ascii", STRbatAscii, false, "Return unicode of head of string", args(1,2, batarg("",int),batarg("s",str))),
5932 : pattern("batstr", "ascii", STRbatAscii, false, "Return unicode of head of string", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5933 : pattern("batstr", "substring", STRbatsubstringTail, false, "Extract the tail of a string", args(1,3, batarg("",str),batarg("s",str),batarg("start",int))),
5934 : pattern("batstr", "substring", STRbatsubstringTail, false, "Extract the tail of a string", args(1,5, batarg("",str),batarg("s",str),batarg("start",int),batarg("s1",oid),batarg("s2",oid))),
5935 : pattern("batstr", "substring", STRbatsubstringTailcst, false, "Extract the tail of a string", args(1,3, batarg("",str),batarg("s",str),arg("start",int))),
5936 : pattern("batstr", "substring", STRbatsubstringTailcst, false, "Extract the tail of a string", args(1,4, batarg("",str),batarg("s",str),arg("start",int),batarg("s",oid))),
5937 : pattern("batstr", "substring", STRbatsubstringTail_strcst, false, "Extract the tail of a string", args(1,3, batarg("",str),arg("s",str),batarg("start",int))),
5938 : pattern("batstr", "substring", STRbatsubstringTail_strcst, false, "Extract the tail of a string", args(1,4, batarg("",str),arg("s",str),batarg("start",int),batarg("s",oid))),
5939 : pattern("batstr", "substring3", STRbatsubstring, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),batarg("start",int),batarg("index",int))),
5940 : pattern("batstr", "substring3", STRbatsubstring, false, "Substring extraction using [start,start+length]", args(1,7, batarg("",str),batarg("s",str),batarg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid),batarg("s3",oid))),
5941 : pattern("batstr", "substring3", STRbatsubstring_2nd_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),arg("start",int),arg("index",int))),
5942 : pattern("batstr", "substring3", STRbatsubstring_2nd_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),batarg("s",str),arg("start",int),arg("index",int),batarg("s",oid))),
5943 : pattern("batstr", "substring3", STRbatsubstring_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),arg("start",int),batarg("index",int))),
5944 : pattern("batstr", "substring3", STRbatsubstring_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),batarg("s",str),arg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5945 : pattern("batstr", "substring3", STRbatsubstring_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),batarg("start",int),arg("index",int))),
5946 : pattern("batstr", "substring3", STRbatsubstring_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),batarg("s",str),batarg("start",int),arg("index",int),batarg("s1",oid),batarg("s2",oid))),
5947 : pattern("batstr", "substring3", STRbatsubstring_1st_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),arg("start",int),batarg("index",int))),
5948 : pattern("batstr", "substring3", STRbatsubstring_1st_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),arg("s",str),arg("start",int),batarg("index",int),batarg("s",oid))),
5949 : pattern("batstr", "substring3", STRbatsubstring_1st_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),batarg("start",int),arg("index",int))),
5950 : pattern("batstr", "substring3", STRbatsubstring_1st_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),arg("s",str),batarg("start",int),arg("index",int),batarg("s",oid))),
5951 : pattern("batstr", "substring3", STRbatsubstring_1st_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),batarg("start",int),batarg("index",int))),
5952 : pattern("batstr", "substring3", STRbatsubstring_1st_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),arg("s",str),batarg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5953 : pattern("batstr", "unicode", STRbatFromWChr, false, "convert a unicode to a character.", args(1,2, batarg("",str),batarg("wchar",int))),
5954 : pattern("batstr", "unicode", STRbatFromWChr, false, "convert a unicode to a character.", args(1,3, batarg("",str),batarg("wchar",int),batarg("s",oid))),
5955 : pattern("batstr", "unicodeAt", STRbatWChrAt, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),batarg("s",str),batarg("index",int))),
5956 : pattern("batstr", "unicodeAt", STRbatWChrAt, false, "get a unicode character (as an int) from a string position.", args(1,5, batarg("",int),batarg("s",str),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5957 : pattern("batstr", "unicodeAt", STRbatWChrAtcst, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),batarg("s",str),arg("index",int))),
5958 : pattern("batstr", "unicodeAt", STRbatWChrAtcst, false, "get a unicode character (as an int) from a string position.", args(1,4, batarg("",int),batarg("s",str),arg("index",int),batarg("s",oid))),
5959 : pattern("batstr", "unicodeAt", STRbatWChrAt_strcst, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),arg("s",str),batarg("index",int))),
5960 : pattern("batstr", "unicodeAt", STRbatWChrAt_strcst, false, "get a unicode character (as an int) from a string position.", args(1,4, batarg("",int),arg("s",str),batarg("index",int),batarg("s",oid))),
5961 : pattern("batstr", "substitute", STRbatSubstitute, false, "Substitute first occurrence of 'src' by\n'dst'. Iff repeated = true this is\nrepeated while 'src' can be found in the\nresult string. In order to prevent\nrecursion and result strings of unlimited\nsize, repeating is only done iff src is\nnot a substring of dst.", args(1,5, batarg("",str),batarg("s",str),batarg("src",str),batarg("dst",str),batarg("rep",bit))),
5962 : pattern("batstr", "substitute", STRbatSubstitutecst, false, "Substitute first occurrence of 'src' by\n'dst'. Iff repeated = true this is\nrepeated while 'src' can be found in the\nresult string. In order to prevent\nrecursion and result strings of unlimited\nsize, repeating is only done iff src is\nnot a substring of dst.", args(1,5, batarg("",str),batarg("s",str),arg("src",str),arg("dst",str),arg("rep",bit))),
5963 : pattern("batstr", "stringleft", STRbatprefix, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("l",int))),
5964 : pattern("batstr", "stringleft", STRbatprefix, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("l",int),batarg("s1",oid),batarg("s2",oid))),
5965 : pattern("batstr", "stringleft", STRbatprefixcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("l",int))),
5966 : pattern("batstr", "stringleft", STRbatprefixcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("l",int),batarg("s",oid))),
5967 : pattern("batstr", "stringleft", STRbatprefix_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("l",int))),
5968 : pattern("batstr", "stringleft", STRbatprefix_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("l",int),batarg("s",oid))),
5969 : pattern("batstr", "stringright", STRbatsuffix, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("l",int))),
5970 : pattern("batstr", "stringright", STRbatsuffix, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("l",int),batarg("s1",oid),batarg("s2",oid))),
5971 : pattern("batstr", "stringright", STRbatsuffixcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("l",int))),
5972 : pattern("batstr", "stringright", STRbatsuffixcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("l",int),batarg("s",oid))),
5973 : pattern("batstr", "stringright", STRbatsuffix_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("l",int))),
5974 : pattern("batstr", "stringright", STRbatsuffix_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("l",int),batarg("s",oid))),
5975 : pattern("batstr", "locate", STRbatstrLocate, false, "Locate the start position of a string", args(1,3, batarg("",int),batarg("s1",str),batarg("s2",str))),
5976 : pattern("batstr", "locate", STRbatstrLocate, false, "Locate the start position of a string", args(1,5, batarg("",int),batarg("s1",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5977 : pattern("batstr", "locate", STRbatstrLocatecst, false, "Locate the start position of a string", args(1,3, batarg("",int),batarg("s1",str),arg("s2",str))),
5978 : pattern("batstr", "locate", STRbatstrLocatecst, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),arg("s2",str),batarg("s",oid))),
5979 : pattern("batstr", "locate", STRbatstrLocate_strcst, false, "Locate the start position of a string", args(1,3, batarg("",int),arg("s1",str),batarg("s2",str))),
5980 : pattern("batstr", "locate", STRbatstrLocate_strcst, false, "Locate the start position of a string", args(1,4, batarg("",int),arg("s1",str),batarg("s2",str),batarg("s",oid))),
5981 : pattern("batstr", "locate3", STRbatstrLocate3, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),batarg("s2",str),batarg("start",int))),
5982 : pattern("batstr", "locate3", STRbatstrLocate3cst, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),arg("s2",str),arg("start",int))),
5983 : pattern("batstr", "insert", STRbatInsert, false, "Insert a string into another", args(1,5, batarg("",str),batarg("s",str),batarg("start",int),batarg("l",int),batarg("s2",str))),
5984 : pattern("batstr", "insert", STRbatInsertcst, false, "Insert a string into another", args(1,5, batarg("",str),batarg("s",str),arg("start",int),arg("l",int),arg("s2",str))),
5985 : pattern("batstr", "replace", STRbatReplace, false, "Insert a string into another", args(1,4, batarg("",str),batarg("s",str),batarg("pat",str),batarg("s2",str))),
5986 : pattern("batstr", "replace", STRbatReplacecst, false, "Insert a string into another", args(1,4, batarg("",str),batarg("s",str),arg("pat",str),arg("s2",str))),
5987 : pattern("batstr", "repeat", STRbatrepeat, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("c",int))),
5988 : pattern("batstr", "repeat", STRbatrepeat, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("c",int),batarg("s1",oid),batarg("s2",oid))),
5989 : pattern("batstr", "repeat", STRbatrepeatcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("c",int))),
5990 : pattern("batstr", "repeat", STRbatrepeatcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("c",int),batarg("s",oid))),
5991 : pattern("batstr", "repeat", STRbatrepeat_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("c",int))),
5992 : pattern("batstr", "repeat", STRbatrepeat_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("c",int),batarg("s",oid))),
5993 : pattern("batstr", "space", STRbatSpace, false, "", args(1,2, batarg("",str),batarg("l",int))),
5994 : pattern("batstr", "space", STRbatSpace, false, "", args(1,3, batarg("",str),batarg("l",int),batarg("s",oid))),
5995 : pattern("batstr", "asciify", BATSTRasciify, false, "Transform BAT of strings from UTF8 to ASCII", args(1, 2, batarg("",str), batarg("b",str))),
5996 : pattern("batstr", "asciify", BATSTRasciify, false, "Transform BAT of strings from UTF8 to ASCII", args(1, 3, batarg("",str), batarg("b",str),batarg("s",oid))),
5997 : { .imp=NULL }
5998 : };
5999 : #include "mal_import.h"
6000 : #ifdef _MSC_VER
6001 : #undef read
6002 : #pragma section(".CRT$XCU",read)
6003 : #endif
6004 329 : LIB_STARTUP_FUNC(init_batstr_mal)
6005 329 : { mal_module("batstr", NULL, batstr_init_funcs); }
|