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