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