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 924 : batstr_func_has_candidates(const char *func)
33 : {
34 7378 : for (size_t i = 0; batstr_funcs_with_no_cands[i]; i++)
35 6466 : if (strcmp(batstr_funcs_with_no_cands[i], func) == 0)
36 : return false;
37 : return true;
38 : }
39 :
40 : static inline void
41 4769 : finalize_output(bat *res, BAT *bn, const char *msg, bool nils, BUN q)
42 : {
43 4769 : if (bn && !msg) {
44 4769 : BATsetcount(bn, q);
45 4769 : bn->tnil = nils;
46 4769 : bn->tnonil = !nils;
47 4769 : bn->tkey = BATcount(bn) <= 1;
48 4769 : bn->tsorted = BATcount(bn) <= 1;
49 4769 : bn->trevsorted = BATcount(bn) <= 1;
50 4769 : bn->theap->dirty |= BATcount(bn) > 0;
51 4769 : *res = bn->batCacheid;
52 4769 : BBPkeepref(bn);
53 0 : } else if (bn)
54 0 : BBPreclaim(bn);
55 4764 : }
56 :
57 : static void
58 4915 : unfix_inputs(int nargs, ...)
59 : {
60 4915 : va_list valist;
61 :
62 4915 : va_start(valist, nargs);
63 15093 : for (int i = 0; i < nargs; i++) {
64 10163 : BAT *b = va_arg(valist, BAT *);
65 16370 : BBPreclaim(b);
66 : }
67 4930 : va_end(valist);
68 4930 : }
69 :
70 : static inline str
71 5602 : str_prefix(str *buf, size_t *buflen, const char *s, int l)
72 : {
73 5602 : return str_Sub_String(buf, buflen, s, 0, l);
74 : }
75 :
76 : static str
77 3865 : do_batstr_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
78 : const char *name, int (*func)(const char *))
79 : {
80 3865 : BATiter bi;
81 3865 : BAT *bn = NULL, *b = NULL, *bs = NULL;
82 3865 : int *restrict vals;
83 3865 : str msg = MAL_SUCCEED;
84 3865 : bool nils = false;
85 3865 : struct canditer ci1 = { 0 };
86 3865 : oid off1;
87 3865 : bat *res = getArgReference_bat(stk, pci, 0),
88 3865 : bid = *getArgReference_bat(stk, pci, 1),
89 3865 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
90 :
91 3865 : (void) cntxt;
92 3865 : (void) mb;
93 3865 : if (!(b = BATdescriptor(bid))) {
94 0 : msg = createException(MAL, name,
95 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
96 0 : goto bailout;
97 : }
98 3876 : 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 3876 : canditer_init(&ci1, b, bs);
104 3871 : 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 3876 : off1 = b->hseqbase;
110 3876 : bi = bat_iterator(b);
111 3878 : vals = Tloc(bn, 0);
112 3878 : if (ci1.tpe == cand_dense) {
113 1591052 : for (BUN i = 0; i < ci1.ncand; i++) {
114 1587223 : oid p1 = (canditer_next_dense(&ci1) - off1);
115 1587223 : const char *restrict x = BUNtvar(bi, p1);
116 :
117 1587256 : if (strNil(x)) {
118 3 : vals[i] = int_nil;
119 3 : nils = true;
120 : } else {
121 1587253 : vals[i] = func(x);
122 : }
123 : }
124 : } else {
125 1612968 : for (BUN i = 0; i < ci1.ncand; i++) {
126 1612928 : oid p1 = (canditer_next(&ci1) - off1);
127 1614077 : const char *restrict x = BUNtvar(bi, p1);
128 :
129 1617442 : if (strNil(x)) {
130 0 : vals[i] = int_nil;
131 0 : nils = true;
132 : } else {
133 1617442 : vals[i] = func(x);
134 : }
135 : }
136 : }
137 3869 : bat_iterator_end(&bi);
138 3876 : bailout:
139 3876 : finalize_output(res, bn, msg, nils, ci1.ncand);
140 3872 : unfix_inputs(2, b, bs);
141 3877 : 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 3876 : str err;
150 3876 : if (b && b->tascii)
151 3869 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.bytes", str_strlen);
152 : else
153 7 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.length", UTF8_strlen);
154 3876 : BBPreclaim(b);
155 3874 : return err;
156 : }
157 :
158 : static str
159 1 : STRbatBytes(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
160 : {
161 1 : return do_batstr_int(cntxt, mb, stk, pci, "batstr.bytes", str_strlen);
162 : }
163 :
164 : static str
165 3 : STRbatAscii(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
166 : {
167 3 : BATiter bi;
168 3 : BAT *bn = NULL, *b = NULL, *bs = NULL;
169 3 : int *restrict vals, next;
170 3 : str msg = MAL_SUCCEED;
171 3 : bool nils = false;
172 3 : struct canditer ci1 = { 0 };
173 3 : oid off1;
174 3 : bat *res = getArgReference_bat(stk, pci, 0),
175 3 : bid = *getArgReference_bat(stk, pci, 1),
176 3 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
177 :
178 3 : (void) cntxt;
179 3 : (void) mb;
180 3 : if (!(b = BATdescriptor(bid))) {
181 0 : msg = createException(MAL, "batstr.unicodeAt",
182 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
183 0 : goto bailout;
184 : }
185 3 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
186 0 : msg = createException(MAL, "batstr.unicodeAt",
187 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
188 0 : goto bailout;
189 : }
190 3 : canditer_init(&ci1, b, bs);
191 3 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
192 0 : msg = createException(MAL, "batstr.unicodeAt",
193 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
194 0 : goto bailout;
195 : }
196 :
197 3 : off1 = b->hseqbase;
198 3 : bi = bat_iterator(b);
199 3 : vals = Tloc(bn, 0);
200 3 : if (ci1.tpe == cand_dense) {
201 10 : for (BUN i = 0; i < ci1.ncand; i++) {
202 8 : oid p1 = (canditer_next_dense(&ci1) - off1);
203 8 : const char *restrict x = BUNtvar(bi, p1);
204 :
205 8 : if ((msg = str_wchr_at(&next, x, 0)) != MAL_SUCCEED)
206 0 : goto bailout1;
207 8 : vals[i] = next;
208 8 : nils |= is_int_nil(next);
209 : }
210 : } else {
211 15 : for (BUN i = 0; i < ci1.ncand; i++) {
212 14 : oid p1 = (canditer_next(&ci1) - off1);
213 14 : const char *restrict x = BUNtvar(bi, p1);
214 :
215 14 : if ((msg = str_wchr_at(&next, x, 0)) != MAL_SUCCEED)
216 0 : goto bailout1;
217 14 : vals[i] = next;
218 14 : nils |= is_int_nil(next);
219 : }
220 : }
221 1 : bailout1:
222 3 : bat_iterator_end(&bi);
223 3 : bailout:
224 3 : finalize_output(res, bn, msg, nils, ci1.ncand);
225 3 : unfix_inputs(2, b, bs);
226 3 : return msg;
227 : }
228 :
229 : static str
230 1 : STRbatFromWChr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
231 : {
232 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
233 1 : size_t buflen = MAX(strlen(str_nil) + 1, 8);
234 1 : int *restrict vals, x;
235 1 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
236 1 : bool nils = false;
237 1 : struct canditer ci1 = { 0 };
238 1 : oid off1;
239 1 : bat *res = getArgReference_bat(stk, pci, 0),
240 1 : bid = *getArgReference_bat(stk, pci, 1),
241 1 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
242 1 : BATiter bi;
243 :
244 1 : (void) cntxt;
245 1 : (void) mb;
246 1 : if (!buf) {
247 0 : msg = createException(MAL, "batstr.unicode",
248 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
249 0 : goto bailout;
250 : }
251 1 : if (!(b = BATdescriptor(bid))) {
252 0 : msg = createException(MAL, "batstr.unicode",
253 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
254 0 : goto bailout;
255 : }
256 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
257 0 : msg = createException(MAL, "batstr.unicode",
258 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
259 0 : goto bailout;
260 : }
261 1 : canditer_init(&ci1, b, bs);
262 1 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
263 0 : msg = createException(MAL, "batstr.unicode",
264 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
265 0 : goto bailout;
266 : }
267 :
268 1 : bi = bat_iterator(b);
269 1 : off1 = b->hseqbase;
270 1 : vals = bi.base;
271 1 : if (ci1.tpe == cand_dense) {
272 5 : for (BUN i = 0; i < ci1.ncand; i++) {
273 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
274 4 : x = vals[p1];
275 :
276 4 : if (is_int_nil(x)) {
277 2 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
278 0 : msg = createException(MAL, "batstr.unicode",
279 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
280 0 : goto bailout1;
281 : }
282 : nils = true;
283 : } else {
284 2 : if ((msg = str_from_wchr(&buf, &buflen, vals[p1])) != MAL_SUCCEED) {
285 0 : goto bailout1;
286 : }
287 2 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
288 0 : msg = createException(MAL, "batstr.unicode",
289 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
290 0 : goto bailout1;
291 : }
292 : }
293 : }
294 : } else {
295 0 : for (BUN i = 0; i < ci1.ncand; i++) {
296 0 : oid p1 = (canditer_next(&ci1) - off1);
297 0 : x = vals[p1];
298 :
299 0 : if (is_int_nil(x)) {
300 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
301 0 : msg = createException(MAL, "batstr.unicode",
302 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
303 0 : goto bailout1;
304 : }
305 : nils = true;
306 : } else {
307 0 : if ((msg = str_from_wchr(&buf, &buflen, vals[p1])) != MAL_SUCCEED) {
308 0 : goto bailout1;
309 : }
310 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
311 0 : msg = createException(MAL, "batstr.unicode",
312 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
313 0 : goto bailout1;
314 : }
315 : }
316 : }
317 : }
318 0 : bailout1:
319 1 : bat_iterator_end(&bi);
320 1 : bailout:
321 1 : GDKfree(buf);
322 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
323 1 : unfix_inputs(2, b, bs);
324 1 : return msg;
325 : }
326 :
327 : static str
328 0 : STRbatSpace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
329 : {
330 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
331 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
332 0 : int *restrict vals, x;
333 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
334 0 : bool nils = false;
335 0 : const char space[] = " ", *s = space;
336 0 : struct canditer ci1 = { 0 };
337 0 : oid off1;
338 0 : bat *res = getArgReference_bat(stk, pci, 0),
339 0 : bid = *getArgReference_bat(stk, pci, 1),
340 0 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
341 0 : BATiter bi;
342 :
343 0 : (void) cntxt;
344 0 : (void) mb;
345 0 : if (!buf) {
346 0 : msg = createException(MAL, "batstr.space",
347 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
348 0 : goto bailout;
349 : }
350 0 : if (!(b = BATdescriptor(bid))) {
351 0 : msg = createException(MAL, "batstr.space",
352 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
353 0 : goto bailout;
354 : }
355 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
356 0 : msg = createException(MAL, "batstr.search",
357 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
358 0 : goto bailout;
359 : }
360 0 : canditer_init(&ci1, b, bs);
361 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
362 0 : msg = createException(MAL, "batstr.space",
363 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
364 0 : goto bailout;
365 : }
366 :
367 0 : off1 = b->hseqbase;
368 0 : bi = bat_iterator(b);
369 0 : vals = bi.base;
370 0 : if (ci1.tpe == cand_dense) {
371 0 : for (BUN i = 0; i < ci1.ncand; i++) {
372 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
373 0 : x = vals[p1];
374 :
375 0 : if (is_int_nil(x) || x < 0) {
376 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
377 0 : msg = createException(MAL, "batstr.space",
378 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
379 0 : goto bailout1;
380 : }
381 : nils = true;
382 : } else {
383 0 : if ((msg = str_repeat(&buf, &buflen, s, x)) != MAL_SUCCEED)
384 0 : goto bailout1;
385 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
386 0 : msg = createException(MAL, "batstr.space",
387 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
388 0 : goto bailout1;
389 : }
390 : }
391 : }
392 : } else {
393 0 : for (BUN i = 0; i < ci1.ncand; i++) {
394 0 : oid p1 = (canditer_next(&ci1) - off1);
395 0 : x = vals[p1];
396 :
397 0 : if (is_int_nil(x) || x < 0) {
398 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
399 0 : msg = createException(MAL, "batstr.space",
400 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
401 0 : goto bailout1;
402 : }
403 : nils = true;
404 : } else {
405 0 : if ((msg = str_repeat(&buf, &buflen, s, x)) != MAL_SUCCEED)
406 0 : goto bailout1;
407 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
408 0 : msg = createException(MAL, "batstr.space",
409 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
410 0 : goto bailout1;
411 : }
412 : }
413 : }
414 : }
415 0 : bailout1:
416 0 : bat_iterator_end(&bi);
417 0 : bailout:
418 0 : GDKfree(buf);
419 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
420 0 : unfix_inputs(2, b, bs);
421 0 : return msg;
422 : }
423 :
424 : static str
425 50 : do_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
426 : const char *name, str (*func)(str *, size_t *, const char *))
427 : {
428 50 : BATiter bi;
429 50 : BAT *bn = NULL, *b = NULL, *bs = NULL;
430 50 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
431 50 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
432 50 : bool nils = false;
433 50 : struct canditer ci1 = { 0 };
434 50 : oid off1;
435 50 : bat *res = getArgReference_bat(stk, pci, 0),
436 50 : bid = *getArgReference_bat(stk, pci, 1),
437 50 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
438 :
439 50 : (void) cntxt;
440 50 : (void) mb;
441 50 : if (!buf) {
442 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
443 0 : goto bailout;
444 : }
445 50 : if (!(b = BATdescriptor(bid))) {
446 0 : msg = createException(MAL, name,
447 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
448 0 : goto bailout;
449 : }
450 50 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
451 0 : msg = createException(MAL, name,
452 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
453 0 : goto bailout;
454 : }
455 50 : canditer_init(&ci1, b, bs);
456 50 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
457 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
458 0 : goto bailout;
459 : }
460 :
461 50 : off1 = b->hseqbase;
462 50 : bi = bat_iterator(b);
463 50 : if (ci1.tpe == cand_dense) {
464 424 : for (BUN i = 0; i < ci1.ncand; i++) {
465 374 : oid p1 = (canditer_next_dense(&ci1) - off1);
466 374 : const char *restrict x = BUNtvar(bi, p1);
467 :
468 374 : 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 369 : if ((msg = (*func) (&buf, &buflen, x)) != MAL_SUCCEED)
477 0 : goto bailout1;
478 369 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
479 0 : msg = createException(MAL, name,
480 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
481 0 : goto bailout1;
482 : }
483 : }
484 : }
485 : } else {
486 0 : for (BUN i = 0; i < ci1.ncand; i++) {
487 0 : oid p1 = (canditer_next(&ci1) - off1);
488 0 : const char *restrict x = BUNtvar(bi, p1);
489 :
490 0 : if (strNil(x)) {
491 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
492 0 : msg = createException(MAL, name,
493 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
494 0 : goto bailout1;
495 : }
496 : nils = true;
497 : } else {
498 0 : if ((msg = (*func) (&buf, &buflen, x)) != MAL_SUCCEED)
499 0 : goto bailout1;
500 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
501 0 : msg = createException(MAL, name,
502 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
503 0 : goto bailout1;
504 : }
505 : }
506 : }
507 : }
508 0 : bailout1:
509 50 : bat_iterator_end(&bi);
510 50 : bailout:
511 50 : GDKfree(buf);
512 50 : finalize_output(res, bn, msg, nils, ci1.ncand);
513 50 : unfix_inputs(2, b, bs);
514 50 : return msg;
515 : }
516 :
517 : /* Input: a BAT of strings 'b' and a constant string 'y'
518 : * Output type: str (a BAT of strings)
519 : */
520 : static str
521 10 : 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 10 : BATiter bi;
526 10 : BAT *bn = NULL, *b = NULL, *bs = NULL;
527 10 : const char *y = *getArgReference_str(stk, pci, 2);
528 10 : 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 10 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
554 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
555 0 : goto bailout;
556 : }
557 :
558 11 : off1 = b->hseqbase;
559 11 : bi = bat_iterator(b);
560 11 : if (ci1.tpe == cand_dense) {
561 29 : for (BUN i = 0; i < ci1.ncand; i++) {
562 18 : oid p1 = (canditer_next_dense(&ci1) - off1);
563 18 : const char *x = BUNtvar(bi, p1);
564 :
565 36 : if (strNil(x) || strNil(y)) {
566 9 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
567 0 : msg = createException(MAL, name,
568 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
569 0 : goto bailout1;
570 : }
571 : nils = true;
572 : } else {
573 9 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
574 0 : goto bailout1;
575 9 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
576 0 : msg = createException(MAL, name,
577 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
578 0 : goto bailout1;
579 : }
580 : }
581 : }
582 : } else {
583 0 : for (BUN i = 0; i < ci1.ncand; i++) {
584 0 : oid p1 = (canditer_next(&ci1) - off1);
585 0 : const char *x = BUNtvar(bi, p1);
586 :
587 0 : if (strNil(x) || strNil(y)) {
588 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
589 0 : msg = createException(MAL, name,
590 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
591 0 : goto bailout1;
592 : }
593 : nils = true;
594 : } else {
595 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
596 0 : goto bailout1;
597 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
598 0 : msg = createException(MAL, name,
599 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
600 0 : goto bailout1;
601 : }
602 : }
603 : }
604 : }
605 0 : bailout1:
606 11 : bat_iterator_end(&bi);
607 11 : bailout:
608 11 : GDKfree(buf);
609 11 : finalize_output(res, bn, msg, nils, ci1.ncand);
610 11 : unfix_inputs(2, b, bs);
611 11 : return msg;
612 : }
613 :
614 : /* Input: a const string 'x' and a BAT of strings 'y'
615 : * Output type: str (a BAT of strings)
616 : */
617 : static str
618 0 : do_batstr_str_conststr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
619 : const char *name, size_t buflen,
620 : str (*func)(str *, size_t *, const char *, const char *))
621 : {
622 0 : BATiter bi;
623 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
624 0 : const char *x = *getArgReference_str(stk, pci, 1);
625 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
626 0 : bool nils = false;
627 0 : struct canditer ci1 = { 0 };
628 0 : oid off1;
629 0 : bat *res = getArgReference_bat(stk, pci, 0),
630 0 : bid = *getArgReference_bat(stk, pci, 2),
631 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
632 :
633 0 : (void) cntxt;
634 0 : (void) mb;
635 0 : if (!buf) {
636 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
637 0 : goto bailout;
638 : }
639 0 : if (!(b = BATdescriptor(bid))) {
640 0 : msg = createException(MAL, name,
641 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
642 0 : goto bailout;
643 : }
644 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
645 0 : msg = createException(MAL, name,
646 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
647 0 : goto bailout;
648 : }
649 0 : canditer_init(&ci1, b, bs);
650 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
651 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
652 0 : goto bailout;
653 : }
654 :
655 0 : off1 = b->hseqbase;
656 0 : bi = bat_iterator(b);
657 0 : if (ci1.tpe == cand_dense) {
658 0 : for (BUN i = 0; i < ci1.ncand; i++) {
659 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
660 0 : const char *y = BUNtvar(bi, p1);
661 :
662 0 : if (strNil(x) || strNil(y)) {
663 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
664 0 : msg = createException(MAL, name,
665 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
666 0 : goto bailout1;
667 : }
668 : nils = true;
669 : } else {
670 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
671 0 : goto bailout1;
672 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
673 0 : msg = createException(MAL, name,
674 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
675 0 : goto bailout1;
676 : }
677 : }
678 : }
679 : } else {
680 0 : for (BUN i = 0; i < ci1.ncand; i++) {
681 0 : oid p1 = (canditer_next(&ci1) - off1);
682 0 : const char *y = BUNtvar(bi, p1);
683 :
684 0 : if (strNil(x) || strNil(y)) {
685 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
686 0 : msg = createException(MAL, name,
687 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
688 0 : goto bailout1;
689 : }
690 : nils = true;
691 : } else {
692 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
693 0 : goto bailout1;
694 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
695 0 : msg = createException(MAL, name,
696 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
697 0 : goto bailout1;
698 : }
699 : }
700 : }
701 : }
702 0 : bailout1:
703 0 : bat_iterator_end(&bi);
704 0 : bailout:
705 0 : GDKfree(buf);
706 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
707 0 : unfix_inputs(2, b, bs);
708 0 : return msg;
709 : }
710 :
711 : /* Input: two BATs of strings 'l' and 'l2'
712 : * Output type: str (a BAT of strings)
713 : */
714 : static str
715 3 : do_batstr_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
716 : const char *name, size_t buflen,
717 : str (*func)(str *, size_t *, const char *, const char *))
718 : {
719 3 : BATiter lefti, righti;
720 3 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
721 3 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
722 3 : bool nils = false;
723 3 : struct canditer ci1 = { 0 }, ci2 = { 0 };
724 3 : oid off1, off2;
725 3 : bat *res = getArgReference_bat(stk, pci, 0),
726 3 : l = *getArgReference_bat(stk, pci, 1),
727 3 : l2 = *getArgReference_bat(stk, pci, 2),
728 3 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
729 3 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
730 :
731 3 : (void) cntxt;
732 3 : (void) mb;
733 3 : if (!buf) {
734 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
735 0 : goto bailout;
736 : }
737 3 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(l2))) {
738 0 : msg = createException(MAL, name,
739 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
740 0 : goto bailout;
741 : }
742 3 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
743 3 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
744 0 : msg = createException(MAL, name,
745 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
746 0 : goto bailout;
747 : }
748 3 : canditer_init(&ci1, left, lefts);
749 3 : canditer_init(&ci2, right, rights);
750 3 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
751 0 : msg = createException(MAL, name,
752 : ILLEGAL_ARGUMENT
753 : " Requires bats of identical size");
754 0 : goto bailout;
755 : }
756 3 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
757 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
758 0 : goto bailout;
759 : }
760 :
761 3 : off1 = left->hseqbase;
762 3 : off2 = right->hseqbase;
763 3 : lefti = bat_iterator(left);
764 3 : righti = bat_iterator(right);
765 3 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
766 12 : for (BUN i = 0; i < ci1.ncand; i++) {
767 9 : oid p1 = (canditer_next_dense(&ci1) - off1),
768 9 : p2 = (canditer_next_dense(&ci2) - off2);
769 9 : const char *x = BUNtvar(lefti, p1);
770 9 : const char *y = BUNtvar(righti, p2);
771 :
772 18 : if (strNil(x) || strNil(y)) {
773 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
774 0 : msg = createException(MAL, name,
775 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
776 0 : goto bailout1;
777 : }
778 : nils = true;
779 : } else {
780 9 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
781 0 : goto bailout1;
782 9 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
783 0 : msg = createException(MAL, name,
784 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
785 0 : goto bailout1;
786 : }
787 : }
788 : }
789 : } else {
790 0 : for (BUN i = 0; i < ci1.ncand; i++) {
791 0 : oid p1 = (canditer_next(&ci1) - off1),
792 0 : p2 = (canditer_next(&ci2) - off2);
793 0 : const char *x = BUNtvar(lefti, p1);
794 0 : const char *y = BUNtvar(righti, p2);
795 :
796 0 : if (strNil(x) || strNil(y)) {
797 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
798 0 : msg = createException(MAL, name,
799 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
800 0 : goto bailout1;
801 : }
802 : nils = true;
803 : } else {
804 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
805 0 : goto bailout1;
806 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
807 0 : msg = createException(MAL, name,
808 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
809 0 : goto bailout1;
810 : }
811 : }
812 : }
813 : }
814 0 : bailout1:
815 3 : bat_iterator_end(&lefti);
816 3 : bat_iterator_end(&righti);
817 3 : bailout:
818 3 : GDKfree(buf);
819 3 : finalize_output(res, bn, msg, nils, ci1.ncand);
820 3 : unfix_inputs(4, left, lefts, right, rights);
821 3 : return msg;
822 : }
823 :
824 : /* Input: a BAT of strings 'l' and a constant int 'y'
825 : * Output type: str (a BAT of strings)
826 : */
827 : static str
828 2 : do_batstr_constint_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
829 : const char *name,
830 : str (*func)(str *, size_t *, const char *, int))
831 : {
832 2 : BATiter bi;
833 2 : BAT *bn = NULL, *b = NULL, *bs = NULL;
834 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
835 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
836 2 : int y = *getArgReference_int(stk, pci, 2);
837 2 : bool nils = false;
838 2 : struct canditer ci1 = { 0 };
839 2 : oid off1;
840 2 : bat *res = getArgReference_bat(stk, pci, 0),
841 2 : bid = *getArgReference_bat(stk, pci, 1),
842 2 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
843 :
844 2 : (void) cntxt;
845 2 : (void) mb;
846 2 : if (!buf) {
847 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
848 0 : goto bailout;
849 : }
850 2 : if (!(b = BATdescriptor(bid))) {
851 0 : msg = createException(MAL, name,
852 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
853 0 : goto bailout;
854 : }
855 2 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
856 0 : msg = createException(MAL, name,
857 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
858 0 : goto bailout;
859 : }
860 2 : canditer_init(&ci1, b, bs);
861 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
862 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
863 0 : goto bailout;
864 : }
865 :
866 2 : off1 = b->hseqbase;
867 2 : bi = bat_iterator(b);
868 2 : if (ci1.tpe == cand_dense) {
869 6 : for (BUN i = 0; i < ci1.ncand; i++) {
870 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
871 4 : const char *x = BUNtvar(bi, p1);
872 :
873 8 : if (strNil(x) || is_int_nil(y)) {
874 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
875 0 : msg = createException(MAL, name,
876 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
877 0 : goto bailout1;
878 : }
879 : nils = true;
880 : } else {
881 4 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
882 0 : goto bailout1;
883 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
884 0 : msg = createException(MAL, name,
885 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
886 0 : goto bailout1;
887 : }
888 : }
889 : }
890 : } else {
891 0 : for (BUN i = 0; i < ci1.ncand; i++) {
892 0 : oid p1 = (canditer_next(&ci1) - off1);
893 0 : const char *x = BUNtvar(bi, p1);
894 :
895 0 : if (strNil(x) || is_int_nil(y)) {
896 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
897 0 : msg = createException(MAL, name,
898 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
899 0 : goto bailout1;
900 : }
901 : nils = true;
902 : } else {
903 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
904 0 : goto bailout1;
905 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
906 0 : msg = createException(MAL, name,
907 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
908 0 : goto bailout1;
909 : }
910 : }
911 : }
912 : }
913 0 : bailout1:
914 2 : bat_iterator_end(&bi);
915 2 : bailout:
916 2 : GDKfree(buf);
917 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
918 2 : unfix_inputs(2, b, bs);
919 2 : return msg;
920 : }
921 :
922 : /* Input: a constant string 'x' and a BAT of integers 'y'
923 : * Output type: str (a BAT of strings)
924 : */
925 : static str
926 0 : do_batstr_int_conststr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
927 : const char *name,
928 : str (*func)(str *, size_t *, const char *, int))
929 : {
930 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
931 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
932 0 : const char *x = *getArgReference_str(stk, pci, 1);
933 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
934 0 : int y, *restrict inputs;
935 0 : bool nils = false;
936 0 : struct canditer ci1 = { 0 };
937 0 : oid off1;
938 0 : bat *res = getArgReference_bat(stk, pci, 0),
939 0 : bid = *getArgReference_bat(stk, pci, 2),
940 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
941 0 : BATiter bi;
942 :
943 0 : (void) cntxt;
944 0 : (void) mb;
945 0 : if (!buf) {
946 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
947 0 : goto bailout;
948 : }
949 0 : if (!(b = BATdescriptor(bid))) {
950 0 : msg = createException(MAL, name,
951 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
952 0 : goto bailout;
953 : }
954 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
955 0 : msg = createException(MAL, name,
956 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
957 0 : goto bailout;
958 : }
959 0 : canditer_init(&ci1, b, bs);
960 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
961 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
962 0 : goto bailout;
963 : }
964 :
965 0 : off1 = b->hseqbase;
966 0 : bi = bat_iterator(b);
967 0 : inputs = bi.base;
968 0 : if (ci1.tpe == cand_dense) {
969 0 : for (BUN i = 0; i < ci1.ncand; i++) {
970 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
971 0 : y = inputs[p1];
972 :
973 0 : if (strNil(x) || is_int_nil(y)) {
974 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
975 0 : msg = createException(MAL, name,
976 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
977 0 : goto bailout1;
978 : }
979 : nils = true;
980 : } else {
981 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
982 0 : goto bailout1;
983 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
984 0 : msg = createException(MAL, name,
985 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
986 0 : goto bailout1;
987 : }
988 : }
989 : }
990 : } else {
991 0 : for (BUN i = 0; i < ci1.ncand; i++) {
992 0 : oid p1 = (canditer_next(&ci1) - off1);
993 0 : y = inputs[p1];
994 :
995 0 : if (strNil(x) || is_int_nil(y)) {
996 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
997 0 : msg = createException(MAL, name,
998 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
999 0 : goto bailout1;
1000 : }
1001 : nils = true;
1002 : } else {
1003 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1004 0 : goto bailout1;
1005 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1006 0 : msg = createException(MAL, name,
1007 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1008 0 : goto bailout1;
1009 : }
1010 : }
1011 : }
1012 : }
1013 0 : bailout1:
1014 0 : bat_iterator_end(&bi);
1015 0 : bailout:
1016 0 : GDKfree(buf);
1017 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
1018 0 : unfix_inputs(2, b, bs);
1019 0 : return msg;
1020 : }
1021 :
1022 : /* Input: a BAT of strings 'l' and a BAT of integers 'n'
1023 : * Output type: str (a BAT of strings)
1024 : */
1025 : static str
1026 2 : do_batstr_batint_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1027 : const char *name,
1028 : str (*func)(str *, size_t *, const char *, int))
1029 : {
1030 2 : BATiter lefti;
1031 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1032 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1033 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1034 2 : bool nils = false;
1035 2 : int *restrict righti, y;
1036 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1037 2 : oid off1, off2;
1038 2 : bat *res = getArgReference_bat(stk, pci, 0),
1039 2 : l = *getArgReference_bat(stk, pci, 1),
1040 2 : n = *getArgReference_bat(stk, pci, 2),
1041 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
1042 2 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
1043 2 : BATiter bi;
1044 :
1045 2 : (void) cntxt;
1046 2 : (void) mb;
1047 2 : if (!buf) {
1048 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1049 0 : goto bailout;
1050 : }
1051 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(n))) {
1052 0 : msg = createException(MAL, name,
1053 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1054 0 : goto bailout;
1055 : }
1056 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1057 2 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1058 0 : msg = createException(MAL, name,
1059 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1060 0 : goto bailout;
1061 : }
1062 2 : canditer_init(&ci1, left, ls);
1063 2 : canditer_init(&ci2, right, rs);
1064 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1065 0 : msg = createException(MAL, name,
1066 : ILLEGAL_ARGUMENT
1067 : " Requires bats of identical size");
1068 0 : goto bailout;
1069 : }
1070 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1071 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1072 0 : goto bailout;
1073 : }
1074 :
1075 2 : off1 = left->hseqbase;
1076 2 : off2 = right->hseqbase;
1077 2 : lefti = bat_iterator(left);
1078 2 : bi = bat_iterator(right);
1079 2 : righti = bi.base;
1080 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1081 6 : for (BUN i = 0; i < ci1.ncand; i++) {
1082 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
1083 4 : p2 = (canditer_next_dense(&ci2) - off2);
1084 4 : const char *x = BUNtvar(lefti, p1);
1085 4 : y = righti[p2];
1086 :
1087 8 : if (strNil(x) || is_int_nil(y)) {
1088 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1089 0 : msg = createException(MAL, name,
1090 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1091 0 : goto bailout1;
1092 : }
1093 : nils = true;
1094 : } else {
1095 4 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1096 0 : goto bailout1;
1097 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1098 0 : msg = createException(MAL, name,
1099 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1100 0 : goto bailout1;
1101 : }
1102 : }
1103 : }
1104 : } else {
1105 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1106 0 : oid p1 = (canditer_next(&ci1) - off1),
1107 0 : p2 = (canditer_next(&ci2) - off2);
1108 0 : const char *x = BUNtvar(lefti, p1);
1109 0 : y = righti[p2];
1110 :
1111 0 : if (strNil(x) || is_int_nil(y)) {
1112 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1113 0 : msg = createException(MAL, name,
1114 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1115 0 : goto bailout1;
1116 : }
1117 : nils = true;
1118 : } else {
1119 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1120 0 : goto bailout1;
1121 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1122 0 : msg = createException(MAL, name,
1123 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1124 0 : goto bailout1;
1125 : }
1126 : }
1127 : }
1128 : }
1129 0 : bailout1:
1130 2 : bat_iterator_end(&bi);
1131 2 : bat_iterator_end(&lefti);
1132 2 : bailout:
1133 2 : GDKfree(buf);
1134 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1135 2 : unfix_inputs(4, left, ls, right, rs);
1136 2 : return msg;
1137 : }
1138 :
1139 : /* Input: a BAT of strings 'l', a constant int 'y' and a constant str 'z'
1140 : * Output type: str (a BAT of strings)
1141 : */
1142 : static str
1143 2 : do_batstr_constint_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1144 : InstrPtr pci, const char *name,
1145 : str (*func)(str *, size_t *, const char *, int, const char *))
1146 : {
1147 2 : BATiter bi;
1148 2 : BAT *bn = NULL, *b = NULL, *bs = NULL;
1149 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1150 2 : const char *z = *getArgReference_str(stk, pci, 3);
1151 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1152 2 : int y = *getArgReference_int(stk, pci, 2);
1153 2 : bool nils = false;
1154 2 : struct canditer ci1 = { 0 };
1155 2 : oid off1;
1156 2 : bat *res = getArgReference_bat(stk, pci, 0),
1157 2 : l = *getArgReference_bat(stk, pci, 1),
1158 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
1159 :
1160 2 : (void) cntxt;
1161 2 : (void) mb;
1162 2 : if (!buf) {
1163 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1164 0 : goto bailout;
1165 : }
1166 2 : if (!(b = BATdescriptor(l))) {
1167 0 : msg = createException(MAL, name,
1168 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1169 0 : goto bailout;
1170 : }
1171 2 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
1172 0 : msg = createException(MAL, name,
1173 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1174 0 : goto bailout;
1175 : }
1176 2 : canditer_init(&ci1, b, bs);
1177 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1178 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1179 0 : goto bailout;
1180 : }
1181 :
1182 2 : off1 = b->hseqbase;
1183 2 : bi = bat_iterator(b);
1184 2 : if (ci1.tpe == cand_dense) {
1185 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1186 8 : oid p1 = (canditer_next_dense(&ci1) - off1);
1187 8 : const char *x = BUNtvar(bi, p1);
1188 :
1189 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1190 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1191 0 : msg = createException(MAL, name,
1192 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1193 0 : goto bailout1;
1194 : }
1195 : nils = true;
1196 : } else {
1197 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1198 0 : goto bailout1;
1199 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1200 0 : msg = createException(MAL, name,
1201 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1202 0 : goto bailout1;
1203 : }
1204 : }
1205 : }
1206 : } else {
1207 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1208 0 : oid p1 = (canditer_next(&ci1) - off1);
1209 0 : const char *x = BUNtvar(bi, p1);
1210 :
1211 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1212 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1213 0 : msg = createException(MAL, name,
1214 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1215 0 : goto bailout1;
1216 : }
1217 : nils = true;
1218 : } else {
1219 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1220 0 : goto bailout1;
1221 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1222 0 : msg = createException(MAL, name,
1223 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1224 0 : goto bailout1;
1225 : }
1226 : }
1227 : }
1228 : }
1229 0 : bailout1:
1230 2 : bat_iterator_end(&bi);
1231 2 : bailout:
1232 2 : GDKfree(buf);
1233 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1234 2 : unfix_inputs(2, b, bs);
1235 2 : return msg;
1236 : }
1237 :
1238 : /* Input: a BAT of strings 'l', a BAT of integers 'n' and a constant str 'z'
1239 : * Output type: str (a BAT of strings)
1240 : */
1241 : static str
1242 2 : do_batstr_batint_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1243 : InstrPtr pci, const char *name,
1244 : str (*func)(str *, size_t *, const char *,
1245 : int, const char *))
1246 : {
1247 2 : BATiter lefti;
1248 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1249 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1250 2 : const char *z = *getArgReference_str(stk, pci, 3);
1251 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1252 2 : bool nils = false;
1253 2 : int *restrict righti, y;
1254 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1255 2 : oid off1, off2;
1256 2 : bat *res = getArgReference_bat(stk, pci, 0),
1257 2 : l = *getArgReference_bat(stk, pci, 1),
1258 2 : n = *getArgReference_bat(stk, pci, 2),
1259 2 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
1260 2 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
1261 2 : BATiter bi;
1262 :
1263 2 : (void) cntxt;
1264 2 : (void) mb;
1265 2 : if (!buf) {
1266 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1267 0 : goto bailout;
1268 : }
1269 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(n))) {
1270 0 : msg = createException(MAL, name,
1271 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1272 0 : goto bailout;
1273 : }
1274 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1275 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1276 0 : msg = createException(MAL, name,
1277 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1278 0 : goto bailout;
1279 : }
1280 2 : canditer_init(&ci1, left, ls);
1281 2 : canditer_init(&ci2, right, rs);
1282 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1283 0 : msg = createException(MAL, name,
1284 : ILLEGAL_ARGUMENT
1285 : " Requires bats of identical size");
1286 0 : goto bailout;
1287 : }
1288 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1289 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1290 0 : goto bailout;
1291 : }
1292 :
1293 2 : off1 = left->hseqbase;
1294 2 : off2 = right->hseqbase;
1295 2 : lefti = bat_iterator(left);
1296 2 : bi = bat_iterator(right);
1297 2 : righti = bi.base;
1298 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1299 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1300 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1301 8 : p2 = (canditer_next_dense(&ci2) - off2);
1302 8 : const char *x = BUNtvar(lefti, p1);
1303 8 : y = righti[p2];
1304 :
1305 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1306 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1307 0 : msg = createException(MAL, name,
1308 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1309 0 : goto bailout1;
1310 : }
1311 : nils = true;
1312 : } else {
1313 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1314 0 : goto bailout1;
1315 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1316 0 : msg = createException(MAL, name,
1317 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1318 0 : goto bailout1;
1319 : }
1320 : }
1321 : }
1322 : } else {
1323 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1324 0 : oid p1 = (canditer_next(&ci1) - off1),
1325 0 : p2 = (canditer_next(&ci2) - off2);
1326 0 : const char *x = BUNtvar(lefti, p1);
1327 0 : y = righti[p2];
1328 :
1329 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1330 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1331 0 : msg = createException(MAL, name,
1332 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1333 0 : goto bailout1;
1334 : }
1335 : nils = true;
1336 : } else {
1337 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1338 0 : goto bailout1;
1339 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1340 0 : msg = createException(MAL, name,
1341 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1342 0 : goto bailout1;
1343 : }
1344 : }
1345 : }
1346 : }
1347 0 : bailout1:
1348 2 : bat_iterator_end(&bi);
1349 2 : bat_iterator_end(&lefti);
1350 2 : bailout:
1351 2 : GDKfree(buf);
1352 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1353 2 : unfix_inputs(4, left, ls, right, rs);
1354 2 : return msg;
1355 : }
1356 :
1357 : /* Input: a BAT of strings 'l', a constant int 'y' and a BAT of strings 'l2'
1358 : * Output type: str (a BAT of strings)
1359 : */
1360 : static str
1361 2 : do_batstr_constint_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1362 : InstrPtr pci, const char *name,
1363 : str (*func)(str *, size_t *, const char *,
1364 : int, const char *))
1365 : {
1366 2 : BATiter lefti, righti;
1367 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1368 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1369 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1370 2 : bool nils = false;
1371 2 : int y = *getArgReference_int(stk, pci, 2);
1372 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1373 2 : oid off1, off2;
1374 2 : bat *res = getArgReference_bat(stk, pci, 0),
1375 2 : l = *getArgReference_bat(stk, pci, 1),
1376 2 : l2 = *getArgReference_bat(stk, pci, 3),
1377 2 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
1378 2 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
1379 :
1380 2 : (void) cntxt;
1381 2 : (void) mb;
1382 2 : if (!buf) {
1383 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1384 0 : goto bailout;
1385 : }
1386 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(l2))) {
1387 0 : msg = createException(MAL, name,
1388 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1389 0 : goto bailout;
1390 : }
1391 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1392 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1393 0 : msg = createException(MAL, name,
1394 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1395 0 : goto bailout;
1396 : }
1397 2 : canditer_init(&ci1, left, ls);
1398 2 : canditer_init(&ci2, right, rs);
1399 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1400 0 : msg = createException(MAL, name,
1401 : ILLEGAL_ARGUMENT
1402 : " Requires bats of identical size");
1403 0 : goto bailout;
1404 : }
1405 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1406 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1407 0 : goto bailout;
1408 : }
1409 :
1410 2 : off1 = left->hseqbase;
1411 2 : off2 = right->hseqbase;
1412 2 : lefti = bat_iterator(left);
1413 2 : righti = bat_iterator(right);
1414 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1415 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1416 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1417 8 : p2 = (canditer_next_dense(&ci2) - off2);
1418 8 : const char *x = BUNtvar(lefti, p1);
1419 8 : const char *z = BUNtvar(righti, p2);
1420 :
1421 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1422 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1423 0 : msg = createException(MAL, name,
1424 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1425 0 : goto bailout1;
1426 : }
1427 : nils = true;
1428 : } else {
1429 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1430 0 : goto bailout1;
1431 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1432 0 : msg = createException(MAL, name,
1433 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1434 0 : goto bailout1;
1435 : }
1436 : }
1437 : }
1438 : } else {
1439 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1440 0 : oid p1 = (canditer_next(&ci1) - off1),
1441 0 : p2 = (canditer_next(&ci2) - off2);
1442 0 : const char *x = BUNtvar(lefti, p1);
1443 0 : const char *z = BUNtvar(righti, p2);
1444 :
1445 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1446 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1447 0 : msg = createException(MAL, name,
1448 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1449 0 : goto bailout1;
1450 : }
1451 : nils = true;
1452 : } else {
1453 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1454 0 : goto bailout1;
1455 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1456 0 : msg = createException(MAL, name,
1457 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1458 0 : goto bailout1;
1459 : }
1460 : }
1461 : }
1462 : }
1463 0 : bailout1:
1464 2 : bat_iterator_end(&lefti);
1465 2 : bat_iterator_end(&righti);
1466 2 : bailout:
1467 2 : GDKfree(buf);
1468 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1469 2 : unfix_inputs(4, left, ls, right, rs);
1470 2 : return msg;
1471 : }
1472 :
1473 : /* Input: a BAT of strings 'l', a BAT of int 'n' and a BAT of strings 'l2'
1474 : * Output type: str (a BAT of strings)
1475 : */
1476 : static str
1477 2 : do_batstr_batint_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1478 : InstrPtr pci, const char *name,
1479 : str (*func)(str *, size_t *, const char *,
1480 : int, const char *))
1481 : {
1482 2 : BATiter arg1i, arg3i, bi;
1483 2 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL, *arg2s = NULL,
1484 2 : *arg3 = NULL, *arg3s = NULL;
1485 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1486 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1487 2 : bool nils = false;
1488 2 : int *restrict arg2i, y;
1489 2 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
1490 2 : oid off1, off2, off3;
1491 2 : bat *res = getArgReference_bat(stk, pci, 0),
1492 2 : l = *getArgReference_bat(stk, pci, 1),
1493 2 : n = *getArgReference_bat(stk, pci, 2),
1494 2 : l2 = *getArgReference_bat(stk, pci, 3),
1495 2 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
1496 2 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
1497 2 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
1498 :
1499 2 : (void) cntxt;
1500 2 : (void) mb;
1501 2 : if (!buf) {
1502 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1503 0 : goto bailout;
1504 : }
1505 2 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(n))
1506 2 : || !(arg3 = BATdescriptor(l2))) {
1507 0 : msg = createException(MAL, name,
1508 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1509 0 : goto bailout;
1510 : }
1511 2 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1)))
1512 2 : || (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2)))
1513 2 : || (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3)))) {
1514 0 : msg = createException(MAL, name,
1515 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1516 0 : goto bailout;
1517 : }
1518 2 : canditer_init(&ci1, arg1, arg1s);
1519 2 : canditer_init(&ci2, arg2, arg2s);
1520 2 : canditer_init(&ci3, arg3, arg3s);
1521 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
1522 2 : || ci2.hseq != ci3.hseq) {
1523 0 : msg = createException(MAL, name,
1524 : ILLEGAL_ARGUMENT
1525 : " Requires bats of identical size");
1526 0 : goto bailout;
1527 : }
1528 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1529 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1530 0 : goto bailout;
1531 : }
1532 :
1533 2 : off1 = arg1->hseqbase;
1534 2 : off2 = arg2->hseqbase;
1535 2 : off3 = arg3->hseqbase;
1536 2 : arg1i = bat_iterator(arg1);
1537 2 : bi = bat_iterator(arg2);
1538 2 : arg2i = bi.base;
1539 2 : arg3i = bat_iterator(arg3);
1540 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
1541 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1542 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1543 8 : p2 = (canditer_next_dense(&ci2) - off2),
1544 8 : p3 = (canditer_next_dense(&ci3) - off3);
1545 8 : const char *x = BUNtvar(arg1i, p1);
1546 8 : y = arg2i[p2];
1547 8 : const char *z = BUNtvar(arg3i, p3);
1548 :
1549 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1550 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1551 0 : msg = createException(MAL, name,
1552 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1553 0 : goto bailout1;
1554 : }
1555 : nils = true;
1556 : } else {
1557 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1558 0 : goto bailout1;
1559 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1560 0 : msg = createException(MAL, name,
1561 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1562 0 : goto bailout1;
1563 : }
1564 : }
1565 : }
1566 : } else {
1567 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1568 0 : oid p1 = (canditer_next(&ci1) - off1),
1569 0 : p2 = (canditer_next(&ci2) - off2),
1570 0 : p3 = (canditer_next(&ci3) - off3);
1571 0 : const char *x = BUNtvar(arg1i, p1);
1572 0 : y = arg2i[p2];
1573 0 : const char *z = BUNtvar(arg3i, p3);
1574 :
1575 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1576 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1577 0 : msg = createException(MAL, name,
1578 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1579 0 : goto bailout1;
1580 : }
1581 : nils = true;
1582 : } else {
1583 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1584 0 : goto bailout1;
1585 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1586 0 : msg = createException(MAL, name,
1587 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1588 0 : goto bailout1;
1589 : }
1590 : }
1591 : }
1592 : }
1593 0 : bailout1:
1594 2 : bat_iterator_end(&arg1i);
1595 2 : bat_iterator_end(&arg3i);
1596 2 : bat_iterator_end(&bi);
1597 2 : bailout:
1598 2 : GDKfree(buf);
1599 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1600 2 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
1601 2 : return msg;
1602 : }
1603 :
1604 : static str
1605 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 8 : STRbatStrip2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1669 : {
1670 8 : 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 27 : *sid1 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 4 : 3) : NULL,
1855 27 : *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 2012 : for (BUN i = 0; i < ci1.ncand; i++) {
2012 1954 : oid p1 = (canditer_next_dense(&ci1) - off1);
2013 1954 : char *x = BUNtvar(bi, p1);
2014 :
2015 1954 : if (ynil || strNil(x)) {
2016 6 : vals[i] = bit_nil;
2017 6 : nils = true;
2018 : } else {
2019 1948 : vals[i] = func(x, y, ylen) == 0;
2020 : }
2021 : }
2022 : } else {
2023 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2024 0 : oid p1 = (canditer_next(&ci1) - off1);
2025 0 : char *x = BUNtvar(bi, p1);
2026 :
2027 0 : if (ynil || strNil(x)) {
2028 0 : vals[i] = bit_nil;
2029 0 : nils = true;
2030 : } else {
2031 0 : vals[i] = func(x, y, ylen) == 0;
2032 : }
2033 : }
2034 : }
2035 58 : bat_iterator_end(&bi);
2036 58 : exit2:
2037 58 : finalize_output(res, bn, msg, nils, ci1.ncand);
2038 58 : unfix_inputs(2, b, bs);
2039 58 : return msg;
2040 : }
2041 :
2042 : static str
2043 16 : BATSTRstarts_with_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2044 : {
2045 16 : bit *icase = NULL;
2046 16 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2047 10 : || pci->argc == 5) {
2048 6 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2049 6 : icase = getArgReference_bit(stk, pci, 3);
2050 : }
2051 16 : return prefix_or_suffix_cst(cntxt, mb, stk, pci, "batstr.startswith",
2052 : (icase
2053 6 : && *icase) ? str_is_iprefix : str_is_prefix,
2054 : icase);
2055 : }
2056 :
2057 : static str
2058 21 : BATSTRends_with_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2059 : {
2060 21 : bit *icase = NULL;
2061 21 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2062 12 : || pci->argc == 5) {
2063 9 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2064 9 : icase = getArgReference_bit(stk, pci, 3);
2065 : }
2066 21 : return prefix_or_suffix_cst(cntxt, mb, stk, pci, "batstr.endswith",
2067 : (icase
2068 9 : && *icase) ? str_is_isuffix : str_is_suffix,
2069 : icase);
2070 : }
2071 :
2072 : static str
2073 21 : BATSTRcontains_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2074 : {
2075 21 : bit *icase = NULL;
2076 21 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2077 12 : || pci->argc == 5) {
2078 9 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2079 9 : icase = getArgReference_bit(stk, pci, 3);
2080 : }
2081 21 : return prefix_or_suffix_cst(cntxt, mb, stk, pci, "batstr.contains",
2082 : (icase
2083 9 : && *icase) ? str_icontains : str_contains,
2084 : icase);
2085 : }
2086 :
2087 : static str
2088 0 : prefix_or_suffix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2089 : const char *name, int (*func)(const char *,
2090 : const char *, int),
2091 : bit *icase)
2092 : {
2093 0 : (void) cntxt;
2094 0 : (void) mb;
2095 :
2096 0 : BATiter bi;
2097 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2098 0 : bit *restrict vals;
2099 0 : const char *x = *getArgReference_str(stk, pci, 1);
2100 0 : str msg = MAL_SUCCEED;
2101 0 : bool nils = false;
2102 0 : struct canditer ci1 = { 0 };
2103 0 : oid off1;
2104 0 : bat *res = getArgReference_bat(stk, pci, 0),
2105 0 : bid = *getArgReference_bat(stk, pci, 2), *sid1 = NULL;
2106 0 : int xnil;
2107 :
2108 0 : if ((!icase && (pci->argc == 4)) || pci->argc == 5) {
2109 0 : assert(isaBatType(getArgType(mb, pci, icase ? 4 : 3)));
2110 0 : sid1 = getArgReference_bat(stk, pci, icase ? 4 : 3);
2111 : }
2112 :
2113 0 : if (!(b = BATdescriptor(bid))) {
2114 0 : msg = createException(MAL, name,
2115 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2116 0 : goto exit2;
2117 : }
2118 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2119 0 : msg = createException(MAL, name,
2120 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2121 0 : goto exit2;
2122 : }
2123 0 : canditer_init(&ci1, b, bs);
2124 0 : if (!(bn = COLnew(ci1.hseq, TYPE_bit, ci1.ncand, TRANSIENT))) {
2125 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2126 0 : goto exit2;
2127 : }
2128 :
2129 0 : off1 = b->hseqbase;
2130 0 : bi = bat_iterator(b);
2131 0 : vals = Tloc(bn, 0);
2132 0 : xnil = strNil(x);
2133 0 : if (ci1.tpe == cand_dense) {
2134 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2135 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
2136 0 : char *y = BUNtvar(bi, p1);
2137 :
2138 0 : if (xnil || strNil(y)) {
2139 0 : vals[i] = bit_nil;
2140 0 : nils = true;
2141 : } else {
2142 0 : vals[i] = func(x, y, str_strlen(y)) == 0;
2143 : }
2144 : }
2145 : } else {
2146 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2147 0 : oid p1 = (canditer_next(&ci1) - off1);
2148 0 : char *y = BUNtvar(bi, p1);
2149 :
2150 0 : if (xnil || strNil(y)) {
2151 0 : vals[i] = bit_nil;
2152 0 : nils = true;
2153 : } else {
2154 0 : vals[i] = func(x, y, str_strlen(y)) == 0;
2155 : }
2156 : }
2157 : }
2158 0 : bat_iterator_end(&bi);
2159 0 : exit2:
2160 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2161 0 : unfix_inputs(2, b, bs);
2162 0 : return msg;
2163 : }
2164 :
2165 : static str
2166 0 : BATSTRstarts_with_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
2167 : InstrPtr pci)
2168 : {
2169 0 : bit *icase = NULL;
2170 0 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2171 0 : || pci->argc == 5) {
2172 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2173 0 : icase = getArgReference_bit(stk, pci, 3);
2174 : }
2175 0 : return prefix_or_suffix_strcst(cntxt, mb, stk, pci, "batstr.startsWith",
2176 : (icase
2177 0 : && *icase) ? str_is_iprefix : str_is_prefix,
2178 : icase);
2179 : }
2180 :
2181 : static str
2182 0 : BATSTRends_with_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2183 : {
2184 0 : bit *icase = NULL;
2185 0 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2186 0 : || pci->argc == 5) {
2187 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2188 0 : icase = getArgReference_bit(stk, pci, 3);
2189 : }
2190 0 : return prefix_or_suffix_strcst(cntxt, mb, stk, pci, "batstr.endsWith",
2191 : (icase
2192 0 : && *icase) ? str_is_isuffix : str_is_suffix,
2193 : icase);
2194 : }
2195 :
2196 : static str
2197 0 : BATSTRcontains_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2198 : {
2199 0 : bit *icase = NULL;
2200 0 : if ((pci->argc == 4 && getArgType(mb, pci, 3) == TYPE_bit)
2201 0 : || pci->argc == 5) {
2202 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2203 0 : icase = getArgReference_bit(stk, pci, 3);
2204 : }
2205 0 : return prefix_or_suffix_strcst(cntxt, mb, stk, pci, "batstr.contains",
2206 : (icase
2207 0 : && *icase) ? str_icontains : str_contains,
2208 : icase);
2209 : }
2210 :
2211 : static str
2212 1 : search_string_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2213 : const char *name, int (*func)(const char *, const char *),
2214 : bit *icase)
2215 : {
2216 1 : (void) cntxt;
2217 1 : (void) mb;
2218 :
2219 1 : BATiter lefti, righti;
2220 1 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
2221 1 : int *restrict vals;
2222 1 : str msg = MAL_SUCCEED;
2223 1 : bool nils = false;
2224 1 : struct canditer ci1 = { 0 }, ci2 = { 0 };
2225 1 : oid off1, off2;
2226 1 : bat *res = getArgReference_bat(stk, pci, 0),
2227 1 : l = *getArgReference_bat(stk, pci, 1),
2228 1 : r = *getArgReference_bat(stk, pci, 2),
2229 1 : *sid1 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 4 : 3) : NULL,
2230 1 : *sid2 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 5 : 4) : NULL;
2231 :
2232 1 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
2233 0 : msg = createException(MAL, name,
2234 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2235 0 : goto exit2;
2236 : }
2237 1 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) ||
2238 0 : (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
2239 0 : msg = createException(MAL, name,
2240 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2241 0 : goto exit2;
2242 : }
2243 1 : canditer_init(&ci1, left, lefts);
2244 1 : canditer_init(&ci2, right, rights);
2245 1 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
2246 0 : msg = createException(MAL, name,
2247 : ILLEGAL_ARGUMENT
2248 : " Requires bats of identical size");
2249 0 : goto exit2;
2250 : }
2251 1 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2252 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2253 0 : goto exit2;
2254 : }
2255 :
2256 1 : off1 = left->hseqbase;
2257 1 : off2 = right->hseqbase;
2258 1 : lefti = bat_iterator(left);
2259 1 : righti = bat_iterator(right);
2260 1 : vals = Tloc(bn, 0);
2261 1 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
2262 5 : for (BUN i = 0; i < ci1.ncand; i++) {
2263 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
2264 4 : p2 = (canditer_next_dense(&ci2) - off2);
2265 4 : char *x = BUNtvar(lefti, p1);
2266 4 : char *y = BUNtvar(righti, p2);
2267 :
2268 8 : if (strNil(x) || strNil(y)) {
2269 0 : vals[i] = int_nil;
2270 0 : nils = true;
2271 : } else {
2272 4 : vals[i] = func(x, y);
2273 : }
2274 : }
2275 : } else {
2276 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2277 0 : oid p1 = (canditer_next(&ci1) - off1),
2278 0 : p2 = (canditer_next(&ci2) - off2);
2279 0 : char *x = BUNtvar(lefti, p1);
2280 0 : char *y = BUNtvar(righti, p2);
2281 :
2282 0 : if (strNil(x) || strNil(y)) {
2283 0 : vals[i] = int_nil;
2284 0 : nils = true;
2285 : } else {
2286 0 : vals[i] = func(x, y);
2287 : }
2288 : }
2289 : }
2290 1 : bat_iterator_end(&lefti);
2291 1 : bat_iterator_end(&righti);
2292 1 : exit2:
2293 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
2294 1 : unfix_inputs(4, left, lefts, right, rights);
2295 1 : return msg;
2296 : }
2297 :
2298 : static str
2299 1 : BATSTRstr_search(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2300 : {
2301 1 : bit *icase = NULL;
2302 1 : switch (pci->argc) {
2303 0 : case 4:
2304 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2305 0 : icase = getArgReference_bit(stk, pci, 3);
2306 : break;
2307 0 : case 6:
2308 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2309 0 : icase = getArgReference_bit(stk, pci, 3);
2310 0 : break;
2311 : }
2312 1 : return search_string_bat(cntxt, mb, stk, pci, "batstr.search",
2313 : (icase
2314 0 : && *icase) ? str_isearch : str_search, icase);
2315 : }
2316 :
2317 : static str
2318 0 : BATSTRrevstr_search(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2319 : {
2320 0 : bit *icase = NULL;
2321 0 : switch (pci->argc) {
2322 0 : case 4:
2323 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2324 0 : icase = getArgReference_bit(stk, pci, 3);
2325 : break;
2326 0 : case 6:
2327 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2328 0 : icase = getArgReference_bit(stk, pci, 3);
2329 0 : break;
2330 : }
2331 0 : return search_string_bat(cntxt, mb, stk, pci, "batstr.r_search",
2332 0 : (icase && *icase) ?
2333 : str_reverse_str_isearch :
2334 : str_reverse_str_search, icase);
2335 : }
2336 :
2337 : static str
2338 1 : search_string_bat_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2339 : const char *name, int (*func)(const char *, const char *),
2340 : bit *icase)
2341 : {
2342 1 : (void) cntxt;
2343 1 : (void) mb;
2344 :
2345 1 : BATiter bi;
2346 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2347 1 : int *restrict vals;
2348 1 : const char *y = *getArgReference_str(stk, pci, 2);
2349 1 : str msg = MAL_SUCCEED;
2350 1 : bool nils = false;
2351 1 : struct canditer ci1 = { 0 };
2352 1 : oid off1;
2353 1 : bat *res = getArgReference_bat(stk, pci, 0),
2354 1 : bid = *getArgReference_bat(stk, pci, 1),
2355 1 : *sid1 = NULL;
2356 1 : int ynil;
2357 :
2358 1 : if ((!icase && (pci->argc == 4)) || pci->argc == 5) {
2359 0 : assert(isaBatType(getArgType(mb, pci, icase ? 4 : 3)));
2360 0 : sid1 = getArgReference_bat(stk, pci, icase ? 4 : 3);
2361 : }
2362 :
2363 1 : if (!(b = BATdescriptor(bid))) {
2364 0 : msg = createException(MAL, name,
2365 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2366 0 : goto exit2;
2367 : }
2368 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2369 0 : msg = createException(MAL, name,
2370 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2371 0 : goto exit2;
2372 : }
2373 1 : canditer_init(&ci1, b, bs);
2374 1 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2375 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2376 0 : goto exit2;
2377 : }
2378 :
2379 1 : off1 = b->hseqbase;
2380 1 : bi = bat_iterator(b);
2381 1 : vals = Tloc(bn, 0);
2382 1 : ynil = strNil(y);
2383 1 : if (ci1.tpe == cand_dense) {
2384 5 : for (BUN i = 0; i < ci1.ncand; i++) {
2385 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
2386 4 : char *x = BUNtvar(bi, p1);
2387 :
2388 4 : if (ynil || strNil(x)) {
2389 0 : vals[i] = int_nil;
2390 0 : nils = true;
2391 : } else {
2392 4 : vals[i] = func(x, y);
2393 : }
2394 : }
2395 : } else {
2396 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2397 0 : oid p1 = (canditer_next(&ci1) - off1);
2398 0 : char *x = BUNtvar(bi, p1);
2399 :
2400 0 : if (ynil || strNil(x)) {
2401 0 : vals[i] = int_nil;
2402 0 : nils = true;
2403 : } else {
2404 0 : vals[i] = func(x, y);
2405 : }
2406 : }
2407 : }
2408 1 : bat_iterator_end(&bi);
2409 1 : exit2:
2410 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
2411 1 : unfix_inputs(2, b, bs);
2412 1 : return msg;
2413 : }
2414 :
2415 : static str
2416 1 : BATSTRstr_search_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2417 : {
2418 1 : bit *icase = NULL;
2419 1 : switch (pci->argc) {
2420 0 : case 4:
2421 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2422 0 : icase = getArgReference_bit(stk, pci, 3);
2423 : break;
2424 0 : case 5:
2425 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2426 0 : icase = getArgReference_bit(stk, pci, 3);
2427 0 : break;
2428 : }
2429 1 : return search_string_bat_cst(cntxt, mb, stk, pci, "batstr.search",
2430 : (icase
2431 0 : && *icase) ? str_isearch : str_search, icase);
2432 : }
2433 :
2434 : static str
2435 0 : BATSTRrevstr_search_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2436 : {
2437 0 : bit *icase = NULL;
2438 0 : switch (pci->argc) {
2439 0 : case 4:
2440 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2441 0 : icase = getArgReference_bit(stk, pci, 3);
2442 : break;
2443 0 : case 5:
2444 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2445 0 : icase = getArgReference_bit(stk, pci, 3);
2446 0 : break;
2447 : }
2448 0 : return search_string_bat_cst(cntxt, mb, stk, pci, "batstr.r_search",
2449 : (icase
2450 0 : && *icase) ? str_reverse_str_isearch :
2451 : str_reverse_str_search, icase);
2452 : }
2453 :
2454 : static str
2455 0 : search_string_bat_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
2456 : InstrPtr pci, const char *name,
2457 : int (*func)(const char *, const char *),
2458 : bit *icase)
2459 : {
2460 0 : (void) cntxt;
2461 0 : (void) mb;
2462 :
2463 0 : BATiter bi;
2464 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2465 0 : int *restrict vals;
2466 0 : const char *x = *getArgReference_str(stk, pci, 1);
2467 0 : str msg = MAL_SUCCEED;
2468 0 : bool nils = false;
2469 0 : struct canditer ci1 = { 0 };
2470 0 : oid off1;
2471 0 : bat *res = getArgReference_bat(stk, pci, 0),
2472 0 : bid = *getArgReference_bat(stk, pci, 2), *sid1 = NULL;
2473 0 : int xnil;
2474 :
2475 0 : if ((!icase && (pci->argc == 4)) || pci->argc == 5) {
2476 0 : assert(isaBatType(getArgType(mb, pci, icase ? 4 : 3)));
2477 0 : sid1 = getArgReference_bat(stk, pci, icase ? 4 : 3);
2478 : }
2479 :
2480 0 : if (!(b = BATdescriptor(bid))) {
2481 0 : msg = createException(MAL, name,
2482 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2483 0 : goto exit2;
2484 : }
2485 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2486 0 : msg = createException(MAL, name,
2487 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2488 0 : goto exit2;
2489 : }
2490 0 : canditer_init(&ci1, b, bs);
2491 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2492 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2493 0 : goto exit2;
2494 : }
2495 :
2496 0 : off1 = b->hseqbase;
2497 0 : bi = bat_iterator(b);
2498 0 : vals = Tloc(bn, 0);
2499 0 : xnil = strNil(x);
2500 0 : if (ci1.tpe == cand_dense) {
2501 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2502 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
2503 0 : char *y = BUNtvar(bi, p1);
2504 :
2505 0 : if (xnil || strNil(y)) {
2506 0 : vals[i] = int_nil;
2507 0 : nils = true;
2508 : } else {
2509 0 : vals[i] = func(x, y);
2510 : }
2511 : }
2512 : } else {
2513 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2514 0 : oid p1 = (canditer_next(&ci1) - off1);
2515 0 : char *y = BUNtvar(bi, p1);
2516 :
2517 0 : if (xnil || strNil(y)) {
2518 0 : vals[i] = int_nil;
2519 0 : nils = true;
2520 : } else {
2521 0 : vals[i] = func(x, y);
2522 : }
2523 : }
2524 : }
2525 0 : bat_iterator_end(&bi);
2526 0 : exit2:
2527 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2528 0 : unfix_inputs(2, b, bs);
2529 0 : return msg;
2530 : }
2531 :
2532 : static str
2533 0 : BATSTRstr_search_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2534 : {
2535 0 : bit *icase = NULL;
2536 0 : switch (pci->argc) {
2537 0 : case 4:
2538 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2539 0 : icase = getArgReference_bit(stk, pci, 3);
2540 : break;
2541 0 : case 5:
2542 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2543 0 : icase = getArgReference_bit(stk, pci, 3);
2544 0 : break;
2545 : }
2546 0 : return search_string_bat_strcst(cntxt, mb, stk, pci, "batstr.search",
2547 : (icase
2548 0 : && *icase) ? str_isearch : str_search,
2549 : icase);
2550 : }
2551 :
2552 : static str
2553 0 : BATSTRrevstr_search_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
2554 : InstrPtr pci)
2555 : {
2556 0 : bit *icase = NULL;
2557 0 : switch (pci->argc) {
2558 0 : case 4:
2559 0 : if (getArgType(mb, pci, 3) == TYPE_bit)
2560 0 : icase = getArgReference_bit(stk, pci, 3);
2561 : break;
2562 0 : case 5:
2563 0 : assert(getArgType(mb, pci, 3) == TYPE_bit);
2564 0 : icase = getArgReference_bit(stk, pci, 3);
2565 0 : break;
2566 : }
2567 0 : return search_string_bat_strcst(cntxt, mb, stk, pci, "batstr.r_search",
2568 : (icase
2569 0 : && *icase) ? str_reverse_str_isearch :
2570 : str_reverse_str_search, icase);
2571 : }
2572 :
2573 : static str
2574 0 : STRbatWChrAt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2575 : {
2576 0 : BATiter lefti, bi;
2577 0 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
2578 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2579 0 : int *restrict righti, *restrict vals, next, y;
2580 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2581 0 : bool nils = false;
2582 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
2583 0 : oid off1, off2;
2584 0 : bat *res = getArgReference_bat(stk, pci, 0),
2585 0 : l = *getArgReference_bat(stk, pci, 1),
2586 0 : r = *getArgReference_bat(stk, pci, 2),
2587 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
2588 0 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
2589 :
2590 0 : (void) cntxt;
2591 0 : (void) mb;
2592 0 : if (!buf) {
2593 0 : msg = createException(MAL, "batstr.unicodeAt",
2594 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2595 0 : goto bailout;
2596 : }
2597 0 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
2598 0 : msg = createException(MAL, "batstr.unicodeAt",
2599 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2600 0 : goto bailout;
2601 : }
2602 0 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
2603 0 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
2604 0 : msg = createException(MAL, "batstr.unicodeAt",
2605 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2606 0 : goto bailout;
2607 : }
2608 0 : canditer_init(&ci1, left, lefts);
2609 0 : canditer_init(&ci2, right, rights);
2610 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
2611 0 : msg = createException(MAL, "batstr.unicodeAt",
2612 : ILLEGAL_ARGUMENT
2613 : " Requires bats of identical size");
2614 0 : goto bailout;
2615 : }
2616 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2617 0 : msg = createException(MAL, "batstr.unicodeAt",
2618 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2619 0 : goto bailout;
2620 : }
2621 :
2622 0 : off1 = left->hseqbase;
2623 0 : off2 = right->hseqbase;
2624 0 : lefti = bat_iterator(left);
2625 0 : bi = bat_iterator(right);
2626 0 : righti = bi.base;
2627 0 : vals = Tloc(bn, 0);
2628 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
2629 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2630 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
2631 0 : p2 = (canditer_next_dense(&ci2) - off2);
2632 0 : const char *x = BUNtvar(lefti, p1);
2633 0 : y = righti[p2];
2634 :
2635 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2636 0 : goto bailout1;
2637 0 : vals[i] = next;
2638 0 : nils |= is_int_nil(next);
2639 : }
2640 : } else {
2641 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2642 0 : oid p1 = (canditer_next(&ci1) - off1),
2643 0 : p2 = (canditer_next(&ci2) - off2);
2644 0 : const char *x = BUNtvar(lefti, p1);
2645 0 : y = righti[p2];
2646 :
2647 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2648 0 : goto bailout1;
2649 0 : vals[i] = next;
2650 0 : nils |= is_int_nil(next);
2651 : }
2652 : }
2653 0 : bailout1:
2654 0 : bat_iterator_end(&bi);
2655 0 : bat_iterator_end(&lefti);
2656 0 : bailout:
2657 0 : GDKfree(buf);
2658 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2659 0 : unfix_inputs(4, left, lefts, right, rights);
2660 0 : return msg;
2661 : }
2662 :
2663 : static str
2664 0 : STRbatWChrAtcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2665 : {
2666 0 : BATiter bi;
2667 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2668 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2669 0 : int y = *getArgReference_int(stk, pci, 2), *restrict vals, next;
2670 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2671 0 : bool nils = false;
2672 0 : struct canditer ci1 = { 0 };
2673 0 : oid off1;
2674 0 : bat *res = getArgReference_bat(stk, pci, 0),
2675 0 : l = *getArgReference_bat(stk, pci, 1),
2676 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2677 :
2678 0 : (void) cntxt;
2679 0 : (void) mb;
2680 0 : if (!buf) {
2681 0 : msg = createException(MAL, "batstr.unicodeAt",
2682 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2683 0 : goto bailout;
2684 : }
2685 0 : if (!(b = BATdescriptor(l))) {
2686 0 : msg = createException(MAL, "batstr.unicodeAt",
2687 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2688 0 : goto bailout;
2689 : }
2690 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2691 0 : msg = createException(MAL, "batstr.unicodeAt",
2692 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2693 0 : goto bailout;
2694 : }
2695 0 : canditer_init(&ci1, b, bs);
2696 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2697 0 : msg = createException(MAL, "batstr.unicodeAt",
2698 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2699 0 : goto bailout;
2700 : }
2701 :
2702 0 : off1 = b->hseqbase;
2703 0 : bi = bat_iterator(b);
2704 0 : vals = Tloc(bn, 0);
2705 0 : if (ci1.tpe == cand_dense) {
2706 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2707 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
2708 0 : const char *x = BUNtvar(bi, p1);
2709 :
2710 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2711 0 : goto bailout1;
2712 0 : vals[i] = next;
2713 0 : nils |= is_int_nil(next);
2714 : }
2715 : } else {
2716 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2717 0 : oid p1 = (canditer_next(&ci1) - off1);
2718 0 : const char *x = BUNtvar(bi, p1);
2719 :
2720 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2721 0 : goto bailout1;
2722 0 : vals[i] = next;
2723 0 : nils |= is_int_nil(next);
2724 : }
2725 : }
2726 0 : bailout1:
2727 0 : bat_iterator_end(&bi);
2728 0 : bailout:
2729 0 : GDKfree(buf);
2730 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2731 0 : unfix_inputs(2, b, bs);
2732 0 : return msg;
2733 : }
2734 :
2735 : static str
2736 0 : STRbatWChrAt_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2737 : {
2738 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2739 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2740 0 : int y, *restrict vals, *restrict input, next;
2741 0 : const char *x = *getArgReference_str(stk, pci, 1);
2742 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2743 0 : bool nils = false;
2744 0 : struct canditer ci1 = { 0 };
2745 0 : oid off1;
2746 0 : bat *res = getArgReference_bat(stk, pci, 0),
2747 0 : l = *getArgReference_bat(stk, pci, 2),
2748 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2749 0 : BATiter bi;
2750 :
2751 0 : (void) cntxt;
2752 0 : (void) mb;
2753 0 : if (!buf) {
2754 0 : msg = createException(MAL, "batstr.unicodeAt",
2755 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2756 0 : goto bailout;
2757 : }
2758 0 : if (!(b = BATdescriptor(l))) {
2759 0 : msg = createException(MAL, "batstr.unicodeAt",
2760 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2761 0 : goto bailout;
2762 : }
2763 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2764 0 : msg = createException(MAL, "batstr.unicodeAt",
2765 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2766 0 : goto bailout;
2767 : }
2768 0 : canditer_init(&ci1, b, bs);
2769 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
2770 0 : msg = createException(MAL, "batstr.unicodeAt",
2771 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2772 0 : goto bailout;
2773 : }
2774 :
2775 0 : off1 = b->hseqbase;
2776 0 : bi = bat_iterator(b);
2777 0 : input = bi.base;
2778 0 : vals = Tloc(bn, 0);
2779 0 : if (ci1.tpe == cand_dense) {
2780 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2781 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
2782 0 : y = input[p1];
2783 :
2784 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2785 0 : goto bailout1;
2786 0 : vals[i] = next;
2787 0 : nils |= is_int_nil(next);
2788 : }
2789 : } else {
2790 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2791 0 : oid p1 = (canditer_next(&ci1) - off1);
2792 0 : y = input[p1];
2793 :
2794 0 : if ((msg = str_wchr_at(&next, x, y)) != MAL_SUCCEED)
2795 0 : goto bailout1;
2796 0 : vals[i] = next;
2797 0 : nils |= is_int_nil(next);
2798 : }
2799 : }
2800 0 : bailout1:
2801 0 : bat_iterator_end(&bi);
2802 0 : bailout:
2803 0 : GDKfree(buf);
2804 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
2805 0 : unfix_inputs(2, b, bs);
2806 0 : return msg;
2807 : }
2808 :
2809 : static str
2810 95 : do_batstr_str_int_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
2811 : const char *name, str (*func)(str *, size_t *,
2812 : const char *, int))
2813 : {
2814 95 : BATiter bi;
2815 95 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2816 95 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2817 95 : int y = *getArgReference_int(stk, pci, 2);
2818 95 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2819 95 : bool nils = false;
2820 95 : struct canditer ci1 = { 0 };
2821 95 : oid off1;
2822 95 : bat *res = getArgReference_bat(stk, pci, 0),
2823 95 : l = *getArgReference_bat(stk, pci, 1),
2824 95 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2825 :
2826 95 : (void) cntxt;
2827 95 : (void) mb;
2828 95 : if (!buf) {
2829 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2830 0 : goto bailout;
2831 : }
2832 95 : if (!(b = BATdescriptor(l))) {
2833 0 : msg = createException(MAL, name,
2834 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2835 0 : goto bailout;
2836 : }
2837 95 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2838 0 : msg = createException(MAL, name,
2839 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2840 0 : goto bailout;
2841 : }
2842 95 : canditer_init(&ci1, b, bs);
2843 95 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
2844 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
2845 0 : goto bailout;
2846 : }
2847 :
2848 95 : off1 = b->hseqbase;
2849 95 : bi = bat_iterator(b);
2850 95 : if (ci1.tpe == cand_dense) {
2851 6137 : for (BUN i = 0; i < ci1.ncand; i++) {
2852 6042 : oid p1 = (canditer_next_dense(&ci1) - off1);
2853 6042 : const char *x = BUNtvar(bi, p1);
2854 :
2855 11665 : if (strNil(x) || is_int_nil(y)) {
2856 422 : 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 5620 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
2864 0 : goto bailout1;
2865 5620 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
2866 0 : msg = createException(MAL, name,
2867 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2868 0 : goto bailout1;
2869 : }
2870 : }
2871 : }
2872 : } else {
2873 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2874 0 : oid p1 = (canditer_next(&ci1) - off1);
2875 0 : const char *x = BUNtvar(bi, p1);
2876 :
2877 0 : if (strNil(x) || is_int_nil(y)) {
2878 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
2879 0 : msg = createException(MAL, name,
2880 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2881 0 : goto bailout1;
2882 : }
2883 : nils = true;
2884 : } else {
2885 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
2886 0 : goto bailout1;
2887 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
2888 0 : msg = createException(MAL, name,
2889 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2890 0 : goto bailout1;
2891 : }
2892 : }
2893 : }
2894 : }
2895 0 : bailout1:
2896 95 : bat_iterator_end(&bi);
2897 95 : bailout:
2898 95 : GDKfree(buf);
2899 95 : finalize_output(res, bn, msg, nils, ci1.ncand);
2900 95 : unfix_inputs(2, b, bs);
2901 95 : return msg;
2902 : }
2903 :
2904 : static str
2905 85 : STRbatprefixcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2906 : {
2907 85 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.prefix",
2908 : str_prefix);
2909 : }
2910 :
2911 : static str
2912 1 : STRbatsuffixcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2913 : {
2914 1 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.suffix",
2915 : str_suffix);
2916 : }
2917 :
2918 : static str
2919 5 : STRbatTailcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2920 : {
2921 5 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.tail", str_tail);
2922 : }
2923 :
2924 : static str
2925 4 : STRbatsubstringTailcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2926 : {
2927 4 : return do_batstr_str_int_cst(cntxt, mb, stk, pci, "batstr.substring",
2928 : str_substring_tail);
2929 : }
2930 :
2931 : static str
2932 1 : STRbatrepeatcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2933 : {
2934 1 : BATiter bi;
2935 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
2936 1 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
2937 1 : int y = *getArgReference_int(stk, pci, 2);
2938 1 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
2939 1 : bool nils = false;
2940 1 : struct canditer ci1 = { 0 };
2941 1 : oid off1;
2942 1 : bat *res = getArgReference_bat(stk, pci, 0),
2943 1 : l = *getArgReference_bat(stk, pci, 1),
2944 1 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
2945 :
2946 1 : (void) cntxt;
2947 1 : (void) mb;
2948 1 : if (!buf) {
2949 0 : msg = createException(MAL, "batstr.repeat",
2950 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2951 0 : goto bailout;
2952 : }
2953 1 : if (!(b = BATdescriptor(l))) {
2954 0 : msg = createException(MAL, "batstr.repeat",
2955 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2956 0 : goto bailout;
2957 : }
2958 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
2959 0 : msg = createException(MAL, "batstr.repeat",
2960 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
2961 0 : goto bailout;
2962 : }
2963 1 : canditer_init(&ci1, b, bs);
2964 1 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
2965 0 : msg = createException(MAL, "batstr.repeat",
2966 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2967 0 : goto bailout;
2968 : }
2969 :
2970 1 : off1 = b->hseqbase;
2971 1 : bi = bat_iterator(b);
2972 1 : if (ci1.tpe == cand_dense) {
2973 5 : for (BUN i = 0; i < ci1.ncand; i++) {
2974 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
2975 4 : const char *x = BUNtvar(bi, p1);
2976 :
2977 8 : if (strNil(x) || is_int_nil(y) || y < 0) {
2978 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
2979 0 : msg = createException(MAL, "batstr.repeat",
2980 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2981 0 : goto bailout1;
2982 : }
2983 : nils = true;
2984 : } else {
2985 4 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
2986 0 : goto bailout1;
2987 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
2988 0 : msg = createException(MAL, "batstr.repeat",
2989 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2990 0 : goto bailout1;
2991 : }
2992 : }
2993 : }
2994 : } else {
2995 0 : for (BUN i = 0; i < ci1.ncand; i++) {
2996 0 : oid p1 = (canditer_next(&ci1) - off1);
2997 0 : const char *x = BUNtvar(bi, p1);
2998 :
2999 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3000 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3001 0 : msg = createException(MAL, "batstr.repeat",
3002 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3003 0 : goto bailout1;
3004 : }
3005 : nils = true;
3006 : } else {
3007 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3008 0 : goto bailout1;
3009 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3010 0 : msg = createException(MAL, "batstr.repeat",
3011 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3012 0 : goto bailout1;
3013 : }
3014 : }
3015 : }
3016 : }
3017 0 : bailout1:
3018 1 : bat_iterator_end(&bi);
3019 1 : bailout:
3020 1 : GDKfree(buf);
3021 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
3022 1 : unfix_inputs(2, b, bs);
3023 1 : return msg;
3024 : }
3025 :
3026 : static str
3027 5 : do_batstr_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3028 : const char *name,
3029 : str (*func)(str *, size_t *, const char *, int))
3030 : {
3031 5 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3032 5 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3033 5 : int *restrict vals, y;
3034 5 : const char *x = *getArgReference_str(stk, pci, 1);
3035 5 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3036 5 : bool nils = false;
3037 5 : struct canditer ci1 = { 0 };
3038 5 : oid off1;
3039 5 : bat *res = getArgReference_bat(stk, pci, 0),
3040 5 : l = *getArgReference_bat(stk, pci, 2),
3041 5 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
3042 5 : BATiter bi;
3043 :
3044 5 : (void) cntxt;
3045 5 : (void) mb;
3046 5 : if (!buf) {
3047 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3048 0 : goto bailout;
3049 : }
3050 5 : if (!(b = BATdescriptor(l))) {
3051 0 : msg = createException(MAL, name,
3052 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3053 0 : goto bailout;
3054 : }
3055 5 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3056 0 : msg = createException(MAL, name,
3057 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3058 0 : goto bailout;
3059 : }
3060 5 : canditer_init(&ci1, b, bs);
3061 5 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3062 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3063 0 : goto bailout;
3064 : }
3065 :
3066 5 : off1 = b->hseqbase;
3067 5 : bi = bat_iterator(b);
3068 5 : vals = bi.base;
3069 5 : if (ci1.tpe == cand_dense) {
3070 10 : for (BUN i = 0; i < ci1.ncand; i++) {
3071 5 : oid p1 = (canditer_next_dense(&ci1) - off1);
3072 5 : y = vals[p1];
3073 :
3074 10 : if (strNil(x) || is_int_nil(y)) {
3075 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3076 0 : msg = createException(MAL, name,
3077 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3078 0 : goto bailout1;
3079 : }
3080 : nils = true;
3081 : } else {
3082 5 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3083 0 : goto bailout1;
3084 5 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3085 0 : msg = createException(MAL, name,
3086 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3087 0 : goto bailout1;
3088 : }
3089 : }
3090 : }
3091 : } else {
3092 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3093 0 : oid p1 = (canditer_next(&ci1) - off1);
3094 0 : y = vals[p1];
3095 :
3096 0 : if (strNil(x) || is_int_nil(y)) {
3097 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3098 0 : msg = createException(MAL, name,
3099 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3100 0 : goto bailout1;
3101 : }
3102 : nils = true;
3103 : } else {
3104 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3105 0 : goto bailout1;
3106 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3107 0 : msg = createException(MAL, name,
3108 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3109 0 : goto bailout1;
3110 : }
3111 : }
3112 : }
3113 : }
3114 0 : bailout1:
3115 5 : bat_iterator_end(&bi);
3116 5 : bailout:
3117 5 : GDKfree(buf);
3118 5 : finalize_output(res, bn, msg, nils, ci1.ncand);
3119 5 : unfix_inputs(2, b, bs);
3120 5 : return msg;
3121 : }
3122 :
3123 : static str
3124 5 : STRbatprefix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3125 : {
3126 5 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.prefix", str_prefix);
3127 : }
3128 :
3129 : static str
3130 0 : STRbatsuffix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3131 : {
3132 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.suffix", str_suffix);
3133 : }
3134 :
3135 : static str
3136 0 : STRbatTail_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3137 : {
3138 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.tail", str_tail);
3139 : }
3140 :
3141 : static str
3142 0 : STRbatsubstringTail_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3143 : InstrPtr pci)
3144 : {
3145 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.substring",
3146 : str_substring_tail);
3147 : }
3148 :
3149 : static str
3150 0 : STRbatrepeat_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3151 : {
3152 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3153 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3154 0 : int *restrict vals, y;
3155 0 : const char *x = *getArgReference_str(stk, pci, 1);
3156 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3157 0 : bool nils = false;
3158 0 : struct canditer ci1 = { 0 };
3159 0 : oid off1;
3160 0 : bat *res = getArgReference_bat(stk, pci, 0),
3161 0 : l = *getArgReference_bat(stk, pci, 2),
3162 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
3163 0 : BATiter bi;
3164 :
3165 0 : (void) cntxt;
3166 0 : (void) mb;
3167 0 : if (!buf) {
3168 0 : msg = createException(MAL, "batstr.repeat",
3169 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3170 0 : goto bailout;
3171 : }
3172 0 : if (!(b = BATdescriptor(l))) {
3173 0 : msg = createException(MAL, "batstr.repeat",
3174 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3175 0 : goto bailout;
3176 : }
3177 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3178 0 : msg = createException(MAL, "batstr.repeat",
3179 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3180 0 : goto bailout;
3181 : }
3182 0 : canditer_init(&ci1, b, bs);
3183 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3184 0 : msg = createException(MAL, "batstr.repeat",
3185 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3186 0 : goto bailout;
3187 : }
3188 :
3189 0 : off1 = b->hseqbase;
3190 0 : bi = bat_iterator(b);
3191 0 : vals = bi.base;
3192 0 : if (ci1.tpe == cand_dense) {
3193 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3194 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
3195 0 : y = vals[p1];
3196 :
3197 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3198 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3199 0 : msg = createException(MAL, "batstr.repeat",
3200 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3201 0 : goto bailout1;
3202 : }
3203 : nils = true;
3204 : } else {
3205 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3206 0 : goto bailout1;
3207 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3208 0 : msg = createException(MAL, "batstr.repeat",
3209 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3210 0 : goto bailout1;
3211 : }
3212 : }
3213 : }
3214 : } else {
3215 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3216 0 : oid p1 = (canditer_next(&ci1) - off1);
3217 0 : y = vals[p1];
3218 :
3219 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3220 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3221 0 : msg = createException(MAL, "batstr.repeat",
3222 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3223 0 : goto bailout1;
3224 : }
3225 : nils = true;
3226 : } else {
3227 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3228 0 : goto bailout1;
3229 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3230 0 : msg = createException(MAL, "batstr.repeat",
3231 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3232 0 : goto bailout1;
3233 : }
3234 : }
3235 : }
3236 : }
3237 0 : bailout1:
3238 0 : bat_iterator_end(&bi);
3239 0 : bailout:
3240 0 : GDKfree(buf);
3241 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3242 0 : unfix_inputs(2, b, bs);
3243 0 : return msg;
3244 : }
3245 :
3246 : static str
3247 33 : do_batstr_str_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3248 : const char *name, str (*func)(str *, size_t *, const char *,
3249 : int))
3250 : {
3251 33 : BATiter lefti;
3252 33 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
3253 33 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3254 33 : int *restrict righti, y;
3255 33 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3256 33 : bool nils = false;
3257 33 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3258 33 : oid off1, off2;
3259 33 : bat *res = getArgReference_bat(stk, pci, 0),
3260 33 : l = *getArgReference_bat(stk, pci, 1),
3261 33 : r = *getArgReference_bat(stk, pci, 2),
3262 33 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
3263 33 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3264 33 : BATiter bi;
3265 :
3266 33 : (void) cntxt;
3267 33 : (void) mb;
3268 33 : if (!buf) {
3269 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3270 0 : goto bailout;
3271 : }
3272 33 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
3273 0 : msg = createException(MAL, name,
3274 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3275 0 : goto bailout;
3276 : }
3277 33 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
3278 33 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
3279 0 : msg = createException(MAL, name,
3280 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3281 0 : goto bailout;
3282 : }
3283 33 : canditer_init(&ci1, left, lefts);
3284 33 : canditer_init(&ci2, right, rights);
3285 33 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3286 0 : msg = createException(MAL, name,
3287 : ILLEGAL_ARGUMENT
3288 : " Requires bats of identical size");
3289 0 : goto bailout;
3290 : }
3291 33 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3292 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3293 0 : goto bailout;
3294 : }
3295 :
3296 33 : off1 = left->hseqbase;
3297 33 : off2 = right->hseqbase;
3298 33 : lefti = bat_iterator(left);
3299 33 : bi = bat_iterator(right);
3300 33 : righti = bi.base;
3301 33 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3302 32458 : for (BUN i = 0; i < ci1.ncand; i++) {
3303 32425 : oid p1 = (canditer_next_dense(&ci1) - off1),
3304 32425 : p2 = (canditer_next_dense(&ci2) - off2);
3305 32425 : const char *x = BUNtvar(lefti, p1);
3306 32425 : y = righti[p2];
3307 :
3308 36214 : if (strNil(x) || is_int_nil(y)) {
3309 28636 : 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 3789 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3317 0 : goto bailout1;
3318 3785 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3319 0 : msg = createException(MAL, name,
3320 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3321 0 : goto bailout1;
3322 : }
3323 : }
3324 : }
3325 : } else {
3326 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3327 0 : oid p1 = (canditer_next(&ci1) - off1),
3328 0 : p2 = (canditer_next(&ci2) - off2);
3329 0 : const char *x = BUNtvar(lefti, p1);
3330 0 : y = righti[p2];
3331 :
3332 0 : if (strNil(x) || is_int_nil(y)) {
3333 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3334 0 : msg = createException(MAL, name,
3335 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3336 0 : goto bailout1;
3337 : }
3338 : nils = true;
3339 : } else {
3340 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3341 0 : goto bailout1;
3342 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3343 0 : msg = createException(MAL, name,
3344 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3345 0 : goto bailout1;
3346 : }
3347 : }
3348 : }
3349 : }
3350 0 : bailout1:
3351 33 : bat_iterator_end(&bi);
3352 33 : bat_iterator_end(&lefti);
3353 33 : bailout:
3354 33 : GDKfree(buf);
3355 33 : finalize_output(res, bn, msg, nils, ci1.ncand);
3356 33 : unfix_inputs(4, left, lefts, right, rights);
3357 33 : return msg;
3358 : }
3359 :
3360 : static str
3361 0 : STRbatprefix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3362 : {
3363 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.prefix", str_prefix);
3364 : }
3365 :
3366 : static str
3367 0 : STRbatsuffix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3368 : {
3369 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.suffix", str_suffix);
3370 : }
3371 :
3372 : static str
3373 0 : STRbatTail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3374 : {
3375 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.tail", str_tail);
3376 : }
3377 :
3378 : static str
3379 33 : STRbatsubstringTail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3380 : {
3381 33 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.substring",
3382 : str_substring_tail);
3383 : }
3384 :
3385 : static str
3386 0 : STRbatrepeat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3387 : {
3388 0 : BATiter lefti;
3389 0 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
3390 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3391 0 : int *restrict righti, y;
3392 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3393 0 : bool nils = false;
3394 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3395 0 : oid off1, off2;
3396 0 : bat *res = getArgReference_bat(stk, pci, 0),
3397 0 : l = *getArgReference_bat(stk, pci, 1),
3398 0 : r = *getArgReference_bat(stk, pci, 2),
3399 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
3400 0 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3401 0 : BATiter bi;
3402 :
3403 0 : (void) cntxt;
3404 0 : (void) mb;
3405 0 : if (!buf) {
3406 0 : msg = createException(MAL, "batstr.repeat",
3407 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3408 0 : goto bailout;
3409 : }
3410 0 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
3411 0 : msg = createException(MAL, "batstr.repeat",
3412 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3413 0 : goto bailout;
3414 : }
3415 0 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
3416 0 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
3417 0 : msg = createException(MAL, "batstr.repeat",
3418 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3419 0 : goto bailout;
3420 : }
3421 0 : canditer_init(&ci1, left, lefts);
3422 0 : canditer_init(&ci2, right, rights);
3423 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3424 0 : msg = createException(MAL, "batstr.repeat",
3425 : ILLEGAL_ARGUMENT
3426 : " Requires bats of identical size");
3427 0 : goto bailout;
3428 : }
3429 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3430 0 : msg = createException(MAL, "batstr.repeat",
3431 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3432 0 : goto bailout;
3433 : }
3434 :
3435 0 : off1 = left->hseqbase;
3436 0 : off2 = right->hseqbase;
3437 0 : lefti = bat_iterator(left);
3438 0 : bi = bat_iterator(right);
3439 0 : righti = bi.base;
3440 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3441 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3442 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3443 0 : p2 = (canditer_next_dense(&ci2) - off2);
3444 0 : const char *x = BUNtvar(lefti, p1);
3445 0 : y = righti[p2];
3446 :
3447 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3448 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3449 0 : msg = createException(MAL, "batstr.repeat",
3450 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3451 0 : goto bailout1;
3452 : }
3453 : nils = true;
3454 : } else {
3455 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3456 0 : goto bailout1;
3457 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3458 0 : msg = createException(MAL, "batstr.repeat",
3459 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3460 0 : goto bailout1;
3461 : }
3462 : }
3463 : }
3464 : } else {
3465 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3466 0 : oid p1 = (canditer_next(&ci1) - off1),
3467 0 : p2 = (canditer_next(&ci2) - off2);
3468 0 : const char *x = BUNtvar(lefti, p1);
3469 0 : y = righti[p2];
3470 :
3471 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3472 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3473 0 : msg = createException(MAL, "batstr.repeat",
3474 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3475 0 : goto bailout1;
3476 : }
3477 : nils = true;
3478 : } else {
3479 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3480 0 : goto bailout1;
3481 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3482 0 : msg = createException(MAL, "batstr.repeat",
3483 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3484 0 : goto bailout1;
3485 : }
3486 : }
3487 : }
3488 : }
3489 0 : bailout1:
3490 0 : bat_iterator_end(&bi);
3491 0 : bat_iterator_end(&lefti);
3492 0 : bailout:
3493 0 : GDKfree(buf);
3494 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3495 0 : unfix_inputs(4, left, lefts, right, rights);
3496 0 : return msg;
3497 : }
3498 :
3499 : static str
3500 352 : STRbatSubstitutecst_imp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3501 : int cand_nargs, const bit *rep)
3502 : {
3503 352 : BATiter bi;
3504 352 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3505 352 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3506 352 : const char *y = *getArgReference_str(stk, pci, 2),
3507 352 : *z = *getArgReference_str(stk, pci, 3);
3508 352 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3509 352 : bool nils = false;
3510 352 : bit w = *rep;
3511 352 : struct canditer ci1 = { 0 };
3512 352 : oid off1;
3513 352 : bat *res = getArgReference_bat(stk, pci, 0),
3514 352 : bid = *getArgReference_bat(stk, pci, 1),
3515 352 : *sid1 = pci->argc == cand_nargs ? getArgReference_bat(stk, pci, cand_nargs - 1) : NULL;
3516 :
3517 352 : if (!buf) {
3518 0 : msg = createException(MAL, "batstr.substritute",
3519 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3520 0 : goto bailout;
3521 : }
3522 352 : if (!(b = BATdescriptor(bid))) {
3523 0 : msg = createException(MAL, "batstr.substritute",
3524 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3525 0 : goto bailout;
3526 : }
3527 352 : 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 352 : canditer_init(&ci1, b, bs);
3533 352 : 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 352 : (void) cntxt;
3540 352 : (void) mb;
3541 352 : off1 = b->hseqbase;
3542 352 : bi = bat_iterator(b);
3543 352 : if (ci1.tpe == cand_dense) {
3544 116982 : for (BUN i = 0; i < ci1.ncand; i++) {
3545 116630 : oid p1 = (canditer_next_dense(&ci1) - off1);
3546 116630 : const char *x = BUNtvar(bi, p1);
3547 :
3548 463880 : 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 115760 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3557 0 : goto bailout1;
3558 115726 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3559 0 : msg = createException(MAL, "batstr.substritute",
3560 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3561 0 : goto bailout1;
3562 : }
3563 : }
3564 : }
3565 : } else {
3566 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3567 0 : oid p1 = (canditer_next(&ci1) - off1);
3568 0 : const char *x = BUNtvar(bi, p1);
3569 :
3570 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3571 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3572 0 : msg = createException(MAL, "batstr.substritute",
3573 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3574 0 : goto bailout1;
3575 : }
3576 : nils = true;
3577 : } else {
3578 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3579 0 : goto bailout1;
3580 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3581 0 : msg = createException(MAL, "batstr.substritute",
3582 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3583 0 : goto bailout1;
3584 : }
3585 : }
3586 : }
3587 : }
3588 0 : bailout1:
3589 352 : bat_iterator_end(&bi);
3590 352 : bailout:
3591 352 : GDKfree(buf);
3592 352 : finalize_output(res, bn, msg, nils, ci1.ncand);
3593 351 : unfix_inputs(2, b, bs);
3594 352 : 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 352 : STRbatReplacecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4200 : {
4201 352 : bit rep = TRUE;
4202 :
4203 352 : return STRbatSubstitutecst_imp(cntxt, mb, stk, pci, 5, &rep);
4204 : }
4205 :
4206 : static str
4207 2 : STRbatReplace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4208 : {
4209 2 : BATiter arg1i, arg2i, arg3i;
4210 2 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL,
4211 2 : *arg2s = NULL, *arg3 = NULL, *arg3s = NULL;
4212 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4213 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4214 2 : bool nils = false;
4215 2 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
4216 2 : oid off1, off2, off3;
4217 2 : bat *res = getArgReference_bat(stk, pci, 0),
4218 2 : l = *getArgReference_bat(stk, pci, 1),
4219 2 : s = *getArgReference_bat(stk, pci, 2),
4220 2 : s2 = *getArgReference_bat(stk, pci, 3),
4221 2 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
4222 2 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
4223 2 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
4224 :
4225 2 : (void) cntxt;
4226 2 : (void) mb;
4227 2 : if (!buf) {
4228 0 : msg = createException(MAL, "batstr.replace",
4229 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4230 0 : goto bailout;
4231 : }
4232 2 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(s))
4233 2 : || !(arg3 = BATdescriptor(s2))) {
4234 0 : msg = createException(MAL, "batstr.replace",
4235 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4236 0 : goto bailout;
4237 : }
4238 2 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) ||
4239 2 : (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) ||
4240 0 : (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3))))
4241 : {
4242 0 : msg = createException(MAL, "batstr.replace",
4243 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4244 0 : goto bailout;
4245 : }
4246 2 : canditer_init(&ci1, arg1, arg1s);
4247 2 : canditer_init(&ci2, arg2, arg2s);
4248 2 : canditer_init(&ci3, arg3, arg3s);
4249 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4250 2 : || ci2.hseq != ci3.hseq) {
4251 0 : msg = createException(MAL, "batstr.replace",
4252 : ILLEGAL_ARGUMENT
4253 : " Requires bats of identical size");
4254 0 : goto bailout;
4255 : }
4256 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4257 0 : msg = createException(MAL, "batstr.replace",
4258 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4259 0 : goto bailout;
4260 : }
4261 :
4262 2 : off1 = arg1->hseqbase;
4263 2 : off2 = arg2->hseqbase;
4264 2 : off3 = arg3->hseqbase;
4265 2 : arg1i = bat_iterator(arg1);
4266 2 : arg2i = bat_iterator(arg2);
4267 2 : arg3i = bat_iterator(arg3);
4268 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
4269 6 : for (BUN i = 0; i < ci1.ncand; i++) {
4270 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
4271 4 : p2 = (canditer_next_dense(&ci2) - off2),
4272 4 : p3 = (canditer_next_dense(&ci3) - off3);
4273 4 : const char *x = BUNtvar(arg1i, p1);
4274 4 : const char *y = BUNtvar(arg2i, p2);
4275 4 : const char *z = BUNtvar(arg3i, p3);
4276 :
4277 12 : if (strNil(x) || strNil(y) || strNil(z)) {
4278 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4279 0 : msg = createException(MAL, "batstr.replace",
4280 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4281 0 : goto bailout1;
4282 : }
4283 : nils = true;
4284 : } else {
4285 4 : if ((msg = str_substitute(&buf, &buflen, x, y, z, TRUE)) != MAL_SUCCEED)
4286 0 : goto bailout1;
4287 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4288 0 : msg = createException(MAL, "batstr.replace",
4289 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4290 0 : goto bailout1;
4291 : }
4292 : }
4293 : }
4294 : } else {
4295 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4296 0 : oid p1 = (canditer_next(&ci1) - off1),
4297 0 : p2 = (canditer_next(&ci2) - off2),
4298 0 : p3 = (canditer_next(&ci3) - off3);
4299 0 : const char *x = BUNtvar(arg1i, p1);
4300 0 : const char *y = BUNtvar(arg2i, p2);
4301 0 : const char *z = BUNtvar(arg3i, p3);
4302 :
4303 0 : if (strNil(x) || strNil(y) || strNil(z)) {
4304 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4305 0 : msg = createException(MAL, "batstr.replace",
4306 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4307 0 : goto bailout1;
4308 : }
4309 : nils = true;
4310 : } else {
4311 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, TRUE)) != MAL_SUCCEED)
4312 0 : goto bailout1;
4313 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4314 0 : msg = createException(MAL, "batstr.replace",
4315 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4316 0 : goto bailout1;
4317 : }
4318 : }
4319 : }
4320 : }
4321 0 : bailout1:
4322 2 : bat_iterator_end(&arg1i);
4323 2 : bat_iterator_end(&arg2i);
4324 2 : bat_iterator_end(&arg3i);
4325 2 : bailout:
4326 2 : GDKfree(buf);
4327 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
4328 2 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
4329 2 : return msg;
4330 : }
4331 :
4332 : static str
4333 0 : STRbatInsert(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4334 : {
4335 0 : BATiter lefti, righti, starti, ncharsi;
4336 0 : BAT *bn = NULL, *left = NULL, *ls = NULL, *start = NULL,
4337 0 : *ss = NULL, *nchars = NULL, *ns = NULL, *right = NULL, *rs = NULL;
4338 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4339 0 : int *sval, *lval, y, z;
4340 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4341 0 : bool nils = false;
4342 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 }, ci4 = { 0 };
4343 0 : oid off1, off2, off3, off4;
4344 0 : bat *res = getArgReference_bat(stk, pci, 0),
4345 0 : l = *getArgReference_bat(stk, pci, 1),
4346 0 : s = *getArgReference_bat(stk, pci, 2),
4347 0 : chars = *getArgReference_bat(stk, pci, 3),
4348 0 : s2 = *getArgReference_bat(stk, pci, 4),
4349 0 : *sid1 = pci->argc == 9 ? getArgReference_bat(stk, pci, 5) : NULL,
4350 0 : *sid2 = pci->argc == 9 ? getArgReference_bat(stk, pci, 6) : NULL,
4351 0 : *sid3 = pci->argc == 9 ? getArgReference_bat(stk, pci, 7) : NULL,
4352 0 : *sid4 = pci->argc == 9 ? getArgReference_bat(stk, pci, 8) : NULL;
4353 :
4354 0 : (void) cntxt;
4355 0 : (void) mb;
4356 0 : if (!buf) {
4357 0 : msg = createException(MAL, "batstr.insert",
4358 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4359 0 : goto bailout;
4360 : }
4361 0 : if (!(left = BATdescriptor(l)) || !(start = BATdescriptor(s))
4362 0 : || !(nchars = BATdescriptor(chars)) || !(right = BATdescriptor(s2))) {
4363 0 : msg = createException(MAL, "batstr.insert",
4364 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4365 0 : goto bailout;
4366 : }
4367 0 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1)))
4368 0 : || (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))
4369 0 : || (sid3 && !is_bat_nil(*sid3) && !(ss = BATdescriptor(*sid3)))
4370 0 : || (sid4 && !is_bat_nil(*sid4) && !(ns = BATdescriptor(*sid4)))) {
4371 0 : msg = createException(MAL, "batstr.insert",
4372 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4373 0 : goto bailout;
4374 : }
4375 0 : canditer_init(&ci1, left, ls);
4376 0 : canditer_init(&ci2, start, ss);
4377 0 : canditer_init(&ci3, nchars, ns);
4378 0 : canditer_init(&ci4, right, rs);
4379 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4380 0 : || ci2.hseq != ci3.hseq || ci4.ncand != ci1.ncand
4381 0 : || ci3.hseq != ci4.hseq) {
4382 0 : msg = createException(MAL, "batstr.insert",
4383 : ILLEGAL_ARGUMENT
4384 : " Requires bats of identical size");
4385 0 : goto bailout;
4386 : }
4387 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4388 0 : msg = createException(MAL, "batstr.insert",
4389 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4390 0 : goto bailout;
4391 : }
4392 :
4393 0 : off1 = left->hseqbase;
4394 0 : off2 = start->hseqbase;
4395 0 : off3 = nchars->hseqbase;
4396 0 : off4 = right->hseqbase;
4397 0 : lefti = bat_iterator(left);
4398 0 : starti = bat_iterator(start);
4399 0 : ncharsi = bat_iterator(nchars);
4400 0 : sval = starti.base;
4401 0 : lval = ncharsi.base;
4402 0 : righti = bat_iterator(right);
4403 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense
4404 0 : && ci4.tpe == cand_dense) {
4405 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4406 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4407 0 : p2 = (canditer_next_dense(&ci2) - off2),
4408 0 : p3 = (canditer_next_dense(&ci3) - off3),
4409 0 : p4 = (canditer_next_dense(&ci4) - off4);
4410 0 : const char *x = BUNtvar(lefti, p1);
4411 0 : y = sval[p2];
4412 0 : z = lval[p3];
4413 0 : const char *w = BUNtvar(righti, p4);
4414 :
4415 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4416 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4417 0 : msg = createException(MAL, "batstr.insert",
4418 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4419 0 : goto bailout1;
4420 : }
4421 : nils = true;
4422 : } else {
4423 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4424 0 : goto bailout1;
4425 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4426 0 : msg = createException(MAL, "batstr.insert",
4427 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4428 0 : goto bailout1;
4429 : }
4430 : }
4431 : }
4432 : } else {
4433 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4434 0 : oid p1 = (canditer_next(&ci1) - off1),
4435 0 : p2 = (canditer_next(&ci2) - off2),
4436 0 : p3 = (canditer_next(&ci3) - off3),
4437 0 : p4 = (canditer_next(&ci4) - off4);
4438 0 : const char *x = BUNtvar(lefti, p1);
4439 0 : y = sval[p2];
4440 0 : z = lval[p3];
4441 0 : const char *w = BUNtvar(righti, p4);
4442 :
4443 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4444 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4445 0 : msg = createException(MAL, "batstr.insert",
4446 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4447 0 : goto bailout1;
4448 : }
4449 : nils = true;
4450 : } else {
4451 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4452 0 : goto bailout1;
4453 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4454 0 : msg = createException(MAL, "batstr.insert",
4455 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4456 0 : goto bailout1;
4457 : }
4458 : }
4459 : }
4460 : }
4461 0 : bailout1:
4462 0 : bat_iterator_end(&starti);
4463 0 : bat_iterator_end(&ncharsi);
4464 0 : bat_iterator_end(&lefti);
4465 0 : bat_iterator_end(&righti);
4466 0 : bailout:
4467 0 : GDKfree(buf);
4468 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4469 0 : unfix_inputs(8, left, ls, start, ss, nchars, ns, right, rs);
4470 0 : return msg;
4471 : }
4472 :
4473 : static str
4474 0 : STRbatInsertcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4475 : {
4476 0 : BATiter bi;
4477 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4478 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4479 0 : int y = *getArgReference_int(stk, pci, 2),
4480 0 : z = *getArgReference_int(stk, pci, 3);
4481 0 : const char *w = *getArgReference_str(stk, pci, 4);
4482 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4483 0 : bool nils = false;
4484 0 : struct canditer ci1 = { 0 };
4485 0 : oid off1;
4486 0 : bat *res = getArgReference_bat(stk, pci, 0),
4487 0 : bid = *getArgReference_bat(stk, pci, 1),
4488 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4489 :
4490 0 : (void) cntxt;
4491 0 : (void) mb;
4492 0 : if (!buf) {
4493 0 : msg = createException(MAL, "batstr.insert",
4494 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4495 0 : goto bailout;
4496 : }
4497 0 : if (!(b = BATdescriptor(bid))) {
4498 0 : msg = createException(MAL, "batstr.insert",
4499 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4500 0 : goto bailout;
4501 : }
4502 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4503 0 : msg = createException(MAL, "batstr.insert",
4504 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4505 0 : goto bailout;
4506 : }
4507 0 : canditer_init(&ci1, b, bs);
4508 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4509 0 : msg = createException(MAL, "batstr.insert",
4510 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4511 0 : goto bailout;
4512 : }
4513 :
4514 0 : off1 = b->hseqbase;
4515 0 : bi = bat_iterator(b);
4516 0 : if (ci1.tpe == cand_dense) {
4517 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4518 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
4519 0 : const char *x = BUNtvar(bi, p1);
4520 :
4521 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4522 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4523 0 : msg = createException(MAL, "batstr.insert",
4524 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4525 0 : goto bailout1;
4526 : }
4527 : nils = true;
4528 : } else {
4529 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4530 0 : goto bailout1;
4531 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4532 0 : msg = createException(MAL, "batstr.insert",
4533 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4534 0 : goto bailout1;
4535 : }
4536 : }
4537 : }
4538 : } else {
4539 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4540 0 : oid p1 = (canditer_next(&ci1) - off1);
4541 0 : const char *x = BUNtvar(bi, p1);
4542 :
4543 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4544 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4545 0 : msg = createException(MAL, "batstr.insert",
4546 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4547 0 : goto bailout1;
4548 : }
4549 : nils = true;
4550 : } else {
4551 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4552 0 : goto bailout1;
4553 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4554 0 : msg = createException(MAL, "batstr.insert",
4555 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4556 0 : goto bailout1;
4557 : }
4558 : }
4559 : }
4560 : }
4561 0 : bailout1:
4562 0 : bat_iterator_end(&bi);
4563 0 : bailout:
4564 0 : GDKfree(buf);
4565 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4566 0 : unfix_inputs(2, b, bs);
4567 0 : return msg;
4568 : }
4569 :
4570 : /*
4571 : * The substring functions require slightly different arguments
4572 : */
4573 : static str
4574 121 : STRbatsubstring_2nd_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4575 : InstrPtr pci)
4576 : {
4577 121 : BATiter bi;
4578 121 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4579 121 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4580 121 : int y = *getArgReference_int(stk, pci, 2),
4581 121 : z = *getArgReference_int(stk, pci, 3);
4582 121 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4583 123 : bool nils = false;
4584 123 : struct canditer ci1 = { 0 };
4585 123 : oid off1;
4586 123 : bat *res = getArgReference_bat(stk, pci, 0),
4587 123 : bid = *getArgReference_bat(stk, pci, 1),
4588 123 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4589 :
4590 123 : (void) cntxt;
4591 123 : (void) mb;
4592 123 : if (!buf) {
4593 0 : msg = createException(MAL, "batstr.substring",
4594 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4595 0 : goto bailout;
4596 : }
4597 123 : if (!(b = BATdescriptor(bid))) {
4598 0 : msg = createException(MAL, "batstr.substring",
4599 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4600 0 : goto bailout;
4601 : }
4602 123 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4603 0 : msg = createException(MAL, "batstr.substring",
4604 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4605 0 : goto bailout;
4606 : }
4607 123 : canditer_init(&ci1, b, bs);
4608 121 : 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 3722866 : for (BUN i = 0; i < ci1.ncand; i++) {
4618 3722743 : oid p1 = (canditer_next_dense(&ci1) - off1);
4619 3722743 : const char *x = BUNtvar(bi, p1);
4620 :
4621 7297673 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4622 97402 : 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 3601014 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4630 0 : goto bailout1;
4631 3708716 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4632 0 : msg = createException(MAL, "batstr.substring",
4633 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4634 0 : goto bailout1;
4635 : }
4636 : }
4637 : }
4638 : } else {
4639 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4640 0 : oid p1 = (canditer_next(&ci1) - off1);
4641 0 : const char *x = BUNtvar(bi, p1);
4642 :
4643 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4644 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4645 0 : msg = createException(MAL, "batstr.substring",
4646 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4647 0 : goto bailout1;
4648 : }
4649 : nils = true;
4650 : } else {
4651 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4652 0 : goto bailout1;
4653 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4654 0 : msg = createException(MAL, "batstr.substring",
4655 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4656 0 : goto bailout1;
4657 : }
4658 : }
4659 : }
4660 : }
4661 0 : bailout1:
4662 123 : bat_iterator_end(&bi);
4663 123 : bailout:
4664 123 : GDKfree(buf);
4665 123 : finalize_output(res, bn, msg, nils, ci1.ncand);
4666 123 : unfix_inputs(2, b, bs);
4667 123 : return msg;
4668 : }
4669 :
4670 : static str
4671 1 : STRbatsubstring_1st_2nd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4672 : InstrPtr pci)
4673 : {
4674 1 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4675 1 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4676 1 : int y = *getArgReference_int(stk, pci, 2), z, *restrict input;
4677 1 : const char *x = *getArgReference_str(stk, pci, 1);
4678 1 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4679 1 : bool nils = false;
4680 1 : struct canditer ci1 = { 0 };
4681 1 : oid off1;
4682 1 : bat *res = getArgReference_bat(stk, pci, 0),
4683 1 : bid = *getArgReference_bat(stk, pci, 3),
4684 1 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4685 1 : BATiter bi;
4686 :
4687 1 : (void) cntxt;
4688 1 : (void) mb;
4689 1 : if (!buf) {
4690 0 : msg = createException(MAL, "batstr.substring",
4691 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4692 0 : goto bailout;
4693 : }
4694 1 : if (!(b = BATdescriptor(bid))) {
4695 0 : msg = createException(MAL, "batstr.substring",
4696 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4697 0 : goto bailout;
4698 : }
4699 1 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4700 0 : msg = createException(MAL, "batstr.substring",
4701 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4702 0 : goto bailout;
4703 : }
4704 1 : canditer_init(&ci1, b, bs);
4705 1 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4706 0 : msg = createException(MAL, "batstr.substring",
4707 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4708 0 : goto bailout;
4709 : }
4710 :
4711 1 : off1 = b->hseqbase;
4712 1 : bi = bat_iterator(b);
4713 1 : input = bi.base;
4714 1 : if (ci1.tpe == cand_dense) {
4715 2 : for (BUN i = 0; i < ci1.ncand; i++) {
4716 1 : oid p1 = (canditer_next_dense(&ci1) - off1);
4717 1 : z = input[p1];
4718 :
4719 2 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4720 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4721 0 : msg = createException(MAL, "batstr.substring",
4722 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4723 0 : goto bailout1;
4724 : }
4725 : nils = true;
4726 : } else {
4727 1 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4728 0 : goto bailout1;
4729 1 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4730 0 : msg = createException(MAL, "batstr.substring",
4731 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4732 0 : goto bailout1;
4733 : }
4734 : }
4735 : }
4736 : } else {
4737 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4738 0 : oid p1 = (canditer_next(&ci1) - off1);
4739 0 : z = input[p1];
4740 :
4741 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4742 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4743 0 : msg = createException(MAL, "batstr.substring",
4744 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4745 0 : goto bailout1;
4746 : }
4747 : nils = true;
4748 : } else {
4749 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4750 0 : goto bailout1;
4751 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4752 0 : msg = createException(MAL, "batstr.substring",
4753 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4754 0 : goto bailout1;
4755 : }
4756 : }
4757 : }
4758 : }
4759 0 : bailout1:
4760 1 : bat_iterator_end(&bi);
4761 1 : bailout:
4762 1 : GDKfree(buf);
4763 1 : finalize_output(res, bn, msg, nils, ci1.ncand);
4764 1 : unfix_inputs(2, b, bs);
4765 1 : return msg;
4766 : }
4767 :
4768 : static str
4769 5 : STRbatsubstring_1st_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4770 : InstrPtr pci)
4771 : {
4772 5 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4773 5 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4774 5 : int y, z = *getArgReference_int(stk, pci, 3), *restrict input;
4775 5 : const char *x = *getArgReference_str(stk, pci, 1);
4776 5 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4777 5 : bool nils = false;
4778 5 : struct canditer ci1 = { 0 };
4779 5 : oid off1;
4780 5 : bat *res = getArgReference_bat(stk, pci, 0),
4781 5 : bid = *getArgReference_bat(stk, pci, 2),
4782 5 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4783 5 : BATiter bi;
4784 :
4785 5 : (void) cntxt;
4786 5 : (void) mb;
4787 5 : if (!buf) {
4788 0 : msg = createException(MAL, "batstr.substring",
4789 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4790 0 : goto bailout;
4791 : }
4792 5 : if (!(b = BATdescriptor(bid))) {
4793 0 : msg = createException(MAL, "batstr.substring",
4794 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4795 0 : goto bailout;
4796 : }
4797 5 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4798 0 : msg = createException(MAL, "batstr.substring",
4799 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4800 0 : goto bailout;
4801 : }
4802 5 : canditer_init(&ci1, b, bs);
4803 5 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4804 0 : msg = createException(MAL, "batstr.substring",
4805 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4806 0 : goto bailout;
4807 : }
4808 :
4809 5 : off1 = b->hseqbase;
4810 5 : bi = bat_iterator(b);
4811 5 : input = bi.base;
4812 5 : if (ci1.tpe == cand_dense) {
4813 9 : for (BUN i = 0; i < ci1.ncand; i++) {
4814 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
4815 4 : y = input[p1];
4816 :
4817 8 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4818 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4819 0 : msg = createException(MAL, "batstr.substring",
4820 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4821 0 : goto bailout1;
4822 : }
4823 : nils = true;
4824 : } else {
4825 4 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4826 0 : goto bailout1;
4827 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4828 0 : msg = createException(MAL, "batstr.substring",
4829 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4830 0 : goto bailout1;
4831 : }
4832 : }
4833 : }
4834 : } else {
4835 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4836 0 : oid p1 = (canditer_next(&ci1) - off1);
4837 0 : y = input[p1];
4838 :
4839 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4840 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4841 0 : msg = createException(MAL, "batstr.substring",
4842 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4843 0 : goto bailout1;
4844 : }
4845 : nils = true;
4846 : } else {
4847 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4848 0 : goto bailout1;
4849 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4850 0 : msg = createException(MAL, "batstr.substring",
4851 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4852 0 : goto bailout1;
4853 : }
4854 : }
4855 : }
4856 : }
4857 0 : bailout1:
4858 5 : bat_iterator_end(&bi);
4859 5 : bailout:
4860 5 : GDKfree(buf);
4861 5 : finalize_output(res, bn, msg, nils, ci1.ncand);
4862 5 : unfix_inputs(2, b, bs);
4863 5 : return msg;
4864 : }
4865 :
4866 : static str
4867 4 : STRbatsubstring_1st_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4868 : {
4869 4 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
4870 4 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4871 4 : int y, z, *vals1, *vals2;
4872 4 : const char *x = *getArgReference_str(stk, pci, 1);
4873 4 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4874 4 : bool nils = false;
4875 4 : struct canditer ci1 = { 0 }, ci2 = { 0 };
4876 4 : oid off1, off2;
4877 4 : bat *res = getArgReference_bat(stk, pci, 0),
4878 4 : bid = *getArgReference_bat(stk, pci, 2),
4879 4 : l = *getArgReference_bat(stk, pci, 3),
4880 4 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
4881 4 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4882 4 : BATiter bi;
4883 4 : BATiter lbi;
4884 :
4885 4 : (void) cntxt;
4886 4 : (void) mb;
4887 4 : if (!buf) {
4888 0 : msg = createException(MAL, "batstr.substring",
4889 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4890 0 : goto bailout;
4891 : }
4892 4 : if (!(b = BATdescriptor(bid)) || !(lb = BATdescriptor(l))) {
4893 0 : msg = createException(MAL, "batstr.substring",
4894 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4895 0 : goto bailout;
4896 : }
4897 4 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
4898 4 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
4899 0 : msg = createException(MAL, "batstr.substring",
4900 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4901 0 : goto bailout;
4902 : }
4903 4 : canditer_init(&ci1, b, bs);
4904 4 : canditer_init(&ci2, lb, lbs);
4905 4 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
4906 0 : msg = createException(MAL, "batstr.substring",
4907 : ILLEGAL_ARGUMENT
4908 : " Requires bats of identical size");
4909 0 : goto bailout;
4910 : }
4911 4 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4912 0 : msg = createException(MAL, "batstr.substring",
4913 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4914 0 : goto bailout;
4915 : }
4916 :
4917 4 : off1 = b->hseqbase;
4918 4 : off2 = lb->hseqbase;
4919 4 : bi = bat_iterator(b);
4920 4 : lbi = bat_iterator(lb);
4921 4 : vals1 = bi.base;
4922 4 : vals2 = lbi.base;
4923 4 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
4924 12 : for (BUN i = 0; i < ci1.ncand; i++) {
4925 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
4926 8 : p2 = (canditer_next_dense(&ci2) - off2);
4927 8 : y = vals1[p1];
4928 8 : z = vals2[p2];
4929 :
4930 16 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4931 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4932 0 : msg = createException(MAL, "batstr.substring",
4933 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4934 0 : goto bailout1;
4935 : }
4936 : nils = true;
4937 : } else {
4938 8 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4939 0 : goto bailout1;
4940 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4941 0 : msg = createException(MAL, "batstr.substring",
4942 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4943 0 : goto bailout1;
4944 : }
4945 : }
4946 : }
4947 : } else {
4948 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4949 0 : oid p1 = (canditer_next(&ci1) - off1),
4950 0 : p2 = (canditer_next(&ci2) - off2);
4951 0 : y = vals1[p1];
4952 0 : z = vals2[p2];
4953 :
4954 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4955 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4956 0 : msg = createException(MAL, "batstr.substring",
4957 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4958 0 : goto bailout1;
4959 : }
4960 : nils = true;
4961 : } else {
4962 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4963 0 : goto bailout1;
4964 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4965 0 : msg = createException(MAL, "batstr.substring",
4966 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4967 0 : goto bailout1;
4968 : }
4969 : }
4970 : }
4971 : }
4972 0 : bailout1:
4973 4 : bat_iterator_end(&bi);
4974 4 : bat_iterator_end(&lbi);
4975 4 : bailout:
4976 4 : GDKfree(buf);
4977 4 : finalize_output(res, bn, msg, nils, ci1.ncand);
4978 4 : unfix_inputs(4, b, bs, lb, lbs);
4979 4 : return msg;
4980 : }
4981 :
4982 : static str
4983 32 : STRbatsubstring_2nd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4984 : {
4985 32 : BATiter bi;
4986 32 : BATiter lbi;
4987 32 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
4988 32 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4989 32 : int y = *getArgReference_int(stk, pci, 2), *len, z;
4990 32 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4991 31 : bool nils = false;
4992 31 : struct canditer ci1 = { 0 }, ci2 = { 0 };
4993 31 : oid off1, off2;
4994 31 : bat *res = getArgReference_bat(stk, pci, 0),
4995 31 : bid = *getArgReference_bat(stk, pci, 1),
4996 31 : l = *getArgReference_bat(stk, pci, 3),
4997 31 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
4998 31 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4999 :
5000 31 : (void) cntxt;
5001 31 : (void) mb;
5002 31 : if (!buf) {
5003 0 : msg = createException(MAL, "batstr.substring",
5004 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5005 0 : goto bailout;
5006 : }
5007 31 : if (!(b = BATdescriptor(bid)) || !(lb = BATdescriptor(l))) {
5008 0 : msg = createException(MAL, "batstr.substring",
5009 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5010 0 : goto bailout;
5011 : }
5012 32 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
5013 32 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
5014 0 : msg = createException(MAL, "batstr.substring",
5015 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5016 0 : goto bailout;
5017 : }
5018 32 : canditer_init(&ci1, b, bs);
5019 32 : canditer_init(&ci2, lb, lbs);
5020 32 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5021 0 : msg = createException(MAL, "batstr.substring",
5022 : ILLEGAL_ARGUMENT
5023 : " Requires bats of identical size");
5024 0 : goto bailout;
5025 : }
5026 32 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5027 0 : msg = createException(MAL, "batstr.substring",
5028 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5029 0 : goto bailout;
5030 : }
5031 :
5032 32 : off1 = b->hseqbase;
5033 32 : off2 = lb->hseqbase;
5034 32 : bi = bat_iterator(b);
5035 32 : lbi = bat_iterator(lb);
5036 32 : len = lbi.base;
5037 32 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5038 36 : for (BUN i = 0; i < ci1.ncand; i++) {
5039 5 : oid p1 = (canditer_next_dense(&ci1) - off1),
5040 5 : p2 = (canditer_next_dense(&ci2) - off2);
5041 5 : const char *x = BUNtvar(bi, p1);
5042 4 : z = len[p2];
5043 :
5044 8 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5045 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5046 0 : msg = createException(MAL, "batstr.substring",
5047 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5048 0 : goto bailout1;
5049 : }
5050 : nils = true;
5051 : } else {
5052 4 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5053 0 : goto bailout1;
5054 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5055 0 : msg = createException(MAL, "batstr.substring",
5056 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5057 0 : goto bailout1;
5058 : }
5059 : }
5060 : }
5061 : } else {
5062 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5063 0 : oid p1 = (canditer_next(&ci1) - off1),
5064 0 : p2 = (canditer_next(&ci2) - off2);
5065 0 : const char *x = BUNtvar(bi, p1);
5066 0 : z = len[p2];
5067 :
5068 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5069 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5070 0 : msg = createException(MAL, "batstr.substring",
5071 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5072 0 : goto bailout1;
5073 : }
5074 : nils = true;
5075 : } else {
5076 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5077 0 : goto bailout1;
5078 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5079 0 : msg = createException(MAL, "batstr.substring",
5080 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5081 0 : goto bailout1;
5082 : }
5083 : }
5084 : }
5085 : }
5086 0 : bailout1:
5087 31 : bat_iterator_end(&lbi);
5088 32 : bat_iterator_end(&bi);
5089 32 : bailout:
5090 32 : GDKfree(buf);
5091 32 : finalize_output(res, bn, msg, nils, ci1.ncand);
5092 32 : unfix_inputs(4, b, bs, lb, lbs);
5093 32 : return msg;
5094 : }
5095 :
5096 : static str
5097 0 : STRbatsubstring_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5098 : {
5099 0 : BATiter bi, lbi;
5100 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
5101 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
5102 0 : int *start, y, z = *getArgReference_int(stk, pci, 3);
5103 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
5104 0 : bool nils = false;
5105 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
5106 0 : oid off1, off2;
5107 0 : bat *res = getArgReference_bat(stk, pci, 0),
5108 0 : bid = *getArgReference_bat(stk, pci, 1),
5109 0 : l = *getArgReference_bat(stk, pci, 2),
5110 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
5111 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
5112 :
5113 0 : (void) cntxt;
5114 0 : (void) mb;
5115 0 : if (!buf) {
5116 0 : msg = createException(MAL, "batstr.substring",
5117 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5118 0 : goto bailout;
5119 : }
5120 0 : if (!(b = BATdescriptor(bid)) || !(lb = BATdescriptor(l))) {
5121 0 : msg = createException(MAL, "batstr.substring",
5122 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5123 0 : goto bailout;
5124 : }
5125 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
5126 0 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
5127 0 : msg = createException(MAL, "batstr.substring",
5128 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5129 0 : goto bailout;
5130 : }
5131 0 : canditer_init(&ci1, b, bs);
5132 0 : canditer_init(&ci2, lb, lbs);
5133 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5134 0 : msg = createException(MAL, "batstr.substring",
5135 : ILLEGAL_ARGUMENT
5136 : " Requires bats of identical size");
5137 0 : goto bailout;
5138 : }
5139 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5140 0 : msg = createException(MAL, "batstr.substring",
5141 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5142 0 : goto bailout;
5143 : }
5144 :
5145 0 : off1 = b->hseqbase;
5146 0 : off2 = lb->hseqbase;
5147 0 : bi = bat_iterator(b);
5148 0 : lbi = bat_iterator(lb);
5149 0 : start = lbi.base;
5150 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5151 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5152 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
5153 0 : p2 = (canditer_next_dense(&ci2) - off2);
5154 0 : const char *x = BUNtvar(bi, p1);
5155 0 : y = start[p2];
5156 :
5157 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5158 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5159 0 : msg = createException(MAL, "batstr.substring",
5160 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5161 0 : goto bailout1;
5162 : }
5163 : nils = true;
5164 : } else {
5165 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5166 0 : goto bailout1;
5167 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5168 0 : msg = createException(MAL, "batstr.substring",
5169 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5170 0 : goto bailout1;
5171 : }
5172 : }
5173 : }
5174 : } else {
5175 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5176 0 : oid p1 = (canditer_next(&ci1) - off1),
5177 0 : p2 = (canditer_next(&ci2) - off2);
5178 0 : const char *x = BUNtvar(bi, p1);
5179 0 : y = start[p2];
5180 :
5181 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5182 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5183 0 : msg = createException(MAL, "batstr.substring",
5184 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5185 0 : goto bailout1;
5186 : }
5187 : nils = true;
5188 : } else {
5189 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5190 0 : goto bailout1;
5191 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5192 0 : msg = createException(MAL, "batstr.substring",
5193 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5194 0 : goto bailout1;
5195 : }
5196 : }
5197 : }
5198 : }
5199 0 : bailout1:
5200 0 : bat_iterator_end(&lbi);
5201 0 : bat_iterator_end(&bi);
5202 0 : bailout:
5203 0 : GDKfree(buf);
5204 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5205 0 : unfix_inputs(4, b, bs, lb, lbs);
5206 0 : return msg;
5207 : }
5208 :
5209 : static str
5210 27 : STRbatsubstring(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5211 : {
5212 27 : BATiter lefti, starti, lengthi;
5213 27 : BAT *bn = NULL, *left = NULL, *ls = NULL, *start = NULL,
5214 27 : *ss = NULL, *length = NULL, *lens = NULL;
5215 27 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
5216 27 : int *svals, *lvals, y, z;
5217 27 : 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 3794 : for (BUN i = 0; i < ci1.ncand; i++) {
5275 3766 : oid p1 = (canditer_next_dense(&ci1) - off1),
5276 3766 : p2 = (canditer_next_dense(&ci2) - off2),
5277 3766 : p3 = (canditer_next_dense(&ci3) - off3);
5278 3766 : const char *x = BUNtvar(lefti, p1);
5279 3764 : y = svals[p2];
5280 3764 : z = lvals[p3];
5281 :
5282 7498 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5283 47 : 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 3717 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5291 0 : goto bailout1;
5292 3637 : 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 3640 : for (BUN i = 0; i < ci1.ncand; i++) {
5445 3588 : oid p1 = (canditer_next_dense(&ci1) - off1);
5446 3588 : const char *y = BUNtvar(bi, p1);
5447 :
5448 7172 : if (strNil(x) || strNil(y)) {
5449 0 : vals[i] = int_nil;
5450 0 : nils = true;
5451 : } else {
5452 3586 : vals[i] = str_locate2(x, y, 1);
5453 : }
5454 : }
5455 : } else {
5456 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5457 0 : oid p1 = (canditer_next(&ci1) - off1);
5458 0 : const char *y = BUNtvar(bi, p1);
5459 :
5460 0 : if (strNil(x) || strNil(y)) {
5461 0 : vals[i] = int_nil;
5462 0 : nils = true;
5463 : } else {
5464 0 : vals[i] = str_locate2(x, y, 1);
5465 : }
5466 : }
5467 : }
5468 52 : bat_iterator_end(&bi);
5469 52 : bailout:
5470 52 : finalize_output(res, bn, msg, nils, ci1.ncand);
5471 52 : unfix_inputs(2, b, bs);
5472 52 : return msg;
5473 : }
5474 :
5475 : static str
5476 2 : STRbatstrLocate(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5477 : {
5478 2 : BATiter lefti, righti;
5479 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
5480 2 : int *restrict vals;
5481 2 : str msg = MAL_SUCCEED;
5482 2 : bool nils = false;
5483 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
5484 2 : oid off1, off2;
5485 2 : bat *res = getArgReference_bat(stk, pci, 0),
5486 2 : l = *getArgReference_bat(stk, pci, 1),
5487 2 : r = *getArgReference_bat(stk, pci, 2),
5488 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
5489 2 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
5490 :
5491 2 : (void) cntxt;
5492 2 : (void) mb;
5493 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
5494 0 : msg = createException(MAL, "batstr.locate",
5495 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5496 0 : goto bailout;
5497 : }
5498 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5499 2 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
5500 0 : msg = createException(MAL, "batstr.locate",
5501 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5502 0 : goto bailout;
5503 : }
5504 2 : canditer_init(&ci1, left, ls);
5505 2 : canditer_init(&ci2, right, rs);
5506 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5507 0 : msg = createException(MAL, "batstr.locate",
5508 : ILLEGAL_ARGUMENT
5509 : " Requires bats of identical size");
5510 0 : goto bailout;
5511 : }
5512 2 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5513 0 : msg = createException(MAL, "batstr.locate",
5514 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5515 0 : goto bailout;
5516 : }
5517 :
5518 2 : off1 = left->hseqbase;
5519 2 : off2 = right->hseqbase;
5520 2 : lefti = bat_iterator(left);
5521 2 : righti = bat_iterator(right);
5522 2 : vals = Tloc(bn, 0);
5523 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5524 10 : for (BUN i = 0; i < ci1.ncand; i++) {
5525 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
5526 8 : p2 = (canditer_next_dense(&ci2) - off2);
5527 8 : const char *x = BUNtvar(lefti, p1);
5528 8 : const char *y = BUNtvar(righti, p2);
5529 :
5530 16 : if (strNil(x) || strNil(y)) {
5531 0 : vals[i] = int_nil;
5532 0 : nils = true;
5533 : } else {
5534 8 : vals[i] = str_locate2(x, y, 1);
5535 : }
5536 : }
5537 : } else {
5538 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5539 0 : oid p1 = (canditer_next(&ci1) - off1),
5540 0 : p2 = (canditer_next(&ci2) - off2);
5541 0 : const char *x = BUNtvar(lefti, p1);
5542 0 : const char *y = BUNtvar(righti, p2);
5543 :
5544 0 : if (strNil(x) || strNil(y)) {
5545 0 : vals[i] = int_nil;
5546 0 : nils = true;
5547 : } else {
5548 0 : vals[i] = str_locate2(x, y, 1);
5549 : }
5550 : }
5551 : }
5552 2 : bat_iterator_end(&lefti);
5553 2 : bat_iterator_end(&righti);
5554 2 : bailout:
5555 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
5556 2 : unfix_inputs(4, left, ls, right, rs);
5557 2 : return msg;
5558 : }
5559 :
5560 : static str
5561 0 : STRbatstrLocate3cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5562 : {
5563 0 : BATiter bi;
5564 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
5565 0 : int *restrict vals, z = *getArgReference_int(stk, pci, 3);
5566 0 : const char *y = *getArgReference_str(stk, pci, 2);
5567 0 : str msg = MAL_SUCCEED;
5568 0 : bool nils = false;
5569 0 : struct canditer ci1 = { 0 };
5570 0 : oid off1;
5571 0 : bat *res = getArgReference_bat(stk, pci, 0),
5572 0 : l = *getArgReference_bat(stk, pci, 1),
5573 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
5574 :
5575 0 : (void) cntxt;
5576 0 : (void) mb;
5577 0 : if (!(b = BATdescriptor(l))) {
5578 0 : msg = createException(MAL, "batstr.locate2",
5579 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5580 0 : goto bailout;
5581 : }
5582 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
5583 0 : msg = createException(MAL, "batstr.locate2",
5584 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5585 0 : goto bailout;
5586 : }
5587 0 : canditer_init(&ci1, b, bs);
5588 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5589 0 : msg = createException(MAL, "batstr.locate2",
5590 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5591 0 : goto bailout;
5592 : }
5593 :
5594 0 : off1 = b->hseqbase;
5595 0 : bi = bat_iterator(b);
5596 0 : vals = Tloc(bn, 0);
5597 0 : if (ci1.tpe == cand_dense) {
5598 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5599 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
5600 0 : const char *x = BUNtvar(bi, p1);
5601 :
5602 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5603 0 : vals[i] = int_nil;
5604 0 : nils = true;
5605 : } else {
5606 0 : vals[i] = str_locate2(x, y, z);
5607 : }
5608 : }
5609 : } else {
5610 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5611 0 : oid p1 = (canditer_next(&ci1) - off1);
5612 0 : const char *x = BUNtvar(bi, p1);
5613 :
5614 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5615 0 : vals[i] = int_nil;
5616 0 : nils = true;
5617 : } else {
5618 0 : vals[i] = str_locate2(x, y, z);
5619 : }
5620 : }
5621 : }
5622 0 : bat_iterator_end(&bi);
5623 0 : bailout:
5624 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5625 0 : unfix_inputs(2, b, bs);
5626 0 : return msg;
5627 : }
5628 :
5629 : static str
5630 0 : STRbatstrLocate3(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5631 : {
5632 0 : BATiter lefti, righti, starti;
5633 0 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL,
5634 0 : *rs = NULL, *start = NULL, *ss = NULL;
5635 0 : int *restrict vals, *restrict svals, z;
5636 0 : str msg = MAL_SUCCEED;
5637 0 : bool nils = false;
5638 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
5639 0 : oid off1, off2, off3;
5640 0 : bat *res = getArgReference_bat(stk, pci, 0),
5641 0 : l = *getArgReference_bat(stk, pci, 1),
5642 0 : r = *getArgReference_bat(stk, pci, 2),
5643 0 : s = *getArgReference_bat(stk, pci, 3),
5644 0 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
5645 0 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
5646 0 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
5647 :
5648 0 : (void) cntxt;
5649 0 : (void) mb;
5650 0 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))
5651 0 : || !(start = BATdescriptor(s))) {
5652 0 : msg = createException(MAL, "batstr.locate2",
5653 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5654 0 : goto bailout;
5655 : }
5656 0 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5657 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2))) ||
5658 0 : (sid3 && !is_bat_nil(*sid3) && !(ss = BATdescriptor(*sid3)))) {
5659 0 : msg = createException(MAL, "batstr.locate2",
5660 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5661 0 : goto bailout;
5662 : }
5663 0 : canditer_init(&ci1, left, ls);
5664 0 : canditer_init(&ci2, right, rs);
5665 0 : canditer_init(&ci3, start, ss);
5666 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
5667 0 : || ci2.hseq != ci3.hseq) {
5668 0 : msg = createException(MAL, "batstr.locate2",
5669 : ILLEGAL_ARGUMENT
5670 : " Requires bats of identical size");
5671 0 : goto bailout;
5672 : }
5673 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5674 0 : msg = createException(MAL, "batstr.locate2",
5675 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5676 0 : goto bailout;
5677 : }
5678 :
5679 0 : off1 = left->hseqbase;
5680 0 : off2 = right->hseqbase;
5681 0 : off3 = start->hseqbase;
5682 0 : lefti = bat_iterator(left);
5683 0 : righti = bat_iterator(right);
5684 0 : starti = bat_iterator(start);
5685 0 : svals = starti.base;
5686 0 : vals = Tloc(bn, 0);
5687 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
5688 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5689 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
5690 0 : p2 = (canditer_next_dense(&ci2) - off2),
5691 0 : p3 = (canditer_next_dense(&ci3) - off3);
5692 0 : const char *x = BUNtvar(lefti, p1);
5693 0 : const char *y = BUNtvar(righti, p2);
5694 0 : z = svals[p3];
5695 :
5696 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5697 0 : vals[i] = int_nil;
5698 0 : nils = true;
5699 : } else {
5700 0 : vals[i] = str_locate2(x, y, z);
5701 : }
5702 : }
5703 : } else {
5704 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5705 0 : oid p1 = (canditer_next(&ci1) - off1),
5706 0 : p2 = (canditer_next(&ci2) - off2),
5707 0 : p3 = (canditer_next(&ci3) - off3);
5708 0 : const char *x = BUNtvar(lefti, p1);
5709 0 : const char *y = BUNtvar(righti, p2);
5710 0 : z = svals[p3];
5711 :
5712 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5713 0 : vals[i] = int_nil;
5714 0 : nils = true;
5715 : } else {
5716 0 : vals[i] = str_locate2(x, y, z);
5717 : }
5718 : }
5719 : }
5720 0 : bat_iterator_end(&starti);
5721 0 : bat_iterator_end(&lefti);
5722 0 : bat_iterator_end(&righti);
5723 0 : bailout:
5724 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5725 0 : unfix_inputs(6, left, ls, right, rs, start, ss);
5726 0 : return msg;
5727 : }
5728 :
5729 : static str
5730 34 : BATSTRasciify(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5731 : {
5732 34 : return STRbatConvert(cntxt, mb, stk, pci, BATasciify, "batstr.asciify");
5733 : }
5734 :
5735 : #include "mel.h"
5736 : mel_func batstr_init_funcs[] = {
5737 : pattern("batstr", "length", STRbatLength, false, "Return the length of a string.", args(1,2, batarg("",int),batarg("s",str))),
5738 : pattern("batstr", "length", STRbatLength, false, "Return the length of a string.", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5739 : pattern("batstr", "nbytes", STRbatBytes, false, "Return the string length in bytes.", args(1,2, batarg("",int),batarg("s",str))),
5740 : pattern("batstr", "nbytes", STRbatBytes, false, "Return the string length in bytes.", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5741 : pattern("batstr", "toLower", STRbatLower, false, "Convert a string to lower case.", args(1,2, batarg("",str),batarg("s",str))),
5742 : pattern("batstr", "toLower", STRbatLower, false, "Convert a string to lower case.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5743 : pattern("batstr", "toUpper", STRbatUpper, false, "Convert a string to upper case.", args(1,2, batarg("",str),batarg("s",str))),
5744 : pattern("batstr", "toUpper", STRbatUpper, false, "Convert a string to upper case.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5745 : pattern("batstr", "caseFold", STRbatCaseFold, false, "Fold the case of a string.", args(1,2, batarg("",str),batarg("s",str))),
5746 : pattern("batstr", "caseFold", STRbatCaseFold, false, "Fold the case of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5747 : pattern("batstr", "trim", STRbatStrip, false, "Strip whitespaces around a string.", args(1,2, batarg("",str),batarg("s",str))),
5748 : pattern("batstr", "trim", STRbatStrip, false, "Strip whitespaces around a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5749 : pattern("batstr", "ltrim", STRbatLtrim, false, "Strip whitespaces from start of a string.", args(1,2, batarg("",str),batarg("s",str))),
5750 : pattern("batstr", "ltrim", STRbatLtrim, false, "Strip whitespaces from start of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5751 : pattern("batstr", "rtrim", STRbatRtrim, false, "Strip whitespaces from end of a string.", args(1,2, batarg("",str),batarg("s",str))),
5752 : pattern("batstr", "rtrim", STRbatRtrim, false, "Strip whitespaces from end of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5753 : pattern("batstr", "trim2", STRbatStrip2_const, false, "Strip characters in the second string around the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5754 : pattern("batstr", "trim2", STRbatStrip2_const, false, "Strip characters in the second string around the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5755 : pattern("batstr", "trim2", STRbatStrip2_1st_const, false, "Strip characters in the second string around the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5756 : pattern("batstr", "trim2", STRbatStrip2_1st_const, false, "Strip characters in the second string around the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5757 : pattern("batstr", "ltrim2", STRbatLtrim2_const, false, "Strip characters in the second string from start of the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5758 : pattern("batstr", "ltrim2", STRbatLtrim2_const, false, "Strip characters in the second string from start of the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5759 : pattern("batstr", "ltrim2", STRbatLtrim2_1st_const, false, "Strip characters in the second string from start of the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5760 : pattern("batstr", "ltrim2", STRbatLtrim2_1st_const, false, "Strip characters in the second string from start of the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5761 : pattern("batstr", "rtrim2", STRbatRtrim2_const, false, "Strip characters in the second string from end of the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5762 : pattern("batstr", "rtrim2", STRbatRtrim2_const, false, "Strip characters in the second string from end of the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5763 : pattern("batstr", "rtrim2", STRbatRtrim2_1st_const, false, "Strip characters in the second string from end of the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5764 : pattern("batstr", "rtrim2", STRbatRtrim2_1st_const, false, "Strip characters in the second string from end of the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5765 : pattern("batstr", "trim2", STRbatStrip2_bat, false, "Strip characters in the second strings around the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5766 : pattern("batstr", "trim2", STRbatStrip2_bat, false, "Strip characters in the second strings around the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5767 : pattern("batstr", "ltrim2", STRbatLtrim2_bat, false, "Strip characters in the second strings from start of the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5768 : pattern("batstr", "ltrim2", STRbatLtrim2_bat, false, "Strip characters in the second strings from start of the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5769 : pattern("batstr", "rtrim2", STRbatRtrim2_bat, false, "Strip characters in the second strings from end of the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5770 : pattern("batstr", "rtrim2", STRbatRtrim2_bat, false, "Strip characters in the second strings from end of the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5771 : pattern("batstr", "lpad", STRbatLpad_const, false, "Prepend whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,3, batarg("",str),batarg("s",str),arg("n",int))),
5772 : pattern("batstr", "lpad", STRbatLpad_const, false, "Prepend whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s",oid))),
5773 : pattern("batstr", "rpad", STRbatRpad_const, false, "Append whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,3, batarg("",str),batarg("s",str),arg("n",int))),
5774 : pattern("batstr", "rpad", STRbatRpad_const, false, "Append whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s",oid))),
5775 : pattern("batstr", "lpad", STRbatLpad_1st_const, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),arg("s",str),batarg("n",int))),
5776 : pattern("batstr", "lpad", STRbatLpad_1st_const, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),arg("s",str),batarg("n",int),batarg("s",oid))),
5777 : pattern("batstr", "rpad", STRbatRpad_1st_const, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),arg("s",str),batarg("n",int))),
5778 : pattern("batstr", "rpad", STRbatRpad_1st_const, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),arg("s",str),batarg("n",int),batarg("s",oid))),
5779 : pattern("batstr", "lpad", STRbatLpad_bat, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),batarg("s",str),batarg("n",int))),
5780 : pattern("batstr", "lpad", STRbatLpad_bat, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,5, batarg("",str),batarg("s",str),batarg("n",int),batarg("s1",oid),batarg("s2",oid))),
5781 : pattern("batstr", "rpad", STRbatRpad_bat, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),batarg("s",str),batarg("n",int))),
5782 : pattern("batstr", "rpad", STRbatRpad_bat, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,5, batarg("",str),batarg("s",str),batarg("n",int),batarg("s1",oid),batarg("s2",oid))),
5783 : pattern("batstr", "lpad3", STRbatLpad3_const_const, false, "Prepend the second string to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),arg("s2",str))),
5784 : pattern("batstr", "rpad3", STRbatRpad3_const_const, false, "Append the second string to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),arg("s2",str))),
5785 : pattern("batstr", "lpad3", STRbatLpad3_bat_const, false, "Prepend the second string to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),arg("s2",str))),
5786 : pattern("batstr", "rpad3", STRbatRpad3_bat_const, false, "Append the second string to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),arg("s2",str))),
5787 : pattern("batstr", "lpad3", STRbatLpad3_const_bat, false, "Prepend the second strings to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s2",str))),
5788 : pattern("batstr", "rpad3", STRbatRpad3_const_bat, false, "Append the second strings to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s2",str))),
5789 : pattern("batstr", "lpad3", STRbatLpad3_bat_bat, false, "Prepend the second strings to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),batarg("s2",str))),
5790 : pattern("batstr", "rpad3", STRbatRpad3_bat_bat, false, "Append the second strings to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),batarg("s2",str))),
5791 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5792 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5793 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5794 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5795 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string starts with substring.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5796 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string starts with substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5797 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string(with CL) starts with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5798 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string(with CL) starts with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5799 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5800 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5801 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring(with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5802 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring(with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5803 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5804 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5805 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5806 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5807 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string ends with substring.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5808 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string ends with substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5809 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string(with CL) ends with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5810 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string(with CL) ends with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5811 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5812 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5813 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring(with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5814 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring(with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5815 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5816 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5817 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5818 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5819 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5820 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5821 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle (with CL) ends with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5822 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle (with CL) ends with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5823 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5824 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5825 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle (with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5826 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle (with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5827 : pattern("batstr", "splitpart", STRbatsplitpart, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),batarg("needle",str),batarg("field",int))),
5828 : pattern("batstr", "splitpart", STRbatsplitpartcst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),arg("needle",str),arg("field",int))),
5829 : pattern("batstr", "splitpart", STRbatsplitpart_needlecst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),arg("needle",str),batarg("field",int))),
5830 : pattern("batstr", "splitpart", STRbatsplitpart_fieldcst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),batarg("needle",str),arg("field",int))),
5831 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),batarg("c",str))),
5832 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit))),
5833 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),batarg("c",str),batarg("s1",oid),batarg("s2",oid))),
5834 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,6, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5835 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),arg("c",str))),
5836 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit))),
5837 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),batarg("s",oid))),
5838 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,5, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit),batarg("s",oid))),
5839 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),arg("s",str),batarg("c",str))),
5840 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit))),
5841 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),batarg("s",oid))),
5842 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,5, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit),batarg("s",oid))),
5843 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),batarg("c",str))),
5844 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit))),
5845 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring (with CLs). Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),batarg("c",str),batarg("s1",oid),batarg("s2",oid))),
5846 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring (with CLs) + icase flag. Returns position, -1 if not found.", args(1,6, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5847 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),arg("c",str))),
5848 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit))),
5849 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring (with CL). Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),batarg("s",oid))),
5850 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring (with CL) + icase flag. Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit),batarg("s",oid))),
5851 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),arg("s",str),batarg("c",str))),
5852 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit))),
5853 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring (with CL). Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),batarg("s",oid))),
5854 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring (with CL) + icase flag. Returns position, -1 if not found.", args(1,5, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit),batarg("s",oid))),
5855 : pattern("batstr", "string", STRbatTail, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),batarg("b",str),batarg("offset",int))),
5856 : pattern("batstr", "string", STRbatTail, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,5, batarg("",str),batarg("b",str),batarg("offset",int),batarg("s1",oid),batarg("s2",oid))),
5857 : pattern("batstr", "string", STRbatTailcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),batarg("b",str),arg("offset",int))),
5858 : pattern("batstr", "string", STRbatTailcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,4, batarg("",str),batarg("b",str),arg("offset",int),batarg("s",oid))),
5859 : pattern("batstr", "string", STRbatTail_strcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),arg("b",str),batarg("offset",int))),
5860 : pattern("batstr", "string", STRbatTail_strcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,4, batarg("",str),arg("b",str),batarg("offset",int),batarg("s",oid))),
5861 : pattern("batstr", "ascii", STRbatAscii, false, "Return unicode of head of string", args(1,2, batarg("",int),batarg("s",str))),
5862 : pattern("batstr", "ascii", STRbatAscii, false, "Return unicode of head of string", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5863 : pattern("batstr", "substring", STRbatsubstringTail, false, "Extract the tail of a string", args(1,3, batarg("",str),batarg("s",str),batarg("start",int))),
5864 : pattern("batstr", "substring", STRbatsubstringTail, false, "Extract the tail of a string", args(1,5, batarg("",str),batarg("s",str),batarg("start",int),batarg("s1",oid),batarg("s2",oid))),
5865 : pattern("batstr", "substring", STRbatsubstringTailcst, false, "Extract the tail of a string", args(1,3, batarg("",str),batarg("s",str),arg("start",int))),
5866 : pattern("batstr", "substring", STRbatsubstringTailcst, false, "Extract the tail of a string", args(1,4, batarg("",str),batarg("s",str),arg("start",int),batarg("s",oid))),
5867 : pattern("batstr", "substring", STRbatsubstringTail_strcst, false, "Extract the tail of a string", args(1,3, batarg("",str),arg("s",str),batarg("start",int))),
5868 : pattern("batstr", "substring", STRbatsubstringTail_strcst, false, "Extract the tail of a string", args(1,4, batarg("",str),arg("s",str),batarg("start",int),batarg("s",oid))),
5869 : pattern("batstr", "substring3", STRbatsubstring, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),batarg("start",int),batarg("index",int))),
5870 : pattern("batstr", "substring3", STRbatsubstring, false, "Substring extraction using [start,start+length]", args(1,7, batarg("",str),batarg("s",str),batarg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid),batarg("s3",oid))),
5871 : pattern("batstr", "substring3", STRbatsubstring_2nd_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),arg("start",int),arg("index",int))),
5872 : pattern("batstr", "substring3", STRbatsubstring_2nd_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),batarg("s",str),arg("start",int),arg("index",int),batarg("s",oid))),
5873 : pattern("batstr", "substring3", STRbatsubstring_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),arg("start",int),batarg("index",int))),
5874 : pattern("batstr", "substring3", STRbatsubstring_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),batarg("s",str),arg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5875 : pattern("batstr", "substring3", STRbatsubstring_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),batarg("start",int),arg("index",int))),
5876 : pattern("batstr", "substring3", STRbatsubstring_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),batarg("s",str),batarg("start",int),arg("index",int),batarg("s1",oid),batarg("s2",oid))),
5877 : pattern("batstr", "substring3", STRbatsubstring_1st_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),arg("start",int),batarg("index",int))),
5878 : pattern("batstr", "substring3", STRbatsubstring_1st_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),arg("s",str),arg("start",int),batarg("index",int),batarg("s",oid))),
5879 : pattern("batstr", "substring3", STRbatsubstring_1st_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),batarg("start",int),arg("index",int))),
5880 : pattern("batstr", "substring3", STRbatsubstring_1st_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),arg("s",str),batarg("start",int),arg("index",int),batarg("s",oid))),
5881 : pattern("batstr", "substring3", STRbatsubstring_1st_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),batarg("start",int),batarg("index",int))),
5882 : pattern("batstr", "substring3", STRbatsubstring_1st_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),arg("s",str),batarg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5883 : pattern("batstr", "unicode", STRbatFromWChr, false, "convert a unicode to a character.", args(1,2, batarg("",str),batarg("wchar",int))),
5884 : pattern("batstr", "unicode", STRbatFromWChr, false, "convert a unicode to a character.", args(1,3, batarg("",str),batarg("wchar",int),batarg("s",oid))),
5885 : pattern("batstr", "unicodeAt", STRbatWChrAt, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),batarg("s",str),batarg("index",int))),
5886 : pattern("batstr", "unicodeAt", STRbatWChrAt, false, "get a unicode character (as an int) from a string position.", args(1,5, batarg("",int),batarg("s",str),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5887 : pattern("batstr", "unicodeAt", STRbatWChrAtcst, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),batarg("s",str),arg("index",int))),
5888 : pattern("batstr", "unicodeAt", STRbatWChrAtcst, false, "get a unicode character (as an int) from a string position.", args(1,4, batarg("",int),batarg("s",str),arg("index",int),batarg("s",oid))),
5889 : pattern("batstr", "unicodeAt", STRbatWChrAt_strcst, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),arg("s",str),batarg("index",int))),
5890 : pattern("batstr", "unicodeAt", STRbatWChrAt_strcst, false, "get a unicode character (as an int) from a string position.", args(1,4, batarg("",int),arg("s",str),batarg("index",int),batarg("s",oid))),
5891 : pattern("batstr", "substitute", STRbatSubstitute, false, "Substitute first occurrence of 'src' by\n'dst'. Iff repeated = true this is\nrepeated while 'src' can be found in the\nresult string. In order to prevent\nrecursion and result strings of unlimited\nsize, repeating is only done iff src is\nnot a substring of dst.", args(1,5, batarg("",str),batarg("s",str),batarg("src",str),batarg("dst",str),batarg("rep",bit))),
5892 : pattern("batstr", "substitute", STRbatSubstitutecst, false, "Substitute first occurrence of 'src' by\n'dst'. Iff repeated = true this is\nrepeated while 'src' can be found in the\nresult string. In order to prevent\nrecursion and result strings of unlimited\nsize, repeating is only done iff src is\nnot a substring of dst.", args(1,5, batarg("",str),batarg("s",str),arg("src",str),arg("dst",str),arg("rep",bit))),
5893 : pattern("batstr", "stringleft", STRbatprefix, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("l",int))),
5894 : pattern("batstr", "stringleft", STRbatprefix, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("l",int),batarg("s1",oid),batarg("s2",oid))),
5895 : pattern("batstr", "stringleft", STRbatprefixcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("l",int))),
5896 : pattern("batstr", "stringleft", STRbatprefixcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("l",int),batarg("s",oid))),
5897 : pattern("batstr", "stringleft", STRbatprefix_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("l",int))),
5898 : pattern("batstr", "stringleft", STRbatprefix_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("l",int),batarg("s",oid))),
5899 : pattern("batstr", "stringright", STRbatsuffix, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("l",int))),
5900 : pattern("batstr", "stringright", STRbatsuffix, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("l",int),batarg("s1",oid),batarg("s2",oid))),
5901 : pattern("batstr", "stringright", STRbatsuffixcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("l",int))),
5902 : pattern("batstr", "stringright", STRbatsuffixcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("l",int),batarg("s",oid))),
5903 : pattern("batstr", "stringright", STRbatsuffix_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("l",int))),
5904 : pattern("batstr", "stringright", STRbatsuffix_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("l",int),batarg("s",oid))),
5905 : pattern("batstr", "locate", STRbatstrLocate, false, "Locate the start position of a string", args(1,3, batarg("",int),batarg("s1",str),batarg("s2",str))),
5906 : pattern("batstr", "locate", STRbatstrLocate, false, "Locate the start position of a string", args(1,5, batarg("",int),batarg("s1",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5907 : pattern("batstr", "locate", STRbatstrLocatecst, false, "Locate the start position of a string", args(1,3, batarg("",int),batarg("s1",str),arg("s2",str))),
5908 : pattern("batstr", "locate", STRbatstrLocatecst, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),arg("s2",str),batarg("s",oid))),
5909 : pattern("batstr", "locate", STRbatstrLocate_strcst, false, "Locate the start position of a string", args(1,3, batarg("",int),arg("s1",str),batarg("s2",str))),
5910 : pattern("batstr", "locate", STRbatstrLocate_strcst, false, "Locate the start position of a string", args(1,4, batarg("",int),arg("s1",str),batarg("s2",str),batarg("s",oid))),
5911 : pattern("batstr", "locate3", STRbatstrLocate3, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),batarg("s2",str),batarg("start",int))),
5912 : pattern("batstr", "locate3", STRbatstrLocate3cst, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),arg("s2",str),arg("start",int))),
5913 : pattern("batstr", "insert", STRbatInsert, false, "Insert a string into another", args(1,5, batarg("",str),batarg("s",str),batarg("start",int),batarg("l",int),batarg("s2",str))),
5914 : pattern("batstr", "insert", STRbatInsertcst, false, "Insert a string into another", args(1,5, batarg("",str),batarg("s",str),arg("start",int),arg("l",int),arg("s2",str))),
5915 : pattern("batstr", "replace", STRbatReplace, false, "Insert a string into another", args(1,4, batarg("",str),batarg("s",str),batarg("pat",str),batarg("s2",str))),
5916 : pattern("batstr", "replace", STRbatReplacecst, false, "Insert a string into another", args(1,4, batarg("",str),batarg("s",str),arg("pat",str),arg("s2",str))),
5917 : pattern("batstr", "repeat", STRbatrepeat, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("c",int))),
5918 : pattern("batstr", "repeat", STRbatrepeat, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("c",int),batarg("s1",oid),batarg("s2",oid))),
5919 : pattern("batstr", "repeat", STRbatrepeatcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("c",int))),
5920 : pattern("batstr", "repeat", STRbatrepeatcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("c",int),batarg("s",oid))),
5921 : pattern("batstr", "repeat", STRbatrepeat_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("c",int))),
5922 : pattern("batstr", "repeat", STRbatrepeat_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("c",int),batarg("s",oid))),
5923 : pattern("batstr", "space", STRbatSpace, false, "", args(1,2, batarg("",str),batarg("l",int))),
5924 : pattern("batstr", "space", STRbatSpace, false, "", args(1,3, batarg("",str),batarg("l",int),batarg("s",oid))),
5925 : pattern("batstr", "asciify", BATSTRasciify, false, "Transform BAT of strings from UTF8 to ASCII", args(1, 2, batarg("",str), batarg("b",str))),
5926 : pattern("batstr", "asciify", BATSTRasciify, false, "Transform BAT of strings from UTF8 to ASCII", args(1, 3, batarg("",str), batarg("b",str),batarg("s",oid))),
5927 : { .imp=NULL }
5928 : };
5929 : #include "mal_import.h"
5930 : #ifdef _MSC_VER
5931 : #undef read
5932 : #pragma section(".CRT$XCU",read)
5933 : #endif
5934 321 : LIB_STARTUP_FUNC(init_batstr_mal)
5935 321 : { mal_module("batstr", NULL, batstr_init_funcs); }
|