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 4777 : finalize_output(bat *res, BAT *bn, const char *msg, bool nils, BUN q)
42 : {
43 4777 : if (bn && !msg) {
44 4777 : BATsetcount(bn, q);
45 4779 : bn->tnil = nils;
46 4779 : bn->tnonil = !nils;
47 4779 : bn->tkey = BATcount(bn) <= 1;
48 4779 : bn->tsorted = BATcount(bn) <= 1;
49 4779 : bn->trevsorted = BATcount(bn) <= 1;
50 4779 : bn->theap->dirty |= BATcount(bn) > 0;
51 4779 : *res = bn->batCacheid;
52 4779 : BBPkeepref(bn);
53 0 : } else if (bn)
54 0 : BBPreclaim(bn);
55 4774 : }
56 :
57 : static void
58 4901 : unfix_inputs(int nargs, ...)
59 : {
60 4901 : va_list valist;
61 :
62 4901 : va_start(valist, nargs);
63 15045 : for (int i = 0; i < nargs; i++) {
64 10132 : BAT *b = va_arg(valist, BAT *);
65 16322 : BBPreclaim(b);
66 : }
67 4913 : va_end(valist);
68 4913 : }
69 :
70 : static inline str
71 5626 : str_prefix(str *buf, size_t *buflen, const char *s, int l)
72 : {
73 5626 : return str_Sub_String(buf, buflen, s, 0, l);
74 : }
75 :
76 : static str
77 3867 : do_batstr_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
78 : const char *name, int (*func)(const char *))
79 : {
80 3867 : BATiter bi;
81 3867 : BAT *bn = NULL, *b = NULL, *bs = NULL;
82 3867 : int *restrict vals;
83 3867 : str msg = MAL_SUCCEED;
84 3867 : bool nils = false;
85 3867 : struct canditer ci1 = { 0 };
86 3867 : oid off1;
87 3867 : bat *res = getArgReference_bat(stk, pci, 0),
88 3867 : bid = *getArgReference_bat(stk, pci, 1),
89 3867 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
90 :
91 3867 : (void) cntxt;
92 3867 : (void) mb;
93 3867 : 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 3869 : 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 3878 : off1 = b->hseqbase;
110 3878 : bi = bat_iterator(b);
111 3879 : vals = Tloc(bn, 0);
112 3879 : if (ci1.tpe == cand_dense) {
113 1691732 : for (BUN i = 0; i < ci1.ncand; i++) {
114 1687903 : oid p1 = (canditer_next_dense(&ci1) - off1);
115 1687903 : const char *restrict x = BUNtvar(bi, p1);
116 :
117 1687903 : if (strNil(x)) {
118 3 : vals[i] = int_nil;
119 3 : nils = true;
120 : } else {
121 1687900 : vals[i] = func(x);
122 : }
123 : }
124 : } else {
125 1605574 : for (BUN i = 0; i < ci1.ncand; i++) {
126 1605534 : oid p1 = (canditer_next(&ci1) - off1);
127 1605593 : const char *restrict x = BUNtvar(bi, p1);
128 :
129 1605593 : if (strNil(x)) {
130 0 : vals[i] = int_nil;
131 0 : nils = true;
132 : } else {
133 1605593 : vals[i] = func(x);
134 : }
135 : }
136 : }
137 3869 : bat_iterator_end(&bi);
138 3878 : bailout:
139 3878 : finalize_output(res, bn, msg, nils, ci1.ncand);
140 3870 : unfix_inputs(2, b, bs);
141 3875 : return msg;
142 : }
143 :
144 : static str
145 3873 : STRbatLength(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
146 : {
147 3873 : bat bid = *getArgReference_bat(stk, pci, 1);
148 3873 : BAT *b = BATdescriptor(bid);
149 3879 : str err;
150 3879 : if (b && b->tascii)
151 3874 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.bytes", str_strlen);
152 : else
153 5 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.length", UTF8_strlen);
154 3875 : 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 422 : for (BUN i = 0; i < ci1.ncand; i++) {
465 372 : oid p1 = (canditer_next_dense(&ci1) - off1);
466 372 : const char *restrict x = BUNtvar(bi, p1);
467 :
468 372 : 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 367 : if ((msg = (*func) (&buf, &buflen, x)) != MAL_SUCCEED)
477 0 : goto bailout1;
478 366 : 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 11 : bailout:
608 11 : 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 137 : STRbatConvert(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1606 : BAT *(*func)(BAT *, BAT *), const char *malfunc)
1607 : {
1608 137 : BAT *bn = NULL, *b = NULL, *bs = NULL;
1609 137 : bat *res = getArgReference_bat(stk, pci, 0),
1610 137 : *bid = getArgReference_bat(stk, pci, 1),
1611 137 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
1612 :
1613 137 : (void) cntxt;
1614 137 : (void) mb;
1615 137 : if (!(b = BATdescriptor(*bid))) {
1616 0 : throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1617 : }
1618 137 : 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 137 : bn = (*func)(b, bs);
1623 136 : unfix_inputs(2, b, bs);
1624 136 : if (bn == NULL)
1625 0 : throw(MAL, malfunc, GDK_EXCEPTION);
1626 136 : *res = bn->batCacheid;
1627 136 : BBPkeepref(bn);
1628 136 : return MAL_SUCCEED;
1629 : }
1630 :
1631 : static str
1632 84 : STRbatLower(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1633 : {
1634 84 : 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 48 : for (BUN i = 0; i < ci1.ncand; i++) {
1888 33 : oid p1 = (canditer_next_dense(&ci1) - off1),
1889 33 : p2 = (canditer_next_dense(&ci2) - off2);
1890 33 : char *x = BUNtvar(lefti, p1);
1891 33 : char *y = BUNtvar(righti, p2);
1892 :
1893 66 : if (strNil(x) || strNil(y)) {
1894 0 : vals[i] = bit_nil;
1895 0 : nils = true;
1896 : } else {
1897 33 : 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 15 : 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 2024 : for (BUN i = 0; i < ci1.ncand; i++) {
2012 1966 : oid p1 = (canditer_next_dense(&ci1) - off1);
2013 1966 : char *x = BUNtvar(bi, p1);
2014 :
2015 1966 : if (ynil || strNil(x)) {
2016 6 : vals[i] = bit_nil;
2017 6 : nils = true;
2018 : } else {
2019 1960 : 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 94 : 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 6173 : for (BUN i = 0; i < ci1.ncand; i++) {
2852 6078 : oid p1 = (canditer_next_dense(&ci1) - off1);
2853 6078 : const char *x = BUNtvar(bi, p1);
2854 :
2855 11725 : 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 5644 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
2864 0 : goto bailout1;
2865 5644 : 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 5 : bailout:
3117 5 : GDKfree(buf);
3118 5 : finalize_output(res, bn, msg, nils, ci1.ncand);
3119 5 : 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 32487 : for (BUN i = 0; i < ci1.ncand; i++) {
3303 32454 : oid p1 = (canditer_next_dense(&ci1) - off1),
3304 32454 : p2 = (canditer_next_dense(&ci2) - off2);
3305 32454 : const char *x = BUNtvar(lefti, p1);
3306 32454 : y = righti[p2];
3307 :
3308 36246 : 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 3792 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3317 0 : goto bailout1;
3318 3782 : 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 357 : STRbatSubstitutecst_imp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3501 : int cand_nargs, const bit *rep)
3502 : {
3503 357 : BATiter bi;
3504 357 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3505 357 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3506 357 : const char *y = *getArgReference_str(stk, pci, 2),
3507 357 : *z = *getArgReference_str(stk, pci, 3);
3508 357 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3509 360 : bool nils = false;
3510 360 : bit w = *rep;
3511 360 : struct canditer ci1 = { 0 };
3512 360 : oid off1;
3513 360 : bat *res = getArgReference_bat(stk, pci, 0),
3514 360 : bid = *getArgReference_bat(stk, pci, 1),
3515 360 : *sid1 = pci->argc == cand_nargs ? getArgReference_bat(stk, pci, cand_nargs - 1) : NULL;
3516 :
3517 360 : if (!buf) {
3518 0 : msg = createException(MAL, "batstr.substritute",
3519 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3520 0 : goto bailout;
3521 : }
3522 360 : if (!(b = BATdescriptor(bid))) {
3523 0 : msg = createException(MAL, "batstr.substritute",
3524 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3525 0 : goto bailout;
3526 : }
3527 360 : 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 360 : canditer_init(&ci1, b, bs);
3533 359 : 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 360 : (void) cntxt;
3540 360 : (void) mb;
3541 360 : off1 = b->hseqbase;
3542 360 : bi = bat_iterator(b);
3543 358 : if (ci1.tpe == cand_dense) {
3544 93992 : for (BUN i = 0; i < ci1.ncand; i++) {
3545 93633 : oid p1 = (canditer_next_dense(&ci1) - off1);
3546 93633 : const char *x = BUNtvar(bi, p1);
3547 :
3548 374172 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3549 120 : 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 93513 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3557 0 : goto bailout1;
3558 93474 : 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 359 : bat_iterator_end(&bi);
3590 359 : bailout:
3591 359 : GDKfree(buf);
3592 359 : finalize_output(res, bn, msg, nils, ci1.ncand);
3593 360 : unfix_inputs(2, b, bs);
3594 360 : 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 357 : STRbatReplacecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4200 : {
4201 357 : bit rep = TRUE;
4202 :
4203 357 : 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 123 : STRbatsubstring_2nd_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4575 : InstrPtr pci)
4576 : {
4577 123 : BATiter bi;
4578 123 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4579 123 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4580 123 : int y = *getArgReference_int(stk, pci, 2),
4581 123 : z = *getArgReference_int(stk, pci, 3);
4582 123 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4583 123 : bool nils = false;
4584 123 : struct canditer ci1 = { 0 };
4585 123 : oid off1;
4586 123 : bat *res = getArgReference_bat(stk, pci, 0),
4587 123 : bid = *getArgReference_bat(stk, pci, 1),
4588 123 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4589 :
4590 123 : (void) cntxt;
4591 123 : (void) mb;
4592 123 : if (!buf) {
4593 0 : msg = createException(MAL, "batstr.substring",
4594 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4595 0 : goto bailout;
4596 : }
4597 123 : 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 122 : off1 = b->hseqbase;
4615 122 : bi = bat_iterator(b);
4616 123 : if (ci1.tpe == cand_dense) {
4617 3743824 : for (BUN i = 0; i < ci1.ncand; i++) {
4618 3743701 : oid p1 = (canditer_next_dense(&ci1) - off1);
4619 3743701 : const char *x = BUNtvar(bi, p1);
4620 :
4621 7388150 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4622 67085 : 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 3676616 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4630 0 : goto bailout1;
4631 3706815 : 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 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4640 0 : 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 123 : bat_iterator_end(&bi);
4663 123 : bailout:
4664 123 : GDKfree(buf);
4665 123 : finalize_output(res, bn, msg, nils, ci1.ncand);
4666 123 : 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 8 : 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 31 : off1 = b->hseqbase;
5033 31 : off2 = lb->hseqbase;
5034 31 : 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 35 : 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 31 : 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 3822 : for (BUN i = 0; i < ci1.ncand; i++) {
5275 3794 : oid p1 = (canditer_next_dense(&ci1) - off1),
5276 3794 : p2 = (canditer_next_dense(&ci2) - off2),
5277 3794 : p3 = (canditer_next_dense(&ci3) - off3);
5278 3794 : const char *x = BUNtvar(lefti, p1);
5279 3794 : y = svals[p2];
5280 3794 : z = lvals[p3];
5281 :
5282 7558 : 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 3746 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5291 0 : goto bailout1;
5292 3710 : 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 3839 : for (BUN i = 0; i < ci1.ncand; i++) {
5445 3787 : oid p1 = (canditer_next_dense(&ci1) - off1);
5446 3787 : const char *y = BUNtvar(bi, p1);
5447 :
5448 7574 : if (strNil(x) || strNil(y)) {
5449 0 : vals[i] = int_nil;
5450 0 : nils = true;
5451 : } else {
5452 3787 : 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 34 : BATSTRasciify(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5731 : {
5732 34 : 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 308 : LIB_STARTUP_FUNC(init_batstr_mal)
5935 308 : { mal_module("batstr", NULL, batstr_init_funcs); }
|