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 4886 : finalize_output(bat *res, BAT *bn, const char *msg, bool nils, BUN q)
42 : {
43 4886 : if (bn && !msg) {
44 4886 : BATsetcount(bn, q);
45 4886 : bn->tnil = nils;
46 4886 : bn->tnonil = !nils;
47 4886 : bn->tkey = BATcount(bn) <= 1;
48 4886 : bn->tsorted = BATcount(bn) <= 1;
49 4886 : bn->trevsorted = BATcount(bn) <= 1;
50 4886 : bn->theap->dirty |= BATcount(bn) > 0;
51 4886 : *res = bn->batCacheid;
52 4886 : BBPkeepref(bn);
53 0 : } else if (bn)
54 0 : BBPreclaim(bn);
55 4884 : }
56 :
57 : static void
58 5034 : unfix_inputs(int nargs, ...)
59 : {
60 5034 : va_list valist;
61 :
62 5034 : va_start(valist, nargs);
63 15457 : for (int i = 0; i < nargs; i++) {
64 10404 : BAT *b = va_arg(valist, BAT *);
65 16740 : BBPreclaim(b);
66 : }
67 5053 : va_end(valist);
68 5053 : }
69 :
70 : static inline str
71 5631 : str_prefix(str *buf, size_t *buflen, const char *s, int l)
72 : {
73 5631 : return str_Sub_String(buf, buflen, s, 0, l);
74 : }
75 :
76 : static str
77 3870 : do_batstr_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
78 : const char *name, int (*func)(const char *))
79 : {
80 3870 : BATiter bi;
81 3870 : BAT *bn = NULL, *b = NULL, *bs = NULL;
82 3870 : int *restrict vals;
83 3870 : str msg = MAL_SUCCEED;
84 3870 : bool nils = false;
85 3870 : struct canditer ci1 = { 0 };
86 3870 : oid off1;
87 3870 : bat *res = getArgReference_bat(stk, pci, 0),
88 3870 : bid = *getArgReference_bat(stk, pci, 1),
89 3870 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
90 :
91 3870 : (void) cntxt;
92 3870 : (void) mb;
93 3870 : if (!(b = BATdescriptor(bid))) {
94 0 : msg = createException(MAL, name,
95 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
96 0 : goto bailout;
97 : }
98 3877 : 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 3879 : canditer_init(&ci1, b, bs);
104 3866 : 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 3868 : vals = Tloc(bn, 0);
112 3868 : if (ci1.tpe == cand_dense) {
113 1621782 : for (BUN i = 0; i < ci1.ncand; i++) {
114 1617955 : oid p1 = (canditer_next_dense(&ci1) - off1);
115 1617955 : const char *restrict x = BUNtvar(bi, p1);
116 :
117 1617955 : if (strNil(x)) {
118 3 : vals[i] = int_nil;
119 3 : nils = true;
120 : } else {
121 1617952 : vals[i] = func(x);
122 : }
123 : }
124 : } else {
125 1521246 : for (BUN i = 0; i < ci1.ncand; i++) {
126 1521206 : oid p1 = (canditer_next(&ci1) - off1);
127 1520957 : const char *restrict x = BUNtvar(bi, p1);
128 :
129 1520957 : if (strNil(x)) {
130 0 : vals[i] = int_nil;
131 0 : nils = true;
132 : } else {
133 1520957 : vals[i] = func(x);
134 : }
135 : }
136 : }
137 3867 : bat_iterator_end(&bi);
138 3876 : bailout:
139 3876 : finalize_output(res, bn, msg, nils, ci1.ncand);
140 3874 : unfix_inputs(2, b, bs);
141 3878 : return msg;
142 : }
143 :
144 : static str
145 3867 : STRbatLength(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
146 : {
147 3867 : bat bid = *getArgReference_bat(stk, pci, 1);
148 3867 : BAT *b = BATdescriptor(bid);
149 3877 : str err;
150 3877 : if (b && b->tascii)
151 3873 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.bytes", str_strlen);
152 : else
153 4 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.length", UTF8_strlen);
154 3871 : BBPreclaim(b);
155 3875 : 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 49 : do_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
426 : const char *name, str (*func)(str *, size_t *, const char *))
427 : {
428 49 : BATiter bi;
429 49 : BAT *bn = NULL, *b = NULL, *bs = NULL;
430 49 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
431 49 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
432 50 : bool nils = false;
433 50 : struct canditer ci1 = { 0 };
434 50 : oid off1;
435 50 : bat *res = getArgReference_bat(stk, pci, 0),
436 50 : bid = *getArgReference_bat(stk, pci, 1),
437 50 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
438 :
439 50 : (void) cntxt;
440 50 : (void) mb;
441 50 : if (!buf) {
442 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
443 0 : goto bailout;
444 : }
445 50 : if (!(b = BATdescriptor(bid))) {
446 0 : msg = createException(MAL, name,
447 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
448 0 : goto bailout;
449 : }
450 50 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
451 0 : msg = createException(MAL, name,
452 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
453 0 : goto bailout;
454 : }
455 50 : canditer_init(&ci1, b, bs);
456 50 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
457 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
458 0 : goto bailout;
459 : }
460 :
461 50 : off1 = b->hseqbase;
462 50 : bi = bat_iterator(b);
463 50 : if (ci1.tpe == cand_dense) {
464 423 : for (BUN i = 0; i < ci1.ncand; i++) {
465 373 : oid p1 = (canditer_next_dense(&ci1) - off1);
466 373 : const char *restrict x = BUNtvar(bi, p1);
467 :
468 373 : if (strNil(x)) {
469 5 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
470 0 : msg = createException(MAL, name,
471 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
472 0 : goto bailout1;
473 : }
474 : nils = true;
475 : } else {
476 368 : if ((msg = (*func) (&buf, &buflen, x)) != MAL_SUCCEED)
477 0 : goto bailout1;
478 368 : 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 1 : for (BUN i = 0; i < ci1.ncand; i++) {
487 1 : 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 10 : 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 161 : STRbatConvert(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1606 : BAT *(*func)(BAT *, BAT *), const char *malfunc)
1607 : {
1608 161 : BAT *bn = NULL, *b = NULL, *bs = NULL;
1609 161 : bat *res = getArgReference_bat(stk, pci, 0),
1610 161 : *bid = getArgReference_bat(stk, pci, 1),
1611 161 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
1612 :
1613 161 : (void) cntxt;
1614 161 : (void) mb;
1615 161 : if (!(b = BATdescriptor(*bid))) {
1616 0 : throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1617 : }
1618 161 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
1619 0 : BBPreclaim(b);
1620 0 : throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1621 : }
1622 161 : bn = (*func)(b, bs);
1623 161 : unfix_inputs(2, b, bs);
1624 161 : if (bn == NULL)
1625 0 : throw(MAL, malfunc, GDK_EXCEPTION);
1626 161 : *res = bn->batCacheid;
1627 161 : BBPkeepref(bn);
1628 161 : return MAL_SUCCEED;
1629 : }
1630 :
1631 : static str
1632 108 : STRbatLower(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1633 : {
1634 108 : return STRbatConvert(cntxt, mb, stk, pci, BATtolower, "batstr.toLower");
1635 : }
1636 :
1637 : static str
1638 19 : STRbatUpper(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1639 : {
1640 19 : return STRbatConvert(cntxt, mb, stk, pci, BATtoupper, "batstr.toUpper");
1641 : }
1642 :
1643 : static str
1644 0 : STRbatCaseFold(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1645 : {
1646 0 : return STRbatConvert(cntxt, mb, stk, pci, BATcasefold, "batstr.caseFold");
1647 : }
1648 :
1649 : static str
1650 10 : STRbatStrip(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1651 : {
1652 10 : return do_batstr_str(cntxt, mb, stk, pci, "batstr.strip", str_strip);
1653 : }
1654 :
1655 : static str
1656 2 : STRbatLtrim(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1657 : {
1658 2 : return do_batstr_str(cntxt, mb, stk, pci, "batstr.ltrim", str_ltrim);
1659 : }
1660 :
1661 : static str
1662 38 : STRbatRtrim(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1663 : {
1664 38 : return do_batstr_str(cntxt, mb, stk, pci, "batstr.rtrim", str_rtrim);
1665 : }
1666 :
1667 : static str
1668 9 : STRbatStrip2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1669 : {
1670 9 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.strip",
1671 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1672 : str_strip2);
1673 : }
1674 :
1675 : static str
1676 1 : STRbatLtrim2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1677 : {
1678 1 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.ltrim",
1679 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1680 : str_ltrim2);
1681 : }
1682 :
1683 : static str
1684 1 : STRbatRtrim2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1685 : {
1686 1 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.rtrim",
1687 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1688 : str_rtrim2);
1689 : }
1690 :
1691 : static str
1692 0 : STRbatStrip2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1693 : {
1694 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.strip",
1695 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1696 : str_strip2);
1697 : }
1698 :
1699 : static str
1700 0 : STRbatLtrim2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1701 : {
1702 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.ltrim",
1703 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1704 : str_ltrim2);
1705 : }
1706 :
1707 : static str
1708 0 : STRbatRtrim2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1709 : {
1710 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.rtrim",
1711 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1712 : str_rtrim2);
1713 : }
1714 :
1715 : static str
1716 1 : STRbatStrip2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1717 : {
1718 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.strip",
1719 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1720 : str_strip2);
1721 : }
1722 :
1723 : static str
1724 1 : STRbatLtrim2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1725 : {
1726 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.ltrim",
1727 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1728 : str_ltrim2);
1729 : }
1730 :
1731 : static str
1732 1 : STRbatRtrim2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1733 : {
1734 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.rtrim",
1735 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1736 : str_rtrim2);
1737 : }
1738 :
1739 : static str
1740 1 : STRbatLpad_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1741 : {
1742 1 : return do_batstr_constint_str(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1743 : }
1744 :
1745 : static str
1746 1 : STRbatRpad_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1747 : {
1748 1 : return do_batstr_constint_str(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1749 : }
1750 :
1751 : static str
1752 0 : STRbatLpad_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1753 : {
1754 0 : return do_batstr_int_conststr(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1755 : }
1756 :
1757 : static str
1758 0 : STRbatRpad_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1759 : {
1760 0 : return do_batstr_int_conststr(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1761 : }
1762 :
1763 : static str
1764 1 : STRbatLpad_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1765 : {
1766 1 : return do_batstr_batint_str(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1767 : }
1768 :
1769 : static str
1770 1 : STRbatRpad_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1771 : {
1772 1 : return do_batstr_batint_str(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1773 : }
1774 :
1775 : static str
1776 1 : STRbatLpad3_const_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1777 : {
1778 1 : return do_batstr_constint_conststr_str(cntxt, mb, stk, pci, "batstr.lpad",
1779 : str_lpad3);
1780 : }
1781 :
1782 : static str
1783 1 : STRbatRpad3_const_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1784 : {
1785 1 : return do_batstr_constint_conststr_str(cntxt, mb, stk, pci, "batstr.rpad",
1786 : str_rpad3);
1787 : }
1788 :
1789 : static str
1790 1 : STRbatLpad3_bat_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1791 : {
1792 1 : return do_batstr_batint_conststr_str(cntxt, mb, stk, pci, "batstr.lpad",
1793 : str_lpad3);
1794 : }
1795 :
1796 : static str
1797 1 : STRbatRpad3_bat_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1798 : {
1799 1 : return do_batstr_batint_conststr_str(cntxt, mb, stk, pci, "batstr.rpad",
1800 : str_rpad3);
1801 : }
1802 :
1803 : static str
1804 1 : STRbatLpad3_const_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1805 : {
1806 1 : return do_batstr_constint_batstr_str(cntxt, mb, stk, pci, "batstr.lpad",
1807 : str_lpad3);
1808 : }
1809 :
1810 : static str
1811 1 : STRbatRpad3_const_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1812 : {
1813 1 : return do_batstr_constint_batstr_str(cntxt, mb, stk, pci, "batstr.rpad",
1814 : str_rpad3);
1815 : }
1816 :
1817 : static str
1818 1 : STRbatLpad3_bat_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1819 : {
1820 1 : return do_batstr_batint_batstr_str(cntxt, mb, stk, pci, "batstr.lpad",
1821 : str_lpad3);
1822 : }
1823 :
1824 : static str
1825 1 : STRbatRpad3_bat_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1826 : {
1827 1 : return do_batstr_batint_batstr_str(cntxt, mb, stk, pci, "batstr.rpad",
1828 : str_rpad3);
1829 : }
1830 :
1831 : /*
1832 : * A general assumption in all cases is the bats are synchronized on their
1833 : * head column. This is not checked and may be mis-used to deploy the
1834 : * implementation for shifted window arithmetic as well.
1835 : */
1836 : static str
1837 15 : prefix_or_suffix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1838 : const char *name, int (*func)(const char *, const char *, int),
1839 : bit *icase)
1840 : {
1841 15 : (void) cntxt;
1842 15 : (void) mb;
1843 :
1844 15 : BATiter lefti, righti;
1845 15 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
1846 15 : bit *restrict vals;
1847 15 : str msg = MAL_SUCCEED;
1848 15 : bool nils = false;
1849 15 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1850 15 : oid off1, off2;
1851 15 : bat *res = getArgReference_bat(stk, pci, 0),
1852 15 : l = *getArgReference_bat(stk, pci, 1),
1853 15 : r = *getArgReference_bat(stk, pci, 2),
1854 28 : *sid1 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 4 : 3) : NULL,
1855 28 : *sid2 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 5 : 4) : NULL;
1856 :
1857 15 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
1858 0 : msg = createException(MAL, name,
1859 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1860 0 : goto exit2;
1861 : }
1862 15 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) ||
1863 13 : (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
1864 0 : msg = createException(MAL, name,
1865 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1866 0 : goto exit2;
1867 : }
1868 15 : canditer_init(&ci1, left, lefts);
1869 15 : canditer_init(&ci2, right, rights);
1870 15 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1871 0 : msg = createException(MAL, name,
1872 : ILLEGAL_ARGUMENT
1873 : " Requires bats of identical size");
1874 0 : goto exit2;
1875 : }
1876 15 : if (!(bn = COLnew(ci1.hseq, TYPE_bit, ci1.ncand, TRANSIENT))) {
1877 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1878 0 : goto exit2;
1879 : }
1880 :
1881 15 : off1 = left->hseqbase;
1882 15 : off2 = right->hseqbase;
1883 15 : lefti = bat_iterator(left);
1884 15 : righti = bat_iterator(right);
1885 15 : vals = Tloc(bn, 0);
1886 15 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1887 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 2026 : for (BUN i = 0; i < ci1.ncand; i++) {
2012 1968 : oid p1 = (canditer_next_dense(&ci1) - off1);
2013 1968 : char *x = BUNtvar(bi, p1);
2014 :
2015 1968 : if (ynil || strNil(x)) {
2016 6 : vals[i] = bit_nil;
2017 6 : nils = true;
2018 : } else {
2019 1962 : 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 94 : 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 94 : BATiter bi;
2815 94 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2816 94 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2817 94 : int y = *getArgReference_int(stk, pci, 2);
2818 94 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2819 94 : bool nils = false;
2820 94 : struct canditer ci1 = { 0 };
2821 94 : oid off1;
2822 94 : bat *res = getArgReference_bat(stk, pci, 0),
2823 94 : l = *getArgReference_bat(stk, pci, 1),
2824 94 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2825 :
2826 94 : (void) cntxt;
2827 94 : (void) mb;
2828 94 : if (!buf) {
2829 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2830 0 : goto bailout;
2831 : }
2832 94 : 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 94 : off1 = b->hseqbase;
2849 94 : bi = bat_iterator(b);
2850 95 : if (ci1.tpe == cand_dense) {
2851 6178 : for (BUN i = 0; i < ci1.ncand; i++) {
2852 6083 : oid p1 = (canditer_next_dense(&ci1) - off1);
2853 6083 : const char *x = BUNtvar(bi, p1);
2854 :
2855 11735 : 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 5649 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
2864 0 : goto bailout1;
2865 5648 : 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 1 : for (BUN i = 0; i < ci1.ncand; i++) {
2874 1 : 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 94 : bailout:
2898 94 : 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 34 : 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 34 : BATiter lefti;
3252 34 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
3253 34 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3254 34 : int *restrict righti, y;
3255 34 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3256 34 : bool nils = false;
3257 34 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3258 34 : oid off1, off2;
3259 34 : bat *res = getArgReference_bat(stk, pci, 0),
3260 34 : l = *getArgReference_bat(stk, pci, 1),
3261 34 : r = *getArgReference_bat(stk, pci, 2),
3262 34 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
3263 34 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3264 34 : BATiter bi;
3265 :
3266 34 : (void) cntxt;
3267 34 : (void) mb;
3268 34 : if (!buf) {
3269 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3270 0 : goto bailout;
3271 : }
3272 34 : 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 34 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
3278 34 : || (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 34 : canditer_init(&ci1, left, lefts);
3284 34 : canditer_init(&ci2, right, rights);
3285 34 : 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 34 : 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 34 : off1 = left->hseqbase;
3297 34 : off2 = right->hseqbase;
3298 34 : lefti = bat_iterator(left);
3299 34 : bi = bat_iterator(right);
3300 34 : righti = bi.base;
3301 34 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3302 33636 : for (BUN i = 0; i < ci1.ncand; i++) {
3303 33602 : oid p1 = (canditer_next_dense(&ci1) - off1),
3304 33602 : p2 = (canditer_next_dense(&ci2) - off2);
3305 33602 : const char *x = BUNtvar(lefti, p1);
3306 33602 : y = righti[p2];
3307 :
3308 37440 : if (strNil(x) || is_int_nil(y)) {
3309 29764 : 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 3838 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3317 0 : goto bailout1;
3318 3827 : 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 34 : bat_iterator_end(&bi);
3352 34 : bat_iterator_end(&lefti);
3353 34 : bailout:
3354 34 : GDKfree(buf);
3355 34 : finalize_output(res, bn, msg, nils, ci1.ncand);
3356 34 : unfix_inputs(4, left, lefts, right, rights);
3357 34 : 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 34 : STRbatsubstringTail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3380 : {
3381 34 : 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 468 : STRbatSubstitutecst_imp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3501 : int cand_nargs, const bit *rep)
3502 : {
3503 468 : BATiter bi;
3504 468 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3505 468 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3506 468 : const char *y = *getArgReference_str(stk, pci, 2),
3507 468 : *z = *getArgReference_str(stk, pci, 3);
3508 468 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3509 470 : bool nils = false;
3510 470 : bit w = *rep;
3511 470 : struct canditer ci1 = { 0 };
3512 470 : oid off1;
3513 470 : bat *res = getArgReference_bat(stk, pci, 0),
3514 470 : bid = *getArgReference_bat(stk, pci, 1),
3515 470 : *sid1 = pci->argc == cand_nargs ? getArgReference_bat(stk, pci, cand_nargs - 1) : NULL;
3516 :
3517 470 : if (!buf) {
3518 0 : msg = createException(MAL, "batstr.substritute",
3519 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3520 0 : goto bailout;
3521 : }
3522 470 : if (!(b = BATdescriptor(bid))) {
3523 0 : msg = createException(MAL, "batstr.substritute",
3524 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3525 0 : goto bailout;
3526 : }
3527 471 : 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 471 : canditer_init(&ci1, b, bs);
3533 467 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3534 0 : msg = createException(MAL, "batstr.substritute",
3535 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3536 0 : goto bailout;
3537 : }
3538 :
3539 472 : (void) cntxt;
3540 472 : (void) mb;
3541 472 : off1 = b->hseqbase;
3542 472 : bi = bat_iterator(b);
3543 470 : if (ci1.tpe == cand_dense) {
3544 133089 : for (BUN i = 0; i < ci1.ncand; i++) {
3545 132619 : oid p1 = (canditer_next_dense(&ci1) - off1);
3546 132619 : const char *x = BUNtvar(bi, p1);
3547 :
3548 527956 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3549 840 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3550 0 : msg = createException(MAL, "batstr.substritute",
3551 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3552 0 : goto bailout1;
3553 : }
3554 : nils = true;
3555 : } else {
3556 131779 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3557 0 : goto bailout1;
3558 131726 : 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 1 : for (BUN i = 0; i < ci1.ncand; i++) {
3567 1 : 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 470 : bat_iterator_end(&bi);
3590 472 : bailout:
3591 472 : GDKfree(buf);
3592 472 : finalize_output(res, bn, msg, nils, ci1.ncand);
3593 471 : unfix_inputs(2, b, bs);
3594 472 : return msg;
3595 : }
3596 :
3597 : static str
3598 0 : STRbatSubstitutecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3599 : {
3600 0 : const bit *rep = getArgReference_bit(stk, pci, 4);
3601 0 : return STRbatSubstitutecst_imp(cntxt, mb, stk, pci, 6, rep);
3602 : }
3603 :
3604 : static str
3605 0 : STRbatSubstitute(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3606 : {
3607 0 : BATiter arg1i, arg2i, arg3i;
3608 0 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL, *arg2s = NULL,
3609 0 : *arg3 = NULL, *arg3s = NULL, *arg4 = NULL, *arg4s = NULL;
3610 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3611 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3612 0 : bool nils = false;
3613 0 : bit *restrict arg4i, w;
3614 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 }, ci4 = { 0 };
3615 0 : oid off1, off2, off3, off4;
3616 0 : bat *res = getArgReference_bat(stk, pci, 0),
3617 0 : l = *getArgReference_bat(stk, pci, 1),
3618 0 : r = *getArgReference_bat(stk, pci, 2),
3619 0 : s = *getArgReference_bat(stk, pci, 3),
3620 0 : rep = *getArgReference_bat(stk, pci, 4),
3621 0 : *sid1 = pci->argc == 9 ? getArgReference_bat(stk, pci, 5) : NULL,
3622 0 : *sid2 = pci->argc == 9 ? getArgReference_bat(stk, pci, 6) : NULL,
3623 0 : *sid3 = pci->argc == 9 ? getArgReference_bat(stk, pci, 7) : NULL,
3624 0 : *sid4 = pci->argc == 9 ? getArgReference_bat(stk, pci, 8) : NULL;
3625 0 : BATiter bi;
3626 :
3627 0 : if (!buf) {
3628 0 : msg = createException(MAL, "batstr.substritute",
3629 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3630 0 : goto bailout;
3631 : }
3632 0 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(r))
3633 0 : || !(arg3 = BATdescriptor(s)) || !(arg4 = BATdescriptor(rep))) {
3634 0 : msg = createException(MAL, "batstr.substritute",
3635 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3636 0 : goto bailout;
3637 : }
3638 0 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1)))
3639 0 : || (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2)))
3640 0 : || (sid3 && !is_bat_nil(*sid3) && !(arg2s = BATdescriptor(*sid3)))
3641 0 : || (sid4 && !is_bat_nil(*sid4) && !(arg4s = BATdescriptor(*sid4)))) {
3642 0 : msg = createException(MAL, "batstr.substritute",
3643 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3644 0 : goto bailout;
3645 : }
3646 0 : canditer_init(&ci1, arg1, arg1s);
3647 0 : canditer_init(&ci2, arg2, arg2s);
3648 0 : canditer_init(&ci3, arg3, arg3s);
3649 0 : canditer_init(&ci4, arg4, arg4s);
3650 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
3651 0 : || ci2.hseq != ci3.hseq || ci4.ncand != ci1.ncand
3652 0 : || ci3.hseq != ci4.hseq) {
3653 0 : msg = createException(MAL, "batstr.substritute",
3654 : ILLEGAL_ARGUMENT
3655 : " Requires bats of identical size");
3656 0 : goto bailout;
3657 : }
3658 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3659 0 : msg = createException(MAL, "batstr.substritute",
3660 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3661 0 : goto bailout;
3662 : }
3663 :
3664 0 : (void) cntxt;
3665 0 : (void) mb;
3666 0 : off1 = arg1->hseqbase;
3667 0 : off2 = arg2->hseqbase;
3668 0 : off3 = arg3->hseqbase;
3669 0 : off4 = arg4->hseqbase;
3670 0 : arg1i = bat_iterator(arg1);
3671 0 : arg2i = bat_iterator(arg2);
3672 0 : arg3i = bat_iterator(arg3);
3673 0 : bi = bat_iterator(arg4);
3674 0 : arg4i = bi.base;
3675 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense
3676 0 : && ci4.tpe == cand_dense) {
3677 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3678 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3679 0 : p2 = (canditer_next_dense(&ci2) - off2),
3680 0 : p3 = (canditer_next_dense(&ci3) - off3),
3681 0 : p4 = (canditer_next_dense(&ci4) - off4);
3682 0 : const char *x = BUNtvar(arg1i, p1);
3683 0 : const char *y = BUNtvar(arg2i, p2);
3684 0 : const char *z = BUNtvar(arg3i, p3);
3685 0 : w = arg4i[p4];
3686 :
3687 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3688 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3689 0 : msg = createException(MAL, "batstr.substritute",
3690 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3691 0 : goto bailout1;
3692 : }
3693 : nils = true;
3694 : } else {
3695 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3696 0 : goto bailout1;
3697 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3698 0 : msg = createException(MAL, "batstr.substritute",
3699 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3700 0 : goto bailout1;
3701 : }
3702 : }
3703 : }
3704 : } else {
3705 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3706 0 : oid p1 = (canditer_next(&ci1) - off1),
3707 0 : p2 = (canditer_next(&ci2) - off2),
3708 0 : p3 = (canditer_next(&ci3) - off3),
3709 0 : p4 = (canditer_next(&ci4) - off4);
3710 0 : const char *x = BUNtvar(arg1i, p1);
3711 0 : const char *y = BUNtvar(arg2i, p2);
3712 0 : const char *z = BUNtvar(arg3i, p3);
3713 0 : w = arg4i[p4];
3714 :
3715 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3716 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3717 0 : msg = createException(MAL, "batstr.substritute",
3718 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3719 0 : goto bailout1;
3720 : }
3721 : nils = true;
3722 : } else {
3723 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3724 0 : goto bailout1;
3725 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3726 0 : msg = createException(MAL, "batstr.substritute",
3727 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3728 0 : goto bailout1;
3729 : }
3730 : }
3731 : }
3732 : }
3733 0 : bailout1:
3734 0 : bat_iterator_end(&bi);
3735 0 : bat_iterator_end(&arg1i);
3736 0 : bat_iterator_end(&arg2i);
3737 0 : bat_iterator_end(&arg3i);
3738 0 : bailout:
3739 0 : GDKfree(buf);
3740 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3741 0 : unfix_inputs(8, arg1, arg1, arg2, arg2s, arg3, arg3s, arg4, arg4s);
3742 0 : return msg;
3743 : }
3744 :
3745 : static str
3746 3 : STRbatsplitpartcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3747 : {
3748 3 : BATiter bi;
3749 3 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3750 3 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3751 3 : int z = *getArgReference_int(stk, pci, 3);
3752 3 : const char *y = *getArgReference_str(stk, pci, 2);
3753 3 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3754 3 : bool nils = false;
3755 3 : struct canditer ci1 = { 0 };
3756 3 : oid off1;
3757 3 : bat *res = getArgReference_bat(stk, pci, 0),
3758 3 : bid = *getArgReference_bat(stk, pci, 1),
3759 3 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3760 :
3761 3 : (void) cntxt;
3762 3 : (void) mb;
3763 3 : if (!buf) {
3764 0 : msg = createException(MAL, "batstr.splitpart",
3765 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3766 0 : goto bailout;
3767 : }
3768 3 : if (!(b = BATdescriptor(bid))) {
3769 0 : msg = createException(MAL, "batstr.splitpart",
3770 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3771 0 : goto bailout;
3772 : }
3773 3 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3774 0 : msg = createException(MAL, "batstr.splitpart",
3775 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3776 0 : goto bailout;
3777 : }
3778 3 : canditer_init(&ci1, b, bs);
3779 3 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3780 0 : msg = createException(MAL, "batstr.splitpart",
3781 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3782 0 : goto bailout;
3783 : }
3784 :
3785 3 : off1 = b->hseqbase;
3786 3 : bi = bat_iterator(b);
3787 3 : if (ci1.tpe == cand_dense) {
3788 128 : for (BUN i = 0; i < ci1.ncand; i++) {
3789 125 : oid p1 = (canditer_next_dense(&ci1) - off1);
3790 125 : const char *x = BUNtvar(bi, p1);
3791 :
3792 375 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3793 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3794 0 : msg = createException(MAL, "batstr.splitpart",
3795 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3796 0 : goto bailout1;
3797 : }
3798 : nils = true;
3799 : } else {
3800 125 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3801 0 : goto bailout1;
3802 125 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3803 0 : msg = createException(MAL, "batstr.splitpart",
3804 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3805 0 : goto bailout1;
3806 : }
3807 : }
3808 : }
3809 : } else {
3810 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3811 0 : oid p1 = (canditer_next(&ci1) - off1);
3812 0 : const char *x = BUNtvar(bi, p1);
3813 :
3814 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3815 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3816 0 : msg = createException(MAL, "batstr.splitpart",
3817 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3818 0 : goto bailout1;
3819 : }
3820 : nils = true;
3821 : } else {
3822 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3823 0 : goto bailout1;
3824 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3825 0 : msg = createException(MAL, "batstr.splitpart",
3826 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3827 0 : goto bailout1;
3828 : }
3829 : }
3830 : }
3831 : }
3832 0 : bailout1:
3833 3 : bat_iterator_end(&bi);
3834 3 : bailout:
3835 3 : GDKfree(buf);
3836 3 : finalize_output(res, bn, msg, nils, ci1.ncand);
3837 3 : unfix_inputs(2, b, bs);
3838 3 : return msg;
3839 : }
3840 :
3841 : static str
3842 0 : STRbatsplitpart_needlecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3843 : InstrPtr pci)
3844 : {
3845 0 : BATiter bi, fi;
3846 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *f = NULL, *fs = NULL;
3847 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3848 0 : int *restrict field, z;
3849 0 : const char *y = *getArgReference_str(stk, pci, 2);
3850 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3851 0 : bool nils = false;
3852 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3853 0 : oid off1, off2;
3854 0 : bat *res = getArgReference_bat(stk, pci, 0),
3855 0 : bid = *getArgReference_bat(stk, pci, 1),
3856 0 : fid = *getArgReference_bat(stk, pci, 3),
3857 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
3858 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
3859 :
3860 0 : if (!buf) {
3861 0 : msg = createException(MAL, "batstr.splitpart",
3862 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3863 0 : goto bailout;
3864 : }
3865 0 : if (!(b = BATdescriptor(bid)) || !(f = BATdescriptor(fid))) {
3866 0 : msg = createException(MAL, "batstr.splitpart",
3867 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3868 0 : goto bailout;
3869 : }
3870 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
3871 0 : || (sid2 && !is_bat_nil(*sid2) && !(fs = BATdescriptor(*sid2)))) {
3872 0 : msg = createException(MAL, "batstr.splitpart",
3873 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3874 0 : goto bailout;
3875 : }
3876 0 : canditer_init(&ci1, b, bs);
3877 0 : canditer_init(&ci2, f, fs);
3878 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3879 0 : msg = createException(MAL, "batstr.splitpart",
3880 : ILLEGAL_ARGUMENT
3881 : " Requires bats of identical size");
3882 0 : goto bailout;
3883 : }
3884 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3885 0 : msg = createException(MAL, "batstr.splitpart",
3886 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3887 0 : goto bailout;
3888 : }
3889 :
3890 0 : (void) cntxt;
3891 0 : (void) mb;
3892 0 : off1 = b->hseqbase;
3893 0 : off2 = f->hseqbase;
3894 0 : bi = bat_iterator(b);
3895 0 : fi = bat_iterator(f);
3896 0 : field = fi.base;
3897 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3898 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3899 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3900 0 : p2 = (canditer_next_dense(&ci2) - off2);
3901 0 : const char *x = BUNtvar(bi, p1);
3902 0 : z = field[p2];
3903 :
3904 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3905 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3906 0 : msg = createException(MAL, "batstr.splitpart",
3907 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3908 0 : goto bailout1;
3909 : }
3910 : nils = true;
3911 : } else {
3912 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3913 0 : goto bailout1;
3914 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3915 0 : msg = createException(MAL, "batstr.splitpart",
3916 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3917 0 : goto bailout1;
3918 : }
3919 : }
3920 : }
3921 : } else {
3922 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3923 0 : oid p1 = (canditer_next(&ci1) - off1),
3924 0 : p2 = (canditer_next(&ci2) - off2);
3925 0 : const char *x = BUNtvar(bi, p1);
3926 0 : z = field[p2];
3927 :
3928 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3929 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3930 0 : msg = createException(MAL, "batstr.splitpart",
3931 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3932 0 : goto bailout1;
3933 : }
3934 : nils = true;
3935 : } else {
3936 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3937 0 : goto bailout1;
3938 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3939 0 : msg = createException(MAL, "batstr.splitpart",
3940 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3941 0 : goto bailout1;
3942 : }
3943 : }
3944 : }
3945 : }
3946 0 : bailout1:
3947 0 : bat_iterator_end(&fi);
3948 0 : bat_iterator_end(&bi);
3949 0 : bailout:
3950 0 : GDKfree(buf);
3951 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3952 0 : unfix_inputs(4, b, bs, f, fs);
3953 0 : return msg;
3954 : }
3955 :
3956 : static str
3957 0 : STRbatsplitpart_fieldcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3958 : InstrPtr pci)
3959 : {
3960 0 : BATiter bi, ni;
3961 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *n = NULL, *ns = NULL;
3962 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3963 0 : int z = *getArgReference_int(stk, pci, 3);
3964 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3965 0 : bool nils = false;
3966 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3967 0 : oid off1, off2;
3968 0 : bat *res = getArgReference_bat(stk, pci, 0),
3969 0 : bid = *getArgReference_bat(stk, pci, 1),
3970 0 : nid = *getArgReference_bat(stk, pci, 2),
3971 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
3972 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
3973 :
3974 0 : (void) cntxt;
3975 0 : (void) mb;
3976 0 : if (!buf) {
3977 0 : msg = createException(MAL, "batstr.splitpart",
3978 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3979 0 : goto bailout;
3980 : }
3981 0 : if (!(b = BATdescriptor(bid)) || !(n = BATdescriptor(nid))) {
3982 0 : msg = createException(MAL, "batstr.splitpart",
3983 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3984 0 : goto bailout;
3985 : }
3986 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
3987 0 : || (sid2 && !is_bat_nil(*sid2) && !(ns = BATdescriptor(*sid2)))) {
3988 0 : msg = createException(MAL, "batstr.splitpart",
3989 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3990 0 : goto bailout;
3991 : }
3992 0 : canditer_init(&ci1, b, bs);
3993 0 : canditer_init(&ci2, n, ns);
3994 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3995 0 : msg = createException(MAL, "batstr.splitpart",
3996 : ILLEGAL_ARGUMENT
3997 : " Requires bats of identical size");
3998 0 : goto bailout;
3999 : }
4000 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4001 0 : msg = createException(MAL, "batstr.splitpart",
4002 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4003 0 : goto bailout;
4004 : }
4005 :
4006 0 : off1 = b->hseqbase;
4007 0 : off2 = n->hseqbase;
4008 0 : bi = bat_iterator(b);
4009 0 : ni = bat_iterator(n);
4010 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
4011 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4012 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4013 0 : p2 = (canditer_next_dense(&ci2) - off2);
4014 0 : const char *x = BUNtvar(bi, p1);
4015 0 : const char *y = BUNtvar(ni, p2);
4016 :
4017 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4018 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4019 0 : msg = createException(MAL, "batstr.splitpart",
4020 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4021 0 : goto bailout1;
4022 : }
4023 : nils = true;
4024 : } else {
4025 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4026 0 : goto bailout1;
4027 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4028 0 : msg = createException(MAL, "batstr.splitpart",
4029 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4030 0 : goto bailout1;
4031 : }
4032 : }
4033 : }
4034 : } else {
4035 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4036 0 : oid p1 = (canditer_next(&ci1) - off1),
4037 0 : p2 = (canditer_next(&ci2) - off2);
4038 0 : const char *x = BUNtvar(bi, p1);
4039 0 : const char *y = BUNtvar(ni, p2);
4040 :
4041 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4042 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4043 0 : msg = createException(MAL, "batstr.splitpart",
4044 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4045 0 : goto bailout1;
4046 : }
4047 : nils = true;
4048 : } else {
4049 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4050 0 : goto bailout1;
4051 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4052 0 : msg = createException(MAL, "batstr.splitpart",
4053 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4054 0 : goto bailout1;
4055 : }
4056 : }
4057 : }
4058 : }
4059 0 : bailout1:
4060 0 : bat_iterator_end(&bi);
4061 0 : bat_iterator_end(&ni);
4062 0 : bailout:
4063 0 : GDKfree(buf);
4064 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4065 0 : unfix_inputs(4, b, bs, n, ns);
4066 0 : return msg;
4067 : }
4068 :
4069 : static str
4070 0 : STRbatsplitpart(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4071 : {
4072 0 : BATiter arg1i, arg2i;
4073 0 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL,
4074 0 : *arg2s = NULL, *arg3 = NULL, *arg3s = NULL;
4075 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4076 0 : int *restrict arg3i, z;
4077 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4078 0 : bool nils = false;
4079 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
4080 0 : oid off1, off2, off3;
4081 0 : bat *res = getArgReference_bat(stk, pci, 0),
4082 0 : l = *getArgReference_bat(stk, pci, 1),
4083 0 : r = *getArgReference_bat(stk, pci, 2),
4084 0 : t = *getArgReference_bat(stk, pci, 3),
4085 0 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
4086 0 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
4087 0 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
4088 0 : BATiter bi;
4089 :
4090 0 : (void) cntxt;
4091 0 : (void) mb;
4092 0 : if (!buf) {
4093 0 : msg = createException(MAL, "batstr.splitpart",
4094 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4095 0 : goto bailout;
4096 : }
4097 0 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(r))
4098 0 : || !(arg3 = BATdescriptor(t))) {
4099 0 : msg = createException(MAL, "batstr.splitpart",
4100 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4101 0 : goto bailout;
4102 : }
4103 0 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) ||
4104 0 : (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) ||
4105 0 : (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3))))
4106 : {
4107 0 : msg = createException(MAL, "batstr.splitpart",
4108 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4109 0 : goto bailout;
4110 : }
4111 0 : canditer_init(&ci1, arg1, arg1s);
4112 0 : canditer_init(&ci2, arg2, arg2s);
4113 0 : canditer_init(&ci3, arg3, arg3s);
4114 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4115 0 : || ci2.hseq != ci3.hseq) {
4116 0 : msg = createException(MAL, "batstr.splitpart",
4117 : ILLEGAL_ARGUMENT
4118 : " Requires bats of identical size");
4119 0 : goto bailout;
4120 : }
4121 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4122 0 : msg = createException(MAL, "batstr.splitpart",
4123 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4124 0 : goto bailout;
4125 : }
4126 :
4127 0 : off1 = arg1->hseqbase;
4128 0 : off2 = arg2->hseqbase;
4129 0 : off3 = arg3->hseqbase;
4130 0 : arg1i = bat_iterator(arg1);
4131 0 : arg2i = bat_iterator(arg2);
4132 0 : bi = bat_iterator(arg3);
4133 0 : arg3i = bi.base;
4134 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
4135 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4136 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4137 0 : p2 = (canditer_next_dense(&ci2) - off2),
4138 0 : p3 = (canditer_next_dense(&ci3) - off3);
4139 0 : const char *x = BUNtvar(arg1i, p1);
4140 0 : const char *y = BUNtvar(arg2i, p2);
4141 0 : z = arg3i[p3];
4142 :
4143 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4144 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4145 0 : msg = createException(MAL, "batstr.splitpart",
4146 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4147 0 : goto bailout1;
4148 : }
4149 : nils = true;
4150 : } else {
4151 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4152 0 : goto bailout1;
4153 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4154 0 : msg = createException(MAL, "batstr.splitpart",
4155 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4156 0 : goto bailout1;
4157 : }
4158 : }
4159 : }
4160 : } else {
4161 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4162 0 : oid p1 = (canditer_next(&ci1) - off1),
4163 0 : p2 = (canditer_next(&ci2) - off2),
4164 0 : p3 = (canditer_next(&ci3) - off3);
4165 0 : const char *x = BUNtvar(arg1i, p1);
4166 0 : const char *y = BUNtvar(arg2i, p2);
4167 0 : z = arg3i[p3];
4168 :
4169 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4170 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4171 0 : msg = createException(MAL, "batstr.splitpart",
4172 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4173 0 : goto bailout1;
4174 : }
4175 : nils = true;
4176 : } else {
4177 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4178 0 : goto bailout1;
4179 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4180 0 : msg = createException(MAL, "batstr.splitpart",
4181 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4182 0 : goto bailout1;
4183 : }
4184 : }
4185 : }
4186 : }
4187 0 : bailout1:
4188 0 : bat_iterator_end(&bi);
4189 0 : bat_iterator_end(&arg1i);
4190 0 : bat_iterator_end(&arg2i);
4191 0 : bailout:
4192 0 : GDKfree(buf);
4193 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4194 0 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
4195 0 : return msg;
4196 : }
4197 :
4198 : static str
4199 469 : STRbatReplacecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4200 : {
4201 469 : bit rep = TRUE;
4202 :
4203 469 : 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 121 : bool nils = false;
4584 121 : struct canditer ci1 = { 0 };
4585 121 : oid off1;
4586 121 : bat *res = getArgReference_bat(stk, pci, 0),
4587 121 : bid = *getArgReference_bat(stk, pci, 1),
4588 121 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4589 :
4590 121 : (void) cntxt;
4591 121 : (void) mb;
4592 121 : if (!buf) {
4593 0 : msg = createException(MAL, "batstr.substring",
4594 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4595 0 : goto bailout;
4596 : }
4597 121 : if (!(b = BATdescriptor(bid))) {
4598 0 : msg = createException(MAL, "batstr.substring",
4599 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4600 0 : goto bailout;
4601 : }
4602 123 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4603 0 : msg = createException(MAL, "batstr.substring",
4604 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4605 0 : goto bailout;
4606 : }
4607 123 : canditer_init(&ci1, b, bs);
4608 123 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4609 0 : msg = createException(MAL, "batstr.substring",
4610 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4611 0 : goto bailout;
4612 : }
4613 :
4614 123 : off1 = b->hseqbase;
4615 123 : bi = bat_iterator(b);
4616 123 : if (ci1.tpe == cand_dense) {
4617 3912094 : for (BUN i = 0; i < ci1.ncand; i++) {
4618 3911972 : oid p1 = (canditer_next_dense(&ci1) - off1);
4619 3911972 : const char *x = BUNtvar(bi, p1);
4620 :
4621 7724475 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4622 102850 : 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 3809122 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4630 0 : goto bailout1;
4631 3758164 : 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 122 : bat_iterator_end(&bi);
4663 122 : bailout:
4664 122 : GDKfree(buf);
4665 123 : finalize_output(res, bn, msg, nils, ci1.ncand);
4666 122 : unfix_inputs(2, b, bs);
4667 123 : return msg;
4668 : }
4669 :
4670 : static str
4671 1 : STRbatsubstring_1st_2nd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4672 : InstrPtr pci)
4673 : {
4674 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4675 1 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4676 1 : int y = *getArgReference_int(stk, pci, 2), z, *restrict input;
4677 1 : const char *x = *getArgReference_str(stk, pci, 1);
4678 1 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4679 1 : bool nils = false;
4680 1 : struct canditer ci1 = { 0 };
4681 1 : oid off1;
4682 1 : bat *res = getArgReference_bat(stk, pci, 0),
4683 1 : bid = *getArgReference_bat(stk, pci, 3),
4684 1 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4685 1 : BATiter bi;
4686 :
4687 1 : (void) cntxt;
4688 1 : (void) mb;
4689 1 : if (!buf) {
4690 0 : msg = createException(MAL, "batstr.substring",
4691 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4692 0 : goto bailout;
4693 : }
4694 1 : if (!(b = BATdescriptor(bid))) {
4695 0 : msg = createException(MAL, "batstr.substring",
4696 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4697 0 : goto bailout;
4698 : }
4699 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4700 0 : msg = createException(MAL, "batstr.substring",
4701 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4702 0 : goto bailout;
4703 : }
4704 1 : canditer_init(&ci1, b, bs);
4705 1 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4706 0 : msg = createException(MAL, "batstr.substring",
4707 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4708 0 : goto bailout;
4709 : }
4710 :
4711 1 : off1 = b->hseqbase;
4712 1 : bi = bat_iterator(b);
4713 1 : input = bi.base;
4714 1 : if (ci1.tpe == cand_dense) {
4715 2 : for (BUN i = 0; i < ci1.ncand; i++) {
4716 1 : oid p1 = (canditer_next_dense(&ci1) - off1);
4717 1 : z = input[p1];
4718 :
4719 2 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4720 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4721 0 : msg = createException(MAL, "batstr.substring",
4722 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4723 0 : goto bailout1;
4724 : }
4725 : nils = true;
4726 : } else {
4727 1 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4728 0 : goto bailout1;
4729 1 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4730 0 : msg = createException(MAL, "batstr.substring",
4731 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4732 0 : goto bailout1;
4733 : }
4734 : }
4735 : }
4736 : } else {
4737 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4738 0 : oid p1 = (canditer_next(&ci1) - off1);
4739 0 : z = input[p1];
4740 :
4741 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4742 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4743 0 : msg = createException(MAL, "batstr.substring",
4744 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4745 0 : goto bailout1;
4746 : }
4747 : nils = true;
4748 : } else {
4749 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4750 0 : goto bailout1;
4751 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4752 0 : msg = createException(MAL, "batstr.substring",
4753 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4754 0 : goto bailout1;
4755 : }
4756 : }
4757 : }
4758 : }
4759 0 : bailout1:
4760 1 : bat_iterator_end(&bi);
4761 1 : bailout:
4762 1 : GDKfree(buf);
4763 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
4764 1 : unfix_inputs(2, b, bs);
4765 1 : return msg;
4766 : }
4767 :
4768 : static str
4769 5 : STRbatsubstring_1st_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4770 : InstrPtr pci)
4771 : {
4772 5 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4773 5 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4774 5 : int y, z = *getArgReference_int(stk, pci, 3), *restrict input;
4775 5 : const char *x = *getArgReference_str(stk, pci, 1);
4776 5 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4777 5 : bool nils = false;
4778 5 : struct canditer ci1 = { 0 };
4779 5 : oid off1;
4780 5 : bat *res = getArgReference_bat(stk, pci, 0),
4781 5 : bid = *getArgReference_bat(stk, pci, 2),
4782 5 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4783 5 : BATiter bi;
4784 :
4785 5 : (void) cntxt;
4786 5 : (void) mb;
4787 5 : if (!buf) {
4788 0 : msg = createException(MAL, "batstr.substring",
4789 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4790 0 : goto bailout;
4791 : }
4792 5 : if (!(b = BATdescriptor(bid))) {
4793 0 : msg = createException(MAL, "batstr.substring",
4794 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4795 0 : goto bailout;
4796 : }
4797 5 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4798 0 : msg = createException(MAL, "batstr.substring",
4799 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4800 0 : goto bailout;
4801 : }
4802 5 : canditer_init(&ci1, b, bs);
4803 5 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4804 0 : msg = createException(MAL, "batstr.substring",
4805 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4806 0 : goto bailout;
4807 : }
4808 :
4809 5 : off1 = b->hseqbase;
4810 5 : bi = bat_iterator(b);
4811 5 : input = bi.base;
4812 5 : if (ci1.tpe == cand_dense) {
4813 9 : for (BUN i = 0; i < ci1.ncand; i++) {
4814 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
4815 4 : y = input[p1];
4816 :
4817 8 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4818 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4819 0 : msg = createException(MAL, "batstr.substring",
4820 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4821 0 : goto bailout1;
4822 : }
4823 : nils = true;
4824 : } else {
4825 4 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4826 0 : goto bailout1;
4827 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4828 0 : msg = createException(MAL, "batstr.substring",
4829 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4830 0 : goto bailout1;
4831 : }
4832 : }
4833 : }
4834 : } else {
4835 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4836 0 : oid p1 = (canditer_next(&ci1) - off1);
4837 0 : y = input[p1];
4838 :
4839 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4840 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4841 0 : msg = createException(MAL, "batstr.substring",
4842 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4843 0 : goto bailout1;
4844 : }
4845 : nils = true;
4846 : } else {
4847 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4848 0 : goto bailout1;
4849 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4850 0 : msg = createException(MAL, "batstr.substring",
4851 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4852 0 : goto bailout1;
4853 : }
4854 : }
4855 : }
4856 : }
4857 0 : bailout1:
4858 5 : bat_iterator_end(&bi);
4859 5 : bailout:
4860 5 : GDKfree(buf);
4861 5 : finalize_output(res, bn, msg, nils, ci1.ncand);
4862 5 : unfix_inputs(2, b, bs);
4863 5 : return msg;
4864 : }
4865 :
4866 : static str
4867 4 : STRbatsubstring_1st_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4868 : {
4869 4 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
4870 4 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4871 4 : int y, z, *vals1, *vals2;
4872 4 : const char *x = *getArgReference_str(stk, pci, 1);
4873 4 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4874 4 : bool nils = false;
4875 4 : struct canditer ci1 = { 0 }, ci2 = { 0 };
4876 4 : oid off1, off2;
4877 4 : bat *res = getArgReference_bat(stk, pci, 0),
4878 4 : bid = *getArgReference_bat(stk, pci, 2),
4879 4 : l = *getArgReference_bat(stk, pci, 3),
4880 4 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
4881 4 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4882 4 : BATiter bi;
4883 4 : BATiter lbi;
4884 :
4885 4 : (void) cntxt;
4886 4 : (void) mb;
4887 4 : if (!buf) {
4888 0 : msg = createException(MAL, "batstr.substring",
4889 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4890 0 : goto bailout;
4891 : }
4892 4 : if (!(b = BATdescriptor(bid)) || !(lb = BATdescriptor(l))) {
4893 0 : msg = createException(MAL, "batstr.substring",
4894 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4895 0 : goto bailout;
4896 : }
4897 4 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
4898 4 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
4899 0 : msg = createException(MAL, "batstr.substring",
4900 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4901 0 : goto bailout;
4902 : }
4903 4 : canditer_init(&ci1, b, bs);
4904 4 : canditer_init(&ci2, lb, lbs);
4905 4 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
4906 0 : msg = createException(MAL, "batstr.substring",
4907 : ILLEGAL_ARGUMENT
4908 : " Requires bats of identical size");
4909 0 : goto bailout;
4910 : }
4911 4 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4912 0 : msg = createException(MAL, "batstr.substring",
4913 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4914 0 : goto bailout;
4915 : }
4916 :
4917 4 : off1 = b->hseqbase;
4918 4 : off2 = lb->hseqbase;
4919 4 : bi = bat_iterator(b);
4920 3 : 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 11 : for (BUN i = 0; i < ci1.ncand; i++) {
4925 7 : oid p1 = (canditer_next_dense(&ci1) - off1),
4926 7 : p2 = (canditer_next_dense(&ci2) - off2);
4927 7 : y = vals1[p1];
4928 7 : z = vals2[p2];
4929 :
4930 14 : 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 7 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4939 0 : goto bailout1;
4940 6 : 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 3 : bat_iterator_end(&lbi);
4975 4 : bailout:
4976 4 : GDKfree(buf);
4977 4 : finalize_output(res, bn, msg, nils, ci1.ncand);
4978 3 : unfix_inputs(4, b, bs, lb, lbs);
4979 4 : return msg;
4980 : }
4981 :
4982 : static str
4983 31 : STRbatsubstring_2nd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4984 : {
4985 31 : BATiter bi;
4986 31 : BATiter lbi;
4987 31 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
4988 31 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4989 31 : int y = *getArgReference_int(stk, pci, 2), *len, z;
4990 31 : 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 31 : canditer_init(&ci2, lb, lbs);
5020 32 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5021 0 : msg = createException(MAL, "batstr.substring",
5022 : ILLEGAL_ARGUMENT
5023 : " Requires bats of identical size");
5024 0 : goto bailout;
5025 : }
5026 32 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5027 0 : msg = createException(MAL, "batstr.substring",
5028 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5029 0 : goto bailout;
5030 : }
5031 :
5032 32 : off1 = b->hseqbase;
5033 32 : off2 = lb->hseqbase;
5034 32 : bi = bat_iterator(b);
5035 31 : lbi = bat_iterator(lb);
5036 32 : len = lbi.base;
5037 32 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5038 33 : 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 29 : bat_iterator_end(&lbi);
5088 30 : bat_iterator_end(&bi);
5089 32 : bailout:
5090 32 : GDKfree(buf);
5091 31 : 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 3869 : for (BUN i = 0; i < ci1.ncand; i++) {
5275 3841 : oid p1 = (canditer_next_dense(&ci1) - off1),
5276 3841 : p2 = (canditer_next_dense(&ci2) - off2),
5277 3841 : p3 = (canditer_next_dense(&ci3) - off3);
5278 3841 : const char *x = BUNtvar(lefti, p1);
5279 3841 : y = svals[p2];
5280 3841 : z = lvals[p3];
5281 :
5282 7652 : 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 3793 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5291 0 : goto bailout1;
5292 3722 : 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 3809 : for (BUN i = 0; i < ci1.ncand; i++) {
5445 3760 : oid p1 = (canditer_next_dense(&ci1) - off1);
5446 3760 : const char *y = BUNtvar(bi, p1);
5447 :
5448 7520 : if (strNil(x) || strNil(y)) {
5449 0 : vals[i] = int_nil;
5450 0 : nils = true;
5451 : } else {
5452 3760 : vals[i] = str_locate2(x, y, 1);
5453 : }
5454 : }
5455 : } else {
5456 1 : for (BUN i = 0; i < ci1.ncand; i++) {
5457 1 : 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 49 : 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 345 : LIB_STARTUP_FUNC(init_batstr_mal)
5935 345 : { mal_module("batstr", NULL, batstr_init_funcs); }
|