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, 2025 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 932 : batstr_func_has_candidates(const char *func)
33 : {
34 7442 : for (size_t i = 0; batstr_funcs_with_no_cands[i]; i++)
35 6522 : if (strcmp(batstr_funcs_with_no_cands[i], func) == 0)
36 : return false;
37 : return true;
38 : }
39 :
40 : static inline void
41 4889 : finalize_output(bat *res, BAT *bn, const char *msg, bool nils, BUN q)
42 : {
43 4889 : if (bn && !msg) {
44 4889 : BATsetcount(bn, q);
45 4886 : bn->tnil = nils;
46 4886 : bn->tnonil = !nils;
47 4886 : bn->tkey = BATcount(bn) <= 1;
48 4886 : bn->tsorted = BATcount(bn) <= 1;
49 4886 : bn->trevsorted = BATcount(bn) <= 1;
50 4886 : bn->theap->dirty |= BATcount(bn) > 0;
51 4886 : *res = bn->batCacheid;
52 4886 : BBPkeepref(bn);
53 0 : } else if (bn)
54 0 : BBPreclaim(bn);
55 4891 : }
56 :
57 : static void
58 5043 : unfix_inputs(int nargs, ...)
59 : {
60 5043 : va_list valist;
61 :
62 5043 : va_start(valist, nargs);
63 15472 : for (int i = 0; i < nargs; i++) {
64 10417 : BAT *b = va_arg(valist, BAT *);
65 16754 : BBPreclaim(b);
66 : }
67 5055 : va_end(valist);
68 5055 : }
69 :
70 : static inline str
71 5654 : str_prefix(str *buf, size_t *buflen, const char *s, int l)
72 : {
73 5654 : return str_Sub_String(buf, buflen, s, 0, l);
74 : }
75 :
76 : static str
77 3873 : do_batstr_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
78 : const char *name, int (*func)(const char *))
79 : {
80 3873 : BATiter bi;
81 3873 : BAT *bn = NULL, *b = NULL, *bs = NULL;
82 3873 : int *restrict vals;
83 3873 : str msg = MAL_SUCCEED;
84 3873 : bool nils = false;
85 3873 : struct canditer ci1 = { 0 };
86 3873 : oid off1;
87 3873 : bat *res = getArgReference_bat(stk, pci, 0),
88 3873 : bid = *getArgReference_bat(stk, pci, 1),
89 3873 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
90 :
91 3873 : (void) cntxt;
92 3873 : (void) mb;
93 3873 : if (!(b = BATdescriptor(bid))) {
94 0 : msg = createException(MAL, name,
95 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
96 0 : goto bailout;
97 : }
98 3878 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
99 0 : msg = createException(MAL, name,
100 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
101 0 : goto bailout;
102 : }
103 3879 : canditer_init(&ci1, b, bs);
104 3873 : 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 3879 : off1 = b->hseqbase;
110 3879 : bi = bat_iterator(b);
111 3878 : vals = Tloc(bn, 0);
112 3878 : if (ci1.tpe == cand_dense) {
113 1766839 : for (BUN i = 0; i < ci1.ncand; i++) {
114 1763010 : oid p1 = (canditer_next_dense(&ci1) - off1);
115 1763010 : const char *restrict x = BUNtvar(bi, p1);
116 :
117 1763010 : if (strNil(x)) {
118 3 : vals[i] = int_nil;
119 3 : nils = true;
120 : } else {
121 1763007 : vals[i] = func(x);
122 : }
123 : }
124 : } else {
125 1622524 : for (BUN i = 0; i < ci1.ncand; i++) {
126 1622484 : oid p1 = (canditer_next(&ci1) - off1);
127 1622190 : const char *restrict x = BUNtvar(bi, p1);
128 :
129 1622190 : if (strNil(x)) {
130 0 : vals[i] = int_nil;
131 0 : nils = true;
132 : } else {
133 1622190 : vals[i] = func(x);
134 : }
135 : }
136 : }
137 3869 : bat_iterator_end(&bi);
138 3878 : bailout:
139 3878 : finalize_output(res, bn, msg, nils, ci1.ncand);
140 3878 : unfix_inputs(2, b, bs);
141 3879 : return msg;
142 : }
143 :
144 : static str
145 3870 : STRbatLength(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
146 : {
147 3870 : bat bid = *getArgReference_bat(stk, pci, 1);
148 3870 : BAT *b = BATdescriptor(bid);
149 3878 : str err;
150 3878 : if (b && b->tascii)
151 3872 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.bytes", str_strlen);
152 : else
153 6 : err = do_batstr_int(cntxt, mb, stk, pci, "batstr.length", UTF8_strlen);
154 3876 : BBPreclaim(b);
155 3876 : 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 49 : bool nils = false;
433 49 : struct canditer ci1 = { 0 };
434 49 : oid off1;
435 49 : bat *res = getArgReference_bat(stk, pci, 0),
436 49 : bid = *getArgReference_bat(stk, pci, 1),
437 49 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
438 :
439 49 : (void) cntxt;
440 49 : (void) mb;
441 49 : if (!buf) {
442 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
443 0 : goto bailout;
444 : }
445 49 : if (!(b = BATdescriptor(bid))) {
446 0 : msg = createException(MAL, name,
447 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
448 0 : goto bailout;
449 : }
450 49 : 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 49 : 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 49 : off1 = b->hseqbase;
462 49 : bi = bat_iterator(b);
463 50 : if (ci1.tpe == cand_dense) {
464 419 : for (BUN i = 0; i < ci1.ncand; i++) {
465 369 : oid p1 = (canditer_next_dense(&ci1) - off1);
466 369 : const char *restrict x = BUNtvar(bi, p1);
467 :
468 369 : 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 364 : 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 1 : for (BUN i = 0; i < ci1.ncand; i++) {
487 1 : oid p1 = (canditer_next(&ci1) - off1);
488 0 : const char *restrict x = BUNtvar(bi, p1);
489 :
490 0 : if (strNil(x)) {
491 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
492 0 : msg = createException(MAL, name,
493 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
494 0 : goto bailout1;
495 : }
496 : nils = true;
497 : } else {
498 0 : if ((msg = (*func) (&buf, &buflen, x)) != MAL_SUCCEED)
499 0 : goto bailout1;
500 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
501 0 : msg = createException(MAL, name,
502 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
503 0 : goto bailout1;
504 : }
505 : }
506 : }
507 : }
508 0 : bailout1:
509 50 : bat_iterator_end(&bi);
510 50 : bailout:
511 50 : GDKfree(buf);
512 50 : finalize_output(res, bn, msg, nils, ci1.ncand);
513 50 : unfix_inputs(2, b, bs);
514 50 : return msg;
515 : }
516 :
517 : /* Input: a BAT of strings 'b' and a constant string 'y'
518 : * Output type: str (a BAT of strings)
519 : */
520 : static str
521 11 : do_batstr_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
522 : const char *name, size_t buflen,
523 : str (*func)(str *, size_t *, const char *, const char *))
524 : {
525 11 : BATiter bi;
526 11 : BAT *bn = NULL, *b = NULL, *bs = NULL;
527 11 : const char *y = *getArgReference_str(stk, pci, 2);
528 11 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
529 11 : bool nils = false;
530 11 : struct canditer ci1 = { 0 };
531 11 : oid off1;
532 11 : bat *res = getArgReference_bat(stk, pci, 0),
533 11 : bid = *getArgReference_bat(stk, pci, 1),
534 11 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
535 :
536 11 : (void) cntxt;
537 11 : (void) mb;
538 11 : if (!buf) {
539 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
540 0 : goto bailout;
541 : }
542 11 : if (!(b = BATdescriptor(bid))) {
543 0 : msg = createException(MAL, name,
544 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
545 0 : goto bailout;
546 : }
547 11 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
548 0 : msg = createException(MAL, name,
549 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
550 0 : goto bailout;
551 : }
552 11 : canditer_init(&ci1, b, bs);
553 11 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
554 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
555 0 : goto bailout;
556 : }
557 :
558 11 : off1 = b->hseqbase;
559 11 : bi = bat_iterator(b);
560 11 : if (ci1.tpe == cand_dense) {
561 29 : for (BUN i = 0; i < ci1.ncand; i++) {
562 18 : oid p1 = (canditer_next_dense(&ci1) - off1);
563 18 : const char *x = BUNtvar(bi, p1);
564 :
565 36 : if (strNil(x) || strNil(y)) {
566 9 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
567 0 : msg = createException(MAL, name,
568 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
569 0 : goto bailout1;
570 : }
571 : nils = true;
572 : } else {
573 9 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
574 0 : goto bailout1;
575 9 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
576 0 : msg = createException(MAL, name,
577 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
578 0 : goto bailout1;
579 : }
580 : }
581 : }
582 : } else {
583 0 : for (BUN i = 0; i < ci1.ncand; i++) {
584 0 : oid p1 = (canditer_next(&ci1) - off1);
585 0 : const char *x = BUNtvar(bi, p1);
586 :
587 0 : if (strNil(x) || strNil(y)) {
588 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
589 0 : msg = createException(MAL, name,
590 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
591 0 : goto bailout1;
592 : }
593 : nils = true;
594 : } else {
595 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
596 0 : goto bailout1;
597 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
598 0 : msg = createException(MAL, name,
599 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
600 0 : goto bailout1;
601 : }
602 : }
603 : }
604 : }
605 0 : bailout1:
606 11 : bat_iterator_end(&bi);
607 11 : bailout:
608 11 : GDKfree(buf);
609 11 : finalize_output(res, bn, msg, nils, ci1.ncand);
610 11 : unfix_inputs(2, b, bs);
611 11 : return msg;
612 : }
613 :
614 : /* Input: a const string 'x' and a BAT of strings 'y'
615 : * Output type: str (a BAT of strings)
616 : */
617 : static str
618 0 : do_batstr_str_conststr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
619 : const char *name, size_t buflen,
620 : str (*func)(str *, size_t *, const char *, const char *))
621 : {
622 0 : BATiter bi;
623 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
624 0 : const char *x = *getArgReference_str(stk, pci, 1);
625 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
626 0 : bool nils = false;
627 0 : struct canditer ci1 = { 0 };
628 0 : oid off1;
629 0 : bat *res = getArgReference_bat(stk, pci, 0),
630 0 : bid = *getArgReference_bat(stk, pci, 2),
631 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
632 :
633 0 : (void) cntxt;
634 0 : (void) mb;
635 0 : if (!buf) {
636 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
637 0 : goto bailout;
638 : }
639 0 : if (!(b = BATdescriptor(bid))) {
640 0 : msg = createException(MAL, name,
641 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
642 0 : goto bailout;
643 : }
644 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
645 0 : msg = createException(MAL, name,
646 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
647 0 : goto bailout;
648 : }
649 0 : canditer_init(&ci1, b, bs);
650 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
651 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
652 0 : goto bailout;
653 : }
654 :
655 0 : off1 = b->hseqbase;
656 0 : bi = bat_iterator(b);
657 0 : if (ci1.tpe == cand_dense) {
658 0 : for (BUN i = 0; i < ci1.ncand; i++) {
659 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
660 0 : const char *y = BUNtvar(bi, p1);
661 :
662 0 : if (strNil(x) || strNil(y)) {
663 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
664 0 : msg = createException(MAL, name,
665 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
666 0 : goto bailout1;
667 : }
668 : nils = true;
669 : } else {
670 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
671 0 : goto bailout1;
672 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
673 0 : msg = createException(MAL, name,
674 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
675 0 : goto bailout1;
676 : }
677 : }
678 : }
679 : } else {
680 0 : for (BUN i = 0; i < ci1.ncand; i++) {
681 0 : oid p1 = (canditer_next(&ci1) - off1);
682 0 : const char *y = BUNtvar(bi, p1);
683 :
684 0 : if (strNil(x) || strNil(y)) {
685 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
686 0 : msg = createException(MAL, name,
687 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
688 0 : goto bailout1;
689 : }
690 : nils = true;
691 : } else {
692 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
693 0 : goto bailout1;
694 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
695 0 : msg = createException(MAL, name,
696 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
697 0 : goto bailout1;
698 : }
699 : }
700 : }
701 : }
702 0 : bailout1:
703 0 : bat_iterator_end(&bi);
704 0 : bailout:
705 0 : GDKfree(buf);
706 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
707 0 : unfix_inputs(2, b, bs);
708 0 : return msg;
709 : }
710 :
711 : /* Input: two BATs of strings 'l' and 'l2'
712 : * Output type: str (a BAT of strings)
713 : */
714 : static str
715 3 : do_batstr_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
716 : const char *name, size_t buflen,
717 : str (*func)(str *, size_t *, const char *, const char *))
718 : {
719 3 : BATiter lefti, righti;
720 3 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
721 3 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
722 3 : bool nils = false;
723 3 : struct canditer ci1 = { 0 }, ci2 = { 0 };
724 3 : oid off1, off2;
725 3 : bat *res = getArgReference_bat(stk, pci, 0),
726 3 : l = *getArgReference_bat(stk, pci, 1),
727 3 : l2 = *getArgReference_bat(stk, pci, 2),
728 3 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
729 3 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
730 :
731 3 : (void) cntxt;
732 3 : (void) mb;
733 3 : if (!buf) {
734 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
735 0 : goto bailout;
736 : }
737 3 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(l2))) {
738 0 : msg = createException(MAL, name,
739 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
740 0 : goto bailout;
741 : }
742 3 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
743 3 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
744 0 : msg = createException(MAL, name,
745 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
746 0 : goto bailout;
747 : }
748 3 : canditer_init(&ci1, left, lefts);
749 3 : canditer_init(&ci2, right, rights);
750 3 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
751 0 : msg = createException(MAL, name,
752 : ILLEGAL_ARGUMENT
753 : " Requires bats of identical size");
754 0 : goto bailout;
755 : }
756 3 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
757 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
758 0 : goto bailout;
759 : }
760 :
761 3 : off1 = left->hseqbase;
762 3 : off2 = right->hseqbase;
763 3 : lefti = bat_iterator(left);
764 3 : righti = bat_iterator(right);
765 3 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
766 12 : for (BUN i = 0; i < ci1.ncand; i++) {
767 9 : oid p1 = (canditer_next_dense(&ci1) - off1),
768 9 : p2 = (canditer_next_dense(&ci2) - off2);
769 9 : const char *x = BUNtvar(lefti, p1);
770 9 : const char *y = BUNtvar(righti, p2);
771 :
772 18 : if (strNil(x) || strNil(y)) {
773 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
774 0 : msg = createException(MAL, name,
775 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
776 0 : goto bailout1;
777 : }
778 : nils = true;
779 : } else {
780 9 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
781 0 : goto bailout1;
782 9 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
783 0 : msg = createException(MAL, name,
784 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
785 0 : goto bailout1;
786 : }
787 : }
788 : }
789 : } else {
790 0 : for (BUN i = 0; i < ci1.ncand; i++) {
791 0 : oid p1 = (canditer_next(&ci1) - off1),
792 0 : p2 = (canditer_next(&ci2) - off2);
793 0 : const char *x = BUNtvar(lefti, p1);
794 0 : const char *y = BUNtvar(righti, p2);
795 :
796 0 : if (strNil(x) || strNil(y)) {
797 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
798 0 : msg = createException(MAL, name,
799 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
800 0 : goto bailout1;
801 : }
802 : nils = true;
803 : } else {
804 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
805 0 : goto bailout1;
806 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
807 0 : msg = createException(MAL, name,
808 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
809 0 : goto bailout1;
810 : }
811 : }
812 : }
813 : }
814 0 : bailout1:
815 3 : bat_iterator_end(&lefti);
816 3 : bat_iterator_end(&righti);
817 3 : bailout:
818 3 : GDKfree(buf);
819 3 : finalize_output(res, bn, msg, nils, ci1.ncand);
820 3 : unfix_inputs(4, left, lefts, right, rights);
821 3 : return msg;
822 : }
823 :
824 : /* Input: a BAT of strings 'l' and a constant int 'y'
825 : * Output type: str (a BAT of strings)
826 : */
827 : static str
828 2 : do_batstr_constint_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
829 : const char *name,
830 : str (*func)(str *, size_t *, const char *, int))
831 : {
832 2 : BATiter bi;
833 2 : BAT *bn = NULL, *b = NULL, *bs = NULL;
834 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
835 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
836 2 : int y = *getArgReference_int(stk, pci, 2);
837 2 : bool nils = false;
838 2 : struct canditer ci1 = { 0 };
839 2 : oid off1;
840 2 : bat *res = getArgReference_bat(stk, pci, 0),
841 2 : bid = *getArgReference_bat(stk, pci, 1),
842 2 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
843 :
844 2 : (void) cntxt;
845 2 : (void) mb;
846 2 : if (!buf) {
847 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
848 0 : goto bailout;
849 : }
850 2 : if (!(b = BATdescriptor(bid))) {
851 0 : msg = createException(MAL, name,
852 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
853 0 : goto bailout;
854 : }
855 2 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
856 0 : msg = createException(MAL, name,
857 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
858 0 : goto bailout;
859 : }
860 2 : canditer_init(&ci1, b, bs);
861 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
862 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
863 0 : goto bailout;
864 : }
865 :
866 2 : off1 = b->hseqbase;
867 2 : bi = bat_iterator(b);
868 2 : if (ci1.tpe == cand_dense) {
869 6 : for (BUN i = 0; i < ci1.ncand; i++) {
870 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
871 4 : const char *x = BUNtvar(bi, p1);
872 :
873 8 : if (strNil(x) || is_int_nil(y)) {
874 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
875 0 : msg = createException(MAL, name,
876 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
877 0 : goto bailout1;
878 : }
879 : nils = true;
880 : } else {
881 4 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
882 0 : goto bailout1;
883 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
884 0 : msg = createException(MAL, name,
885 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
886 0 : goto bailout1;
887 : }
888 : }
889 : }
890 : } else {
891 0 : for (BUN i = 0; i < ci1.ncand; i++) {
892 0 : oid p1 = (canditer_next(&ci1) - off1);
893 0 : const char *x = BUNtvar(bi, p1);
894 :
895 0 : if (strNil(x) || is_int_nil(y)) {
896 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
897 0 : msg = createException(MAL, name,
898 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
899 0 : goto bailout1;
900 : }
901 : nils = true;
902 : } else {
903 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
904 0 : goto bailout1;
905 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
906 0 : msg = createException(MAL, name,
907 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
908 0 : goto bailout1;
909 : }
910 : }
911 : }
912 : }
913 0 : bailout1:
914 2 : bat_iterator_end(&bi);
915 2 : bailout:
916 2 : GDKfree(buf);
917 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
918 2 : unfix_inputs(2, b, bs);
919 2 : return msg;
920 : }
921 :
922 : /* Input: a constant string 'x' and a BAT of integers 'y'
923 : * Output type: str (a BAT of strings)
924 : */
925 : static str
926 0 : do_batstr_int_conststr(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
927 : const char *name,
928 : str (*func)(str *, size_t *, const char *, int))
929 : {
930 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
931 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
932 0 : const char *x = *getArgReference_str(stk, pci, 1);
933 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
934 0 : int y, *restrict inputs;
935 0 : bool nils = false;
936 0 : struct canditer ci1 = { 0 };
937 0 : oid off1;
938 0 : bat *res = getArgReference_bat(stk, pci, 0),
939 0 : bid = *getArgReference_bat(stk, pci, 2),
940 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
941 0 : BATiter bi;
942 :
943 0 : (void) cntxt;
944 0 : (void) mb;
945 0 : if (!buf) {
946 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
947 0 : goto bailout;
948 : }
949 0 : if (!(b = BATdescriptor(bid))) {
950 0 : msg = createException(MAL, name,
951 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
952 0 : goto bailout;
953 : }
954 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
955 0 : msg = createException(MAL, name,
956 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
957 0 : goto bailout;
958 : }
959 0 : canditer_init(&ci1, b, bs);
960 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
961 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
962 0 : goto bailout;
963 : }
964 :
965 0 : off1 = b->hseqbase;
966 0 : bi = bat_iterator(b);
967 0 : inputs = bi.base;
968 0 : if (ci1.tpe == cand_dense) {
969 0 : for (BUN i = 0; i < ci1.ncand; i++) {
970 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
971 0 : y = inputs[p1];
972 :
973 0 : if (strNil(x) || is_int_nil(y)) {
974 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
975 0 : msg = createException(MAL, name,
976 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
977 0 : goto bailout1;
978 : }
979 : nils = true;
980 : } else {
981 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
982 0 : goto bailout1;
983 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
984 0 : msg = createException(MAL, name,
985 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
986 0 : goto bailout1;
987 : }
988 : }
989 : }
990 : } else {
991 0 : for (BUN i = 0; i < ci1.ncand; i++) {
992 0 : oid p1 = (canditer_next(&ci1) - off1);
993 0 : y = inputs[p1];
994 :
995 0 : if (strNil(x) || is_int_nil(y)) {
996 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
997 0 : msg = createException(MAL, name,
998 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
999 0 : goto bailout1;
1000 : }
1001 : nils = true;
1002 : } else {
1003 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1004 0 : goto bailout1;
1005 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1006 0 : msg = createException(MAL, name,
1007 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1008 0 : goto bailout1;
1009 : }
1010 : }
1011 : }
1012 : }
1013 0 : bailout1:
1014 0 : bat_iterator_end(&bi);
1015 0 : bailout:
1016 0 : GDKfree(buf);
1017 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
1018 0 : unfix_inputs(2, b, bs);
1019 0 : return msg;
1020 : }
1021 :
1022 : /* Input: a BAT of strings 'l' and a BAT of integers 'n'
1023 : * Output type: str (a BAT of strings)
1024 : */
1025 : static str
1026 2 : do_batstr_batint_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1027 : const char *name,
1028 : str (*func)(str *, size_t *, const char *, int))
1029 : {
1030 2 : BATiter lefti;
1031 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1032 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1033 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1034 2 : bool nils = false;
1035 2 : int *restrict righti, y;
1036 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1037 2 : oid off1, off2;
1038 2 : bat *res = getArgReference_bat(stk, pci, 0),
1039 2 : l = *getArgReference_bat(stk, pci, 1),
1040 2 : n = *getArgReference_bat(stk, pci, 2),
1041 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
1042 2 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
1043 2 : BATiter bi;
1044 :
1045 2 : (void) cntxt;
1046 2 : (void) mb;
1047 2 : if (!buf) {
1048 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1049 0 : goto bailout;
1050 : }
1051 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(n))) {
1052 0 : msg = createException(MAL, name,
1053 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1054 0 : goto bailout;
1055 : }
1056 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1057 2 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1058 0 : msg = createException(MAL, name,
1059 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1060 0 : goto bailout;
1061 : }
1062 2 : canditer_init(&ci1, left, ls);
1063 2 : canditer_init(&ci2, right, rs);
1064 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1065 0 : msg = createException(MAL, name,
1066 : ILLEGAL_ARGUMENT
1067 : " Requires bats of identical size");
1068 0 : goto bailout;
1069 : }
1070 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1071 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1072 0 : goto bailout;
1073 : }
1074 :
1075 2 : off1 = left->hseqbase;
1076 2 : off2 = right->hseqbase;
1077 2 : lefti = bat_iterator(left);
1078 2 : bi = bat_iterator(right);
1079 2 : righti = bi.base;
1080 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1081 6 : for (BUN i = 0; i < ci1.ncand; i++) {
1082 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
1083 4 : p2 = (canditer_next_dense(&ci2) - off2);
1084 4 : const char *x = BUNtvar(lefti, p1);
1085 4 : y = righti[p2];
1086 :
1087 8 : if (strNil(x) || is_int_nil(y)) {
1088 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1089 0 : msg = createException(MAL, name,
1090 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1091 0 : goto bailout1;
1092 : }
1093 : nils = true;
1094 : } else {
1095 4 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1096 0 : goto bailout1;
1097 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1098 0 : msg = createException(MAL, name,
1099 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1100 0 : goto bailout1;
1101 : }
1102 : }
1103 : }
1104 : } else {
1105 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1106 0 : oid p1 = (canditer_next(&ci1) - off1),
1107 0 : p2 = (canditer_next(&ci2) - off2);
1108 0 : const char *x = BUNtvar(lefti, p1);
1109 0 : y = righti[p2];
1110 :
1111 0 : if (strNil(x) || is_int_nil(y)) {
1112 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1113 0 : msg = createException(MAL, name,
1114 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1115 0 : goto bailout1;
1116 : }
1117 : nils = true;
1118 : } else {
1119 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
1120 0 : goto bailout1;
1121 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1122 0 : msg = createException(MAL, name,
1123 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1124 0 : goto bailout1;
1125 : }
1126 : }
1127 : }
1128 : }
1129 0 : bailout1:
1130 2 : bat_iterator_end(&bi);
1131 2 : bat_iterator_end(&lefti);
1132 2 : bailout:
1133 2 : GDKfree(buf);
1134 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1135 2 : unfix_inputs(4, left, ls, right, rs);
1136 2 : return msg;
1137 : }
1138 :
1139 : /* Input: a BAT of strings 'l', a constant int 'y' and a constant str 'z'
1140 : * Output type: str (a BAT of strings)
1141 : */
1142 : static str
1143 2 : do_batstr_constint_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1144 : InstrPtr pci, const char *name,
1145 : str (*func)(str *, size_t *, const char *, int, const char *))
1146 : {
1147 2 : BATiter bi;
1148 2 : BAT *bn = NULL, *b = NULL, *bs = NULL;
1149 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1150 2 : const char *z = *getArgReference_str(stk, pci, 3);
1151 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1152 2 : int y = *getArgReference_int(stk, pci, 2);
1153 2 : bool nils = false;
1154 2 : struct canditer ci1 = { 0 };
1155 2 : oid off1;
1156 2 : bat *res = getArgReference_bat(stk, pci, 0),
1157 2 : l = *getArgReference_bat(stk, pci, 1),
1158 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
1159 :
1160 2 : (void) cntxt;
1161 2 : (void) mb;
1162 2 : if (!buf) {
1163 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1164 0 : goto bailout;
1165 : }
1166 2 : if (!(b = BATdescriptor(l))) {
1167 0 : msg = createException(MAL, name,
1168 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1169 0 : goto bailout;
1170 : }
1171 2 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
1172 0 : msg = createException(MAL, name,
1173 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1174 0 : goto bailout;
1175 : }
1176 2 : canditer_init(&ci1, b, bs);
1177 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1178 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1179 0 : goto bailout;
1180 : }
1181 :
1182 2 : off1 = b->hseqbase;
1183 2 : bi = bat_iterator(b);
1184 2 : if (ci1.tpe == cand_dense) {
1185 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1186 8 : oid p1 = (canditer_next_dense(&ci1) - off1);
1187 8 : const char *x = BUNtvar(bi, p1);
1188 :
1189 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1190 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1191 0 : msg = createException(MAL, name,
1192 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1193 0 : goto bailout1;
1194 : }
1195 : nils = true;
1196 : } else {
1197 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1198 0 : goto bailout1;
1199 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1200 0 : msg = createException(MAL, name,
1201 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1202 0 : goto bailout1;
1203 : }
1204 : }
1205 : }
1206 : } else {
1207 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1208 0 : oid p1 = (canditer_next(&ci1) - off1);
1209 0 : const char *x = BUNtvar(bi, p1);
1210 :
1211 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1212 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1213 0 : msg = createException(MAL, name,
1214 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1215 0 : goto bailout1;
1216 : }
1217 : nils = true;
1218 : } else {
1219 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1220 0 : goto bailout1;
1221 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1222 0 : msg = createException(MAL, name,
1223 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1224 0 : goto bailout1;
1225 : }
1226 : }
1227 : }
1228 : }
1229 0 : bailout1:
1230 2 : bat_iterator_end(&bi);
1231 2 : bailout:
1232 2 : GDKfree(buf);
1233 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1234 2 : unfix_inputs(2, b, bs);
1235 2 : return msg;
1236 : }
1237 :
1238 : /* Input: a BAT of strings 'l', a BAT of integers 'n' and a constant str 'z'
1239 : * Output type: str (a BAT of strings)
1240 : */
1241 : static str
1242 2 : do_batstr_batint_conststr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1243 : InstrPtr pci, const char *name,
1244 : str (*func)(str *, size_t *, const char *,
1245 : int, const char *))
1246 : {
1247 2 : BATiter lefti;
1248 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1249 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1250 2 : const char *z = *getArgReference_str(stk, pci, 3);
1251 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1252 2 : bool nils = false;
1253 2 : int *restrict righti, y;
1254 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1255 2 : oid off1, off2;
1256 2 : bat *res = getArgReference_bat(stk, pci, 0),
1257 2 : l = *getArgReference_bat(stk, pci, 1),
1258 2 : n = *getArgReference_bat(stk, pci, 2),
1259 2 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
1260 2 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
1261 2 : BATiter bi;
1262 :
1263 2 : (void) cntxt;
1264 2 : (void) mb;
1265 2 : if (!buf) {
1266 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1267 0 : goto bailout;
1268 : }
1269 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(n))) {
1270 0 : msg = createException(MAL, name,
1271 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1272 0 : goto bailout;
1273 : }
1274 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1275 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1276 0 : msg = createException(MAL, name,
1277 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1278 0 : goto bailout;
1279 : }
1280 2 : canditer_init(&ci1, left, ls);
1281 2 : canditer_init(&ci2, right, rs);
1282 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1283 0 : msg = createException(MAL, name,
1284 : ILLEGAL_ARGUMENT
1285 : " Requires bats of identical size");
1286 0 : goto bailout;
1287 : }
1288 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1289 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1290 0 : goto bailout;
1291 : }
1292 :
1293 2 : off1 = left->hseqbase;
1294 2 : off2 = right->hseqbase;
1295 2 : lefti = bat_iterator(left);
1296 2 : bi = bat_iterator(right);
1297 2 : righti = bi.base;
1298 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1299 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1300 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1301 8 : p2 = (canditer_next_dense(&ci2) - off2);
1302 8 : const char *x = BUNtvar(lefti, p1);
1303 8 : y = righti[p2];
1304 :
1305 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1306 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1307 0 : msg = createException(MAL, name,
1308 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1309 0 : goto bailout1;
1310 : }
1311 : nils = true;
1312 : } else {
1313 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1314 0 : goto bailout1;
1315 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1316 0 : msg = createException(MAL, name,
1317 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1318 0 : goto bailout1;
1319 : }
1320 : }
1321 : }
1322 : } else {
1323 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1324 0 : oid p1 = (canditer_next(&ci1) - off1),
1325 0 : p2 = (canditer_next(&ci2) - off2);
1326 0 : const char *x = BUNtvar(lefti, p1);
1327 0 : y = righti[p2];
1328 :
1329 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1330 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1331 0 : msg = createException(MAL, name,
1332 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1333 0 : goto bailout1;
1334 : }
1335 : nils = true;
1336 : } else {
1337 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1338 0 : goto bailout1;
1339 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1340 0 : msg = createException(MAL, name,
1341 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1342 0 : goto bailout1;
1343 : }
1344 : }
1345 : }
1346 : }
1347 0 : bailout1:
1348 2 : bat_iterator_end(&bi);
1349 2 : bat_iterator_end(&lefti);
1350 2 : bailout:
1351 2 : GDKfree(buf);
1352 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1353 2 : unfix_inputs(4, left, ls, right, rs);
1354 2 : return msg;
1355 : }
1356 :
1357 : /* Input: a BAT of strings 'l', a constant int 'y' and a BAT of strings 'l2'
1358 : * Output type: str (a BAT of strings)
1359 : */
1360 : static str
1361 2 : do_batstr_constint_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1362 : InstrPtr pci, const char *name,
1363 : str (*func)(str *, size_t *, const char *,
1364 : int, const char *))
1365 : {
1366 2 : BATiter lefti, righti;
1367 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
1368 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1369 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1370 2 : bool nils = false;
1371 2 : int y = *getArgReference_int(stk, pci, 2);
1372 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1373 2 : oid off1, off2;
1374 2 : bat *res = getArgReference_bat(stk, pci, 0),
1375 2 : l = *getArgReference_bat(stk, pci, 1),
1376 2 : l2 = *getArgReference_bat(stk, pci, 3),
1377 2 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
1378 2 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
1379 :
1380 2 : (void) cntxt;
1381 2 : (void) mb;
1382 2 : if (!buf) {
1383 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1384 0 : goto bailout;
1385 : }
1386 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(l2))) {
1387 0 : msg = createException(MAL, name,
1388 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1389 0 : goto bailout;
1390 : }
1391 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
1392 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
1393 0 : msg = createException(MAL, name,
1394 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1395 0 : goto bailout;
1396 : }
1397 2 : canditer_init(&ci1, left, ls);
1398 2 : canditer_init(&ci2, right, rs);
1399 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
1400 0 : msg = createException(MAL, name,
1401 : ILLEGAL_ARGUMENT
1402 : " Requires bats of identical size");
1403 0 : goto bailout;
1404 : }
1405 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1406 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1407 0 : goto bailout;
1408 : }
1409 :
1410 2 : off1 = left->hseqbase;
1411 2 : off2 = right->hseqbase;
1412 2 : lefti = bat_iterator(left);
1413 2 : righti = bat_iterator(right);
1414 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1415 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1416 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1417 8 : p2 = (canditer_next_dense(&ci2) - off2);
1418 8 : const char *x = BUNtvar(lefti, p1);
1419 8 : const char *z = BUNtvar(righti, p2);
1420 :
1421 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1422 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1423 0 : msg = createException(MAL, name,
1424 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1425 0 : goto bailout1;
1426 : }
1427 : nils = true;
1428 : } else {
1429 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1430 0 : goto bailout1;
1431 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1432 0 : msg = createException(MAL, name,
1433 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1434 0 : goto bailout1;
1435 : }
1436 : }
1437 : }
1438 : } else {
1439 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1440 0 : oid p1 = (canditer_next(&ci1) - off1),
1441 0 : p2 = (canditer_next(&ci2) - off2);
1442 0 : const char *x = BUNtvar(lefti, p1);
1443 0 : const char *z = BUNtvar(righti, p2);
1444 :
1445 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1446 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1447 0 : msg = createException(MAL, name,
1448 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1449 0 : goto bailout1;
1450 : }
1451 : nils = true;
1452 : } else {
1453 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1454 0 : goto bailout1;
1455 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1456 0 : msg = createException(MAL, name,
1457 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1458 0 : goto bailout1;
1459 : }
1460 : }
1461 : }
1462 : }
1463 0 : bailout1:
1464 2 : bat_iterator_end(&lefti);
1465 2 : bat_iterator_end(&righti);
1466 2 : bailout:
1467 2 : GDKfree(buf);
1468 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1469 2 : unfix_inputs(4, left, ls, right, rs);
1470 2 : return msg;
1471 : }
1472 :
1473 : /* Input: a BAT of strings 'l', a BAT of int 'n' and a BAT of strings 'l2'
1474 : * Output type: str (a BAT of strings)
1475 : */
1476 : static str
1477 2 : do_batstr_batint_batstr_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
1478 : InstrPtr pci, const char *name,
1479 : str (*func)(str *, size_t *, const char *,
1480 : int, const char *))
1481 : {
1482 2 : BATiter arg1i, arg3i, bi;
1483 2 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL, *arg2s = NULL,
1484 2 : *arg3 = NULL, *arg3s = NULL;
1485 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
1486 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
1487 2 : bool nils = false;
1488 2 : int *restrict arg2i, y;
1489 2 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
1490 2 : oid off1, off2, off3;
1491 2 : bat *res = getArgReference_bat(stk, pci, 0),
1492 2 : l = *getArgReference_bat(stk, pci, 1),
1493 2 : n = *getArgReference_bat(stk, pci, 2),
1494 2 : l2 = *getArgReference_bat(stk, pci, 3),
1495 2 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
1496 2 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
1497 2 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
1498 :
1499 2 : (void) cntxt;
1500 2 : (void) mb;
1501 2 : if (!buf) {
1502 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1503 0 : goto bailout;
1504 : }
1505 2 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(n))
1506 2 : || !(arg3 = BATdescriptor(l2))) {
1507 0 : msg = createException(MAL, name,
1508 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1509 0 : goto bailout;
1510 : }
1511 2 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1)))
1512 2 : || (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2)))
1513 2 : || (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3)))) {
1514 0 : msg = createException(MAL, name,
1515 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1516 0 : goto bailout;
1517 : }
1518 2 : canditer_init(&ci1, arg1, arg1s);
1519 2 : canditer_init(&ci2, arg2, arg2s);
1520 2 : canditer_init(&ci3, arg3, arg3s);
1521 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
1522 2 : || ci2.hseq != ci3.hseq) {
1523 0 : msg = createException(MAL, name,
1524 : ILLEGAL_ARGUMENT
1525 : " Requires bats of identical size");
1526 0 : goto bailout;
1527 : }
1528 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
1529 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
1530 0 : goto bailout;
1531 : }
1532 :
1533 2 : off1 = arg1->hseqbase;
1534 2 : off2 = arg2->hseqbase;
1535 2 : off3 = arg3->hseqbase;
1536 2 : arg1i = bat_iterator(arg1);
1537 2 : bi = bat_iterator(arg2);
1538 2 : arg2i = bi.base;
1539 2 : arg3i = bat_iterator(arg3);
1540 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
1541 10 : for (BUN i = 0; i < ci1.ncand; i++) {
1542 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
1543 8 : p2 = (canditer_next_dense(&ci2) - off2),
1544 8 : p3 = (canditer_next_dense(&ci3) - off3);
1545 8 : const char *x = BUNtvar(arg1i, p1);
1546 8 : y = arg2i[p2];
1547 8 : const char *z = BUNtvar(arg3i, p3);
1548 :
1549 16 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1550 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1551 0 : msg = createException(MAL, name,
1552 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1553 0 : goto bailout1;
1554 : }
1555 : nils = true;
1556 : } else {
1557 8 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1558 0 : goto bailout1;
1559 8 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1560 0 : msg = createException(MAL, name,
1561 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1562 0 : goto bailout1;
1563 : }
1564 : }
1565 : }
1566 : } else {
1567 0 : for (BUN i = 0; i < ci1.ncand; i++) {
1568 0 : oid p1 = (canditer_next(&ci1) - off1),
1569 0 : p2 = (canditer_next(&ci2) - off2),
1570 0 : p3 = (canditer_next(&ci3) - off3);
1571 0 : const char *x = BUNtvar(arg1i, p1);
1572 0 : y = arg2i[p2];
1573 0 : const char *z = BUNtvar(arg3i, p3);
1574 :
1575 0 : if (strNil(x) || is_int_nil(y) || strNil(z)) {
1576 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
1577 0 : msg = createException(MAL, name,
1578 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1579 0 : goto bailout1;
1580 : }
1581 : nils = true;
1582 : } else {
1583 0 : if ((msg = (*func) (&buf, &buflen, x, y, z)) != MAL_SUCCEED)
1584 0 : goto bailout1;
1585 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
1586 0 : msg = createException(MAL, name,
1587 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
1588 0 : goto bailout1;
1589 : }
1590 : }
1591 : }
1592 : }
1593 0 : bailout1:
1594 2 : bat_iterator_end(&arg1i);
1595 2 : bat_iterator_end(&arg3i);
1596 2 : bat_iterator_end(&bi);
1597 2 : bailout:
1598 2 : GDKfree(buf);
1599 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
1600 2 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
1601 2 : return msg;
1602 : }
1603 :
1604 : static str
1605 160 : STRbatConvert(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
1606 : BAT *(*func)(BAT *, BAT *), const char *malfunc)
1607 : {
1608 160 : BAT *bn = NULL, *b = NULL, *bs = NULL;
1609 160 : bat *res = getArgReference_bat(stk, pci, 0),
1610 160 : *bid = getArgReference_bat(stk, pci, 1),
1611 160 : *sid1 = pci->argc == 3 ? getArgReference_bat(stk, pci, 2) : NULL;
1612 :
1613 160 : (void) cntxt;
1614 160 : (void) mb;
1615 160 : if (!(b = BATdescriptor(*bid))) {
1616 0 : throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1617 : }
1618 161 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
1619 0 : BBPreclaim(b);
1620 0 : throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1621 : }
1622 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 37 : STRbatRtrim(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1663 : {
1664 37 : return do_batstr_str(cntxt, mb, stk, pci, "batstr.rtrim", str_rtrim);
1665 : }
1666 :
1667 : static str
1668 9 : STRbatStrip2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1669 : {
1670 9 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.strip",
1671 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1672 : str_strip2);
1673 : }
1674 :
1675 : static str
1676 1 : STRbatLtrim2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1677 : {
1678 1 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.ltrim",
1679 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1680 : str_ltrim2);
1681 : }
1682 :
1683 : static str
1684 1 : STRbatRtrim2_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1685 : {
1686 1 : return do_batstr_conststr_str(cntxt, mb, stk, pci, "batstr.rtrim",
1687 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1688 : str_rtrim2);
1689 : }
1690 :
1691 : static str
1692 0 : STRbatStrip2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1693 : {
1694 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.strip",
1695 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1696 : str_strip2);
1697 : }
1698 :
1699 : static str
1700 0 : STRbatLtrim2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1701 : {
1702 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.ltrim",
1703 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1704 : str_ltrim2);
1705 : }
1706 :
1707 : static str
1708 0 : STRbatRtrim2_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1709 : {
1710 0 : return do_batstr_str_conststr(cntxt, mb, stk, pci, "batstr.rtrim",
1711 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1712 : str_rtrim2);
1713 : }
1714 :
1715 : static str
1716 1 : STRbatStrip2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1717 : {
1718 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.strip",
1719 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1720 : str_strip2);
1721 : }
1722 :
1723 : static str
1724 1 : STRbatLtrim2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1725 : {
1726 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.ltrim",
1727 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1728 : str_ltrim2);
1729 : }
1730 :
1731 : static str
1732 1 : STRbatRtrim2_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1733 : {
1734 1 : return do_batstr_batstr_str(cntxt, mb, stk, pci, "batstr.rtrim",
1735 : INITIAL_STR_BUFFER_LENGTH * sizeof(int),
1736 : str_rtrim2);
1737 : }
1738 :
1739 : static str
1740 1 : STRbatLpad_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1741 : {
1742 1 : return do_batstr_constint_str(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1743 : }
1744 :
1745 : static str
1746 1 : STRbatRpad_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1747 : {
1748 1 : return do_batstr_constint_str(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1749 : }
1750 :
1751 : static str
1752 0 : STRbatLpad_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1753 : {
1754 0 : return do_batstr_int_conststr(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1755 : }
1756 :
1757 : static str
1758 0 : STRbatRpad_1st_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1759 : {
1760 0 : return do_batstr_int_conststr(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1761 : }
1762 :
1763 : static str
1764 1 : STRbatLpad_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1765 : {
1766 1 : return do_batstr_batint_str(cntxt, mb, stk, pci, "batstr.lpad", str_lpad);
1767 : }
1768 :
1769 : static str
1770 1 : STRbatRpad_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1771 : {
1772 1 : return do_batstr_batint_str(cntxt, mb, stk, pci, "batstr.rpad", str_rpad);
1773 : }
1774 :
1775 : static str
1776 1 : STRbatLpad3_const_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1777 : {
1778 1 : return do_batstr_constint_conststr_str(cntxt, mb, stk, pci, "batstr.lpad",
1779 : str_lpad3);
1780 : }
1781 :
1782 : static str
1783 1 : STRbatRpad3_const_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1784 : {
1785 1 : return do_batstr_constint_conststr_str(cntxt, mb, stk, pci, "batstr.rpad",
1786 : str_rpad3);
1787 : }
1788 :
1789 : static str
1790 1 : STRbatLpad3_bat_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1791 : {
1792 1 : return do_batstr_batint_conststr_str(cntxt, mb, stk, pci, "batstr.lpad",
1793 : str_lpad3);
1794 : }
1795 :
1796 : static str
1797 1 : STRbatRpad3_bat_const(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1798 : {
1799 1 : return do_batstr_batint_conststr_str(cntxt, mb, stk, pci, "batstr.rpad",
1800 : str_rpad3);
1801 : }
1802 :
1803 : static str
1804 1 : STRbatLpad3_const_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1805 : {
1806 1 : return do_batstr_constint_batstr_str(cntxt, mb, stk, pci, "batstr.lpad",
1807 : str_lpad3);
1808 : }
1809 :
1810 : static str
1811 1 : STRbatRpad3_const_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1812 : {
1813 1 : return do_batstr_constint_batstr_str(cntxt, mb, stk, pci, "batstr.rpad",
1814 : str_rpad3);
1815 : }
1816 :
1817 : static str
1818 1 : STRbatLpad3_bat_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1819 : {
1820 1 : return do_batstr_batint_batstr_str(cntxt, mb, stk, pci, "batstr.lpad",
1821 : str_lpad3);
1822 : }
1823 :
1824 : static str
1825 1 : STRbatRpad3_bat_bat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1826 : {
1827 1 : return do_batstr_batint_batstr_str(cntxt, mb, stk, pci, "batstr.rpad",
1828 : str_rpad3);
1829 : }
1830 :
1831 : /*
1832 : * A general assumption in all cases is the bats are synchronized on their
1833 : * head column. This is not checked and may be mis-used to deploy the
1834 : * implementation for shifted window arithmetic as well.
1835 : */
1836 : static str
1837 16 : 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 16 : (void) cntxt;
1842 16 : (void) mb;
1843 :
1844 16 : BATiter lefti, righti;
1845 16 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
1846 16 : bit *restrict vals;
1847 16 : str msg = MAL_SUCCEED;
1848 16 : bool nils = false;
1849 16 : struct canditer ci1 = { 0 }, ci2 = { 0 };
1850 16 : oid off1, off2;
1851 16 : bat *res = getArgReference_bat(stk, pci, 0),
1852 16 : l = *getArgReference_bat(stk, pci, 1),
1853 16 : r = *getArgReference_bat(stk, pci, 2),
1854 30 : *sid1 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 4 : 3) : NULL,
1855 30 : *sid2 = pci->argc >= 5 ? getArgReference_bat(stk, pci, icase ? 5 : 4) : NULL;
1856 :
1857 16 : 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 16 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) ||
1863 14 : (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 16 : canditer_init(&ci1, left, lefts);
1869 16 : canditer_init(&ci2, right, rights);
1870 16 : 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 16 : 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 16 : off1 = left->hseqbase;
1882 16 : off2 = right->hseqbase;
1883 16 : lefti = bat_iterator(left);
1884 16 : righti = bat_iterator(right);
1885 16 : vals = Tloc(bn, 0);
1886 16 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
1887 50 : for (BUN i = 0; i < ci1.ncand; i++) {
1888 34 : oid p1 = (canditer_next_dense(&ci1) - off1),
1889 34 : p2 = (canditer_next_dense(&ci2) - off2);
1890 34 : char *x = BUNtvar(lefti, p1);
1891 34 : char *y = BUNtvar(righti, p2);
1892 :
1893 68 : if (strNil(x) || strNil(y)) {
1894 0 : vals[i] = bit_nil;
1895 0 : nils = true;
1896 : } else {
1897 34 : 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 16 : bat_iterator_end(&lefti);
1916 16 : bat_iterator_end(&righti);
1917 16 : exit2:
1918 16 : finalize_output(res, bn, msg, nils, ci1.ncand);
1919 16 : unfix_inputs(4, left, lefts, right, rights);
1920 16 : 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 13 : BATSTRcontains(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1953 : {
1954 13 : bit *icase = NULL;
1955 13 : 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 13 : 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 2034 : for (BUN i = 0; i < ci1.ncand; i++) {
2012 1976 : oid p1 = (canditer_next_dense(&ci1) - off1);
2013 1976 : char *x = BUNtvar(bi, p1);
2014 :
2015 1976 : if (ynil || strNil(x)) {
2016 6 : vals[i] = bit_nil;
2017 6 : nils = true;
2018 : } else {
2019 1970 : 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 94 : if (ci1.tpe == cand_dense) {
2851 6203 : for (BUN i = 0; i < ci1.ncand; i++) {
2852 6108 : oid p1 = (canditer_next_dense(&ci1) - off1);
2853 6108 : const char *x = BUNtvar(bi, p1);
2854 :
2855 11785 : if (strNil(x) || is_int_nil(y)) {
2856 434 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
2857 0 : msg = createException(MAL, name,
2858 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
2859 0 : goto bailout1;
2860 : }
2861 : nils = true;
2862 : } else {
2863 5674 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
2864 0 : goto bailout1;
2865 5674 : 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 4 : bool nils = false;
3037 4 : struct canditer ci1 = { 0 };
3038 4 : oid off1;
3039 4 : bat *res = getArgReference_bat(stk, pci, 0),
3040 4 : l = *getArgReference_bat(stk, pci, 2),
3041 4 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
3042 4 : BATiter bi;
3043 :
3044 4 : (void) cntxt;
3045 4 : (void) mb;
3046 4 : if (!buf) {
3047 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3048 0 : goto bailout;
3049 : }
3050 4 : 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 4 : 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 4 : off1 = b->hseqbase;
3067 4 : bi = bat_iterator(b);
3068 3 : vals = bi.base;
3069 3 : if (ci1.tpe == cand_dense) {
3070 7 : for (BUN i = 0; i < ci1.ncand; i++) {
3071 4 : oid p1 = (canditer_next_dense(&ci1) - off1);
3072 4 : y = vals[p1];
3073 :
3074 8 : 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 4 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3083 0 : goto bailout1;
3084 3 : 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 3 : bat_iterator_end(&bi);
3116 3 : bailout:
3117 3 : GDKfree(buf);
3118 4 : finalize_output(res, bn, msg, nils, ci1.ncand);
3119 4 : unfix_inputs(2, b, bs);
3120 5 : return msg;
3121 : }
3122 :
3123 : static str
3124 5 : STRbatprefix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3125 : {
3126 5 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.prefix", str_prefix);
3127 : }
3128 :
3129 : static str
3130 0 : STRbatsuffix_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3131 : {
3132 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.suffix", str_suffix);
3133 : }
3134 :
3135 : static str
3136 0 : STRbatTail_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3137 : {
3138 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.tail", str_tail);
3139 : }
3140 :
3141 : static str
3142 0 : STRbatsubstringTail_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3143 : InstrPtr pci)
3144 : {
3145 0 : return do_batstr_strcst(cntxt, mb, stk, pci, "batstr.substring",
3146 : str_substring_tail);
3147 : }
3148 :
3149 : static str
3150 0 : STRbatrepeat_strcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3151 : {
3152 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3153 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3154 0 : int *restrict vals, y;
3155 0 : const char *x = *getArgReference_str(stk, pci, 1);
3156 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3157 0 : bool nils = false;
3158 0 : struct canditer ci1 = { 0 };
3159 0 : oid off1;
3160 0 : bat *res = getArgReference_bat(stk, pci, 0),
3161 0 : l = *getArgReference_bat(stk, pci, 2),
3162 0 : *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
3163 0 : BATiter bi;
3164 :
3165 0 : (void) cntxt;
3166 0 : (void) mb;
3167 0 : if (!buf) {
3168 0 : msg = createException(MAL, "batstr.repeat",
3169 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3170 0 : goto bailout;
3171 : }
3172 0 : if (!(b = BATdescriptor(l))) {
3173 0 : msg = createException(MAL, "batstr.repeat",
3174 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3175 0 : goto bailout;
3176 : }
3177 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3178 0 : msg = createException(MAL, "batstr.repeat",
3179 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3180 0 : goto bailout;
3181 : }
3182 0 : canditer_init(&ci1, b, bs);
3183 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3184 0 : msg = createException(MAL, "batstr.repeat",
3185 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3186 0 : goto bailout;
3187 : }
3188 :
3189 0 : off1 = b->hseqbase;
3190 0 : bi = bat_iterator(b);
3191 0 : vals = bi.base;
3192 0 : if (ci1.tpe == cand_dense) {
3193 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3194 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
3195 0 : y = vals[p1];
3196 :
3197 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3198 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3199 0 : msg = createException(MAL, "batstr.repeat",
3200 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3201 0 : goto bailout1;
3202 : }
3203 : nils = true;
3204 : } else {
3205 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3206 0 : goto bailout1;
3207 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3208 0 : msg = createException(MAL, "batstr.repeat",
3209 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3210 0 : goto bailout1;
3211 : }
3212 : }
3213 : }
3214 : } else {
3215 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3216 0 : oid p1 = (canditer_next(&ci1) - off1);
3217 0 : y = vals[p1];
3218 :
3219 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3220 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3221 0 : msg = createException(MAL, "batstr.repeat",
3222 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3223 0 : goto bailout1;
3224 : }
3225 : nils = true;
3226 : } else {
3227 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3228 0 : goto bailout1;
3229 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3230 0 : msg = createException(MAL, "batstr.repeat",
3231 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3232 0 : goto bailout1;
3233 : }
3234 : }
3235 : }
3236 : }
3237 0 : bailout1:
3238 0 : bat_iterator_end(&bi);
3239 0 : bailout:
3240 0 : GDKfree(buf);
3241 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3242 0 : unfix_inputs(2, b, bs);
3243 0 : return msg;
3244 : }
3245 :
3246 : static str
3247 34 : do_batstr_str_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3248 : const char *name, str (*func)(str *, size_t *, const char *,
3249 : int))
3250 : {
3251 34 : BATiter lefti;
3252 34 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
3253 34 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3254 34 : int *restrict righti, y;
3255 34 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3256 34 : bool nils = false;
3257 34 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3258 34 : oid off1, off2;
3259 34 : bat *res = getArgReference_bat(stk, pci, 0),
3260 34 : l = *getArgReference_bat(stk, pci, 1),
3261 34 : r = *getArgReference_bat(stk, pci, 2),
3262 34 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
3263 34 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3264 34 : BATiter bi;
3265 :
3266 34 : (void) cntxt;
3267 34 : (void) mb;
3268 34 : if (!buf) {
3269 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3270 0 : goto bailout;
3271 : }
3272 34 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
3273 0 : msg = createException(MAL, name,
3274 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3275 0 : goto bailout;
3276 : }
3277 34 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
3278 34 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
3279 0 : msg = createException(MAL, name,
3280 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3281 0 : goto bailout;
3282 : }
3283 34 : canditer_init(&ci1, left, lefts);
3284 34 : canditer_init(&ci2, right, rights);
3285 34 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3286 0 : msg = createException(MAL, name,
3287 : ILLEGAL_ARGUMENT
3288 : " Requires bats of identical size");
3289 0 : goto bailout;
3290 : }
3291 34 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3292 0 : msg = createException(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
3293 0 : goto bailout;
3294 : }
3295 :
3296 34 : off1 = left->hseqbase;
3297 34 : off2 = right->hseqbase;
3298 34 : lefti = bat_iterator(left);
3299 34 : bi = bat_iterator(right);
3300 34 : righti = bi.base;
3301 34 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3302 33768 : for (BUN i = 0; i < ci1.ncand; i++) {
3303 33734 : oid p1 = (canditer_next_dense(&ci1) - off1),
3304 33734 : p2 = (canditer_next_dense(&ci2) - off2);
3305 33734 : const char *x = BUNtvar(lefti, p1);
3306 33734 : y = righti[p2];
3307 :
3308 37569 : if (strNil(x) || is_int_nil(y)) {
3309 29899 : 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 3835 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3317 0 : goto bailout1;
3318 3830 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3319 0 : msg = createException(MAL, name,
3320 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3321 0 : goto bailout1;
3322 : }
3323 : }
3324 : }
3325 : } else {
3326 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3327 0 : oid p1 = (canditer_next(&ci1) - off1),
3328 0 : p2 = (canditer_next(&ci2) - off2);
3329 0 : const char *x = BUNtvar(lefti, p1);
3330 0 : y = righti[p2];
3331 :
3332 0 : if (strNil(x) || is_int_nil(y)) {
3333 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3334 0 : msg = createException(MAL, name,
3335 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3336 0 : goto bailout1;
3337 : }
3338 : nils = true;
3339 : } else {
3340 0 : if ((msg = (*func) (&buf, &buflen, x, y)) != MAL_SUCCEED)
3341 0 : goto bailout1;
3342 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3343 0 : msg = createException(MAL, name,
3344 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3345 0 : goto bailout1;
3346 : }
3347 : }
3348 : }
3349 : }
3350 0 : bailout1:
3351 34 : bat_iterator_end(&bi);
3352 34 : bat_iterator_end(&lefti);
3353 34 : bailout:
3354 34 : GDKfree(buf);
3355 34 : finalize_output(res, bn, msg, nils, ci1.ncand);
3356 34 : unfix_inputs(4, left, lefts, right, rights);
3357 34 : return msg;
3358 : }
3359 :
3360 : static str
3361 0 : STRbatprefix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3362 : {
3363 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.prefix", str_prefix);
3364 : }
3365 :
3366 : static str
3367 0 : STRbatsuffix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3368 : {
3369 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.suffix", str_suffix);
3370 : }
3371 :
3372 : static str
3373 0 : STRbatTail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3374 : {
3375 0 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.tail", str_tail);
3376 : }
3377 :
3378 : static str
3379 34 : STRbatsubstringTail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3380 : {
3381 34 : return do_batstr_str_int(cntxt, mb, stk, pci, "batstr.substring",
3382 : str_substring_tail);
3383 : }
3384 :
3385 : static str
3386 0 : STRbatrepeat(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3387 : {
3388 0 : BATiter lefti;
3389 0 : BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
3390 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3391 0 : int *restrict righti, y;
3392 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3393 0 : bool nils = false;
3394 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3395 0 : oid off1, off2;
3396 0 : bat *res = getArgReference_bat(stk, pci, 0),
3397 0 : l = *getArgReference_bat(stk, pci, 1),
3398 0 : r = *getArgReference_bat(stk, pci, 2),
3399 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
3400 0 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3401 0 : BATiter bi;
3402 :
3403 0 : (void) cntxt;
3404 0 : (void) mb;
3405 0 : if (!buf) {
3406 0 : msg = createException(MAL, "batstr.repeat",
3407 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3408 0 : goto bailout;
3409 : }
3410 0 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
3411 0 : msg = createException(MAL, "batstr.repeat",
3412 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3413 0 : goto bailout;
3414 : }
3415 0 : if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1)))
3416 0 : || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
3417 0 : msg = createException(MAL, "batstr.repeat",
3418 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3419 0 : goto bailout;
3420 : }
3421 0 : canditer_init(&ci1, left, lefts);
3422 0 : canditer_init(&ci2, right, rights);
3423 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3424 0 : msg = createException(MAL, "batstr.repeat",
3425 : ILLEGAL_ARGUMENT
3426 : " Requires bats of identical size");
3427 0 : goto bailout;
3428 : }
3429 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3430 0 : msg = createException(MAL, "batstr.repeat",
3431 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3432 0 : goto bailout;
3433 : }
3434 :
3435 0 : off1 = left->hseqbase;
3436 0 : off2 = right->hseqbase;
3437 0 : lefti = bat_iterator(left);
3438 0 : bi = bat_iterator(right);
3439 0 : righti = bi.base;
3440 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3441 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3442 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3443 0 : p2 = (canditer_next_dense(&ci2) - off2);
3444 0 : const char *x = BUNtvar(lefti, p1);
3445 0 : y = righti[p2];
3446 :
3447 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3448 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3449 0 : msg = createException(MAL, "batstr.repeat",
3450 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3451 0 : goto bailout1;
3452 : }
3453 : nils = true;
3454 : } else {
3455 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3456 0 : goto bailout1;
3457 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3458 0 : msg = createException(MAL, "batstr.repeat",
3459 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3460 0 : goto bailout1;
3461 : }
3462 : }
3463 : }
3464 : } else {
3465 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3466 0 : oid p1 = (canditer_next(&ci1) - off1),
3467 0 : p2 = (canditer_next(&ci2) - off2);
3468 0 : const char *x = BUNtvar(lefti, p1);
3469 0 : y = righti[p2];
3470 :
3471 0 : if (strNil(x) || is_int_nil(y) || y < 0) {
3472 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3473 0 : msg = createException(MAL, "batstr.repeat",
3474 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3475 0 : goto bailout1;
3476 : }
3477 : nils = true;
3478 : } else {
3479 0 : if ((msg = str_repeat(&buf, &buflen, x, y)) != MAL_SUCCEED)
3480 0 : goto bailout1;
3481 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3482 0 : msg = createException(MAL, "batstr.repeat",
3483 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3484 0 : goto bailout1;
3485 : }
3486 : }
3487 : }
3488 : }
3489 0 : bailout1:
3490 0 : bat_iterator_end(&bi);
3491 0 : bat_iterator_end(&lefti);
3492 0 : bailout:
3493 0 : GDKfree(buf);
3494 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3495 0 : unfix_inputs(4, left, lefts, right, rights);
3496 0 : return msg;
3497 : }
3498 :
3499 : static str
3500 471 : STRbatSubstitutecst_imp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
3501 : int cand_nargs, const bit *rep)
3502 : {
3503 471 : BATiter bi;
3504 471 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3505 471 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3506 471 : const char *y = *getArgReference_str(stk, pci, 2),
3507 471 : *z = *getArgReference_str(stk, pci, 3);
3508 471 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3509 472 : bool nils = false;
3510 472 : bit w = *rep;
3511 472 : struct canditer ci1 = { 0 };
3512 472 : oid off1;
3513 472 : bat *res = getArgReference_bat(stk, pci, 0),
3514 472 : bid = *getArgReference_bat(stk, pci, 1),
3515 472 : *sid1 = pci->argc == cand_nargs ? getArgReference_bat(stk, pci, cand_nargs - 1) : NULL;
3516 :
3517 472 : if (!buf) {
3518 0 : msg = createException(MAL, "batstr.substritute",
3519 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3520 0 : goto bailout;
3521 : }
3522 472 : if (!(b = BATdescriptor(bid))) {
3523 0 : msg = createException(MAL, "batstr.substritute",
3524 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3525 0 : goto bailout;
3526 : }
3527 471 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3528 0 : msg = createException(MAL, "batstr.splitpart",
3529 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3530 0 : goto bailout;
3531 : }
3532 471 : canditer_init(&ci1, b, bs);
3533 471 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3534 0 : msg = createException(MAL, "batstr.substritute",
3535 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3536 0 : goto bailout;
3537 : }
3538 :
3539 472 : (void) cntxt;
3540 472 : (void) mb;
3541 472 : off1 = b->hseqbase;
3542 472 : bi = bat_iterator(b);
3543 471 : if (ci1.tpe == cand_dense) {
3544 132918 : for (BUN i = 0; i < ci1.ncand; i++) {
3545 132446 : oid p1 = (canditer_next_dense(&ci1) - off1);
3546 132446 : const char *x = BUNtvar(bi, p1);
3547 :
3548 527264 : 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 131606 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3557 0 : goto bailout1;
3558 131494 : 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 472 : bat_iterator_end(&bi);
3590 472 : bailout:
3591 472 : GDKfree(buf);
3592 472 : finalize_output(res, bn, msg, nils, ci1.ncand);
3593 472 : unfix_inputs(2, b, bs);
3594 472 : return msg;
3595 : }
3596 :
3597 : static str
3598 0 : STRbatSubstitutecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3599 : {
3600 0 : const bit *rep = getArgReference_bit(stk, pci, 4);
3601 0 : return STRbatSubstitutecst_imp(cntxt, mb, stk, pci, 6, rep);
3602 : }
3603 :
3604 : static str
3605 0 : STRbatSubstitute(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3606 : {
3607 0 : BATiter arg1i, arg2i, arg3i;
3608 0 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL, *arg2s = NULL,
3609 0 : *arg3 = NULL, *arg3s = NULL, *arg4 = NULL, *arg4s = NULL;
3610 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3611 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3612 0 : bool nils = false;
3613 0 : bit *restrict arg4i, w;
3614 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 }, ci4 = { 0 };
3615 0 : oid off1, off2, off3, off4;
3616 0 : bat *res = getArgReference_bat(stk, pci, 0),
3617 0 : l = *getArgReference_bat(stk, pci, 1),
3618 0 : r = *getArgReference_bat(stk, pci, 2),
3619 0 : s = *getArgReference_bat(stk, pci, 3),
3620 0 : rep = *getArgReference_bat(stk, pci, 4),
3621 0 : *sid1 = pci->argc == 9 ? getArgReference_bat(stk, pci, 5) : NULL,
3622 0 : *sid2 = pci->argc == 9 ? getArgReference_bat(stk, pci, 6) : NULL,
3623 0 : *sid3 = pci->argc == 9 ? getArgReference_bat(stk, pci, 7) : NULL,
3624 0 : *sid4 = pci->argc == 9 ? getArgReference_bat(stk, pci, 8) : NULL;
3625 0 : BATiter bi;
3626 :
3627 0 : if (!buf) {
3628 0 : msg = createException(MAL, "batstr.substritute",
3629 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3630 0 : goto bailout;
3631 : }
3632 0 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(r))
3633 0 : || !(arg3 = BATdescriptor(s)) || !(arg4 = BATdescriptor(rep))) {
3634 0 : msg = createException(MAL, "batstr.substritute",
3635 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3636 0 : goto bailout;
3637 : }
3638 0 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1)))
3639 0 : || (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2)))
3640 0 : || (sid3 && !is_bat_nil(*sid3) && !(arg2s = BATdescriptor(*sid3)))
3641 0 : || (sid4 && !is_bat_nil(*sid4) && !(arg4s = BATdescriptor(*sid4)))) {
3642 0 : msg = createException(MAL, "batstr.substritute",
3643 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3644 0 : goto bailout;
3645 : }
3646 0 : canditer_init(&ci1, arg1, arg1s);
3647 0 : canditer_init(&ci2, arg2, arg2s);
3648 0 : canditer_init(&ci3, arg3, arg3s);
3649 0 : canditer_init(&ci4, arg4, arg4s);
3650 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
3651 0 : || ci2.hseq != ci3.hseq || ci4.ncand != ci1.ncand
3652 0 : || ci3.hseq != ci4.hseq) {
3653 0 : msg = createException(MAL, "batstr.substritute",
3654 : ILLEGAL_ARGUMENT
3655 : " Requires bats of identical size");
3656 0 : goto bailout;
3657 : }
3658 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3659 0 : msg = createException(MAL, "batstr.substritute",
3660 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3661 0 : goto bailout;
3662 : }
3663 :
3664 0 : (void) cntxt;
3665 0 : (void) mb;
3666 0 : off1 = arg1->hseqbase;
3667 0 : off2 = arg2->hseqbase;
3668 0 : off3 = arg3->hseqbase;
3669 0 : off4 = arg4->hseqbase;
3670 0 : arg1i = bat_iterator(arg1);
3671 0 : arg2i = bat_iterator(arg2);
3672 0 : arg3i = bat_iterator(arg3);
3673 0 : bi = bat_iterator(arg4);
3674 0 : arg4i = bi.base;
3675 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense
3676 0 : && ci4.tpe == cand_dense) {
3677 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3678 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3679 0 : p2 = (canditer_next_dense(&ci2) - off2),
3680 0 : p3 = (canditer_next_dense(&ci3) - off3),
3681 0 : p4 = (canditer_next_dense(&ci4) - off4);
3682 0 : const char *x = BUNtvar(arg1i, p1);
3683 0 : const char *y = BUNtvar(arg2i, p2);
3684 0 : const char *z = BUNtvar(arg3i, p3);
3685 0 : w = arg4i[p4];
3686 :
3687 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3688 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3689 0 : msg = createException(MAL, "batstr.substritute",
3690 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3691 0 : goto bailout1;
3692 : }
3693 : nils = true;
3694 : } else {
3695 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3696 0 : goto bailout1;
3697 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3698 0 : msg = createException(MAL, "batstr.substritute",
3699 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3700 0 : goto bailout1;
3701 : }
3702 : }
3703 : }
3704 : } else {
3705 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3706 0 : oid p1 = (canditer_next(&ci1) - off1),
3707 0 : p2 = (canditer_next(&ci2) - off2),
3708 0 : p3 = (canditer_next(&ci3) - off3),
3709 0 : p4 = (canditer_next(&ci4) - off4);
3710 0 : const char *x = BUNtvar(arg1i, p1);
3711 0 : const char *y = BUNtvar(arg2i, p2);
3712 0 : const char *z = BUNtvar(arg3i, p3);
3713 0 : w = arg4i[p4];
3714 :
3715 0 : if (strNil(x) || strNil(y) || strNil(z) || is_bit_nil(w)) {
3716 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3717 0 : msg = createException(MAL, "batstr.substritute",
3718 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3719 0 : goto bailout1;
3720 : }
3721 : nils = true;
3722 : } else {
3723 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
3724 0 : goto bailout1;
3725 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3726 0 : msg = createException(MAL, "batstr.substritute",
3727 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3728 0 : goto bailout1;
3729 : }
3730 : }
3731 : }
3732 : }
3733 0 : bailout1:
3734 0 : bat_iterator_end(&bi);
3735 0 : bat_iterator_end(&arg1i);
3736 0 : bat_iterator_end(&arg2i);
3737 0 : bat_iterator_end(&arg3i);
3738 0 : bailout:
3739 0 : GDKfree(buf);
3740 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3741 0 : unfix_inputs(8, arg1, arg1, arg2, arg2s, arg3, arg3s, arg4, arg4s);
3742 0 : return msg;
3743 : }
3744 :
3745 : static str
3746 3 : STRbatsplitpartcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
3747 : {
3748 3 : BATiter bi;
3749 3 : BAT *bn = NULL, *b = NULL, *bs = NULL;
3750 3 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3751 3 : int z = *getArgReference_int(stk, pci, 3);
3752 3 : const char *y = *getArgReference_str(stk, pci, 2);
3753 3 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3754 3 : bool nils = false;
3755 3 : struct canditer ci1 = { 0 };
3756 3 : oid off1;
3757 3 : bat *res = getArgReference_bat(stk, pci, 0),
3758 3 : bid = *getArgReference_bat(stk, pci, 1),
3759 3 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
3760 :
3761 3 : (void) cntxt;
3762 3 : (void) mb;
3763 3 : if (!buf) {
3764 0 : msg = createException(MAL, "batstr.splitpart",
3765 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3766 0 : goto bailout;
3767 : }
3768 3 : if (!(b = BATdescriptor(bid))) {
3769 0 : msg = createException(MAL, "batstr.splitpart",
3770 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3771 0 : goto bailout;
3772 : }
3773 3 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
3774 0 : msg = createException(MAL, "batstr.splitpart",
3775 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3776 0 : goto bailout;
3777 : }
3778 3 : canditer_init(&ci1, b, bs);
3779 3 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3780 0 : msg = createException(MAL, "batstr.splitpart",
3781 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3782 0 : goto bailout;
3783 : }
3784 :
3785 3 : off1 = b->hseqbase;
3786 3 : bi = bat_iterator(b);
3787 3 : if (ci1.tpe == cand_dense) {
3788 128 : for (BUN i = 0; i < ci1.ncand; i++) {
3789 125 : oid p1 = (canditer_next_dense(&ci1) - off1);
3790 125 : const char *x = BUNtvar(bi, p1);
3791 :
3792 375 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3793 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3794 0 : msg = createException(MAL, "batstr.splitpart",
3795 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3796 0 : goto bailout1;
3797 : }
3798 : nils = true;
3799 : } else {
3800 125 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3801 0 : goto bailout1;
3802 125 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3803 0 : msg = createException(MAL, "batstr.splitpart",
3804 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3805 0 : goto bailout1;
3806 : }
3807 : }
3808 : }
3809 : } else {
3810 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3811 0 : oid p1 = (canditer_next(&ci1) - off1);
3812 0 : const char *x = BUNtvar(bi, p1);
3813 :
3814 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3815 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3816 0 : msg = createException(MAL, "batstr.splitpart",
3817 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3818 0 : goto bailout1;
3819 : }
3820 : nils = true;
3821 : } else {
3822 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3823 0 : goto bailout1;
3824 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3825 0 : msg = createException(MAL, "batstr.splitpart",
3826 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3827 0 : goto bailout1;
3828 : }
3829 : }
3830 : }
3831 : }
3832 0 : bailout1:
3833 3 : bat_iterator_end(&bi);
3834 3 : bailout:
3835 3 : GDKfree(buf);
3836 3 : finalize_output(res, bn, msg, nils, ci1.ncand);
3837 3 : unfix_inputs(2, b, bs);
3838 3 : return msg;
3839 : }
3840 :
3841 : static str
3842 0 : STRbatsplitpart_needlecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3843 : InstrPtr pci)
3844 : {
3845 0 : BATiter bi, fi;
3846 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *f = NULL, *fs = NULL;
3847 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3848 0 : int *restrict field, z;
3849 0 : const char *y = *getArgReference_str(stk, pci, 2);
3850 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3851 0 : bool nils = false;
3852 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3853 0 : oid off1, off2;
3854 0 : bat *res = getArgReference_bat(stk, pci, 0),
3855 0 : bid = *getArgReference_bat(stk, pci, 1),
3856 0 : fid = *getArgReference_bat(stk, pci, 3),
3857 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
3858 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
3859 :
3860 0 : if (!buf) {
3861 0 : msg = createException(MAL, "batstr.splitpart",
3862 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3863 0 : goto bailout;
3864 : }
3865 0 : if (!(b = BATdescriptor(bid)) || !(f = BATdescriptor(fid))) {
3866 0 : msg = createException(MAL, "batstr.splitpart",
3867 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3868 0 : goto bailout;
3869 : }
3870 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
3871 0 : || (sid2 && !is_bat_nil(*sid2) && !(fs = BATdescriptor(*sid2)))) {
3872 0 : msg = createException(MAL, "batstr.splitpart",
3873 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3874 0 : goto bailout;
3875 : }
3876 0 : canditer_init(&ci1, b, bs);
3877 0 : canditer_init(&ci2, f, fs);
3878 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3879 0 : msg = createException(MAL, "batstr.splitpart",
3880 : ILLEGAL_ARGUMENT
3881 : " Requires bats of identical size");
3882 0 : goto bailout;
3883 : }
3884 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
3885 0 : msg = createException(MAL, "batstr.splitpart",
3886 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3887 0 : goto bailout;
3888 : }
3889 :
3890 0 : (void) cntxt;
3891 0 : (void) mb;
3892 0 : off1 = b->hseqbase;
3893 0 : off2 = f->hseqbase;
3894 0 : bi = bat_iterator(b);
3895 0 : fi = bat_iterator(f);
3896 0 : field = fi.base;
3897 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
3898 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3899 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
3900 0 : p2 = (canditer_next_dense(&ci2) - off2);
3901 0 : const char *x = BUNtvar(bi, p1);
3902 0 : z = field[p2];
3903 :
3904 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3905 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3906 0 : msg = createException(MAL, "batstr.splitpart",
3907 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3908 0 : goto bailout1;
3909 : }
3910 : nils = true;
3911 : } else {
3912 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3913 0 : goto bailout1;
3914 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3915 0 : msg = createException(MAL, "batstr.splitpart",
3916 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3917 0 : goto bailout1;
3918 : }
3919 : }
3920 : }
3921 : } else {
3922 0 : for (BUN i = 0; i < ci1.ncand; i++) {
3923 0 : oid p1 = (canditer_next(&ci1) - off1),
3924 0 : p2 = (canditer_next(&ci2) - off2);
3925 0 : const char *x = BUNtvar(bi, p1);
3926 0 : z = field[p2];
3927 :
3928 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
3929 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
3930 0 : msg = createException(MAL, "batstr.splitpart",
3931 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3932 0 : goto bailout1;
3933 : }
3934 : nils = true;
3935 : } else {
3936 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
3937 0 : goto bailout1;
3938 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
3939 0 : msg = createException(MAL, "batstr.splitpart",
3940 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3941 0 : goto bailout1;
3942 : }
3943 : }
3944 : }
3945 : }
3946 0 : bailout1:
3947 0 : bat_iterator_end(&fi);
3948 0 : bat_iterator_end(&bi);
3949 0 : bailout:
3950 0 : GDKfree(buf);
3951 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
3952 0 : unfix_inputs(4, b, bs, f, fs);
3953 0 : return msg;
3954 : }
3955 :
3956 : static str
3957 0 : STRbatsplitpart_fieldcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
3958 : InstrPtr pci)
3959 : {
3960 0 : BATiter bi, ni;
3961 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *n = NULL, *ns = NULL;
3962 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
3963 0 : int z = *getArgReference_int(stk, pci, 3);
3964 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
3965 0 : bool nils = false;
3966 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
3967 0 : oid off1, off2;
3968 0 : bat *res = getArgReference_bat(stk, pci, 0),
3969 0 : bid = *getArgReference_bat(stk, pci, 1),
3970 0 : nid = *getArgReference_bat(stk, pci, 2),
3971 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
3972 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
3973 :
3974 0 : (void) cntxt;
3975 0 : (void) mb;
3976 0 : if (!buf) {
3977 0 : msg = createException(MAL, "batstr.splitpart",
3978 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
3979 0 : goto bailout;
3980 : }
3981 0 : if (!(b = BATdescriptor(bid)) || !(n = BATdescriptor(nid))) {
3982 0 : msg = createException(MAL, "batstr.splitpart",
3983 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3984 0 : goto bailout;
3985 : }
3986 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
3987 0 : || (sid2 && !is_bat_nil(*sid2) && !(ns = BATdescriptor(*sid2)))) {
3988 0 : msg = createException(MAL, "batstr.splitpart",
3989 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
3990 0 : goto bailout;
3991 : }
3992 0 : canditer_init(&ci1, b, bs);
3993 0 : canditer_init(&ci2, n, ns);
3994 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
3995 0 : msg = createException(MAL, "batstr.splitpart",
3996 : ILLEGAL_ARGUMENT
3997 : " Requires bats of identical size");
3998 0 : goto bailout;
3999 : }
4000 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4001 0 : msg = createException(MAL, "batstr.splitpart",
4002 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4003 0 : goto bailout;
4004 : }
4005 :
4006 0 : off1 = b->hseqbase;
4007 0 : off2 = n->hseqbase;
4008 0 : bi = bat_iterator(b);
4009 0 : ni = bat_iterator(n);
4010 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
4011 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4012 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4013 0 : p2 = (canditer_next_dense(&ci2) - off2);
4014 0 : const char *x = BUNtvar(bi, p1);
4015 0 : const char *y = BUNtvar(ni, p2);
4016 :
4017 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4018 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4019 0 : msg = createException(MAL, "batstr.splitpart",
4020 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4021 0 : goto bailout1;
4022 : }
4023 : nils = true;
4024 : } else {
4025 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4026 0 : goto bailout1;
4027 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4028 0 : msg = createException(MAL, "batstr.splitpart",
4029 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4030 0 : goto bailout1;
4031 : }
4032 : }
4033 : }
4034 : } else {
4035 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4036 0 : oid p1 = (canditer_next(&ci1) - off1),
4037 0 : p2 = (canditer_next(&ci2) - off2);
4038 0 : const char *x = BUNtvar(bi, p1);
4039 0 : const char *y = BUNtvar(ni, p2);
4040 :
4041 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4042 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4043 0 : msg = createException(MAL, "batstr.splitpart",
4044 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4045 0 : goto bailout1;
4046 : }
4047 : nils = true;
4048 : } else {
4049 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4050 0 : goto bailout1;
4051 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4052 0 : msg = createException(MAL, "batstr.splitpart",
4053 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4054 0 : goto bailout1;
4055 : }
4056 : }
4057 : }
4058 : }
4059 0 : bailout1:
4060 0 : bat_iterator_end(&bi);
4061 0 : bat_iterator_end(&ni);
4062 0 : bailout:
4063 0 : GDKfree(buf);
4064 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4065 0 : unfix_inputs(4, b, bs, n, ns);
4066 0 : return msg;
4067 : }
4068 :
4069 : static str
4070 0 : STRbatsplitpart(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4071 : {
4072 0 : BATiter arg1i, arg2i;
4073 0 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL,
4074 0 : *arg2s = NULL, *arg3 = NULL, *arg3s = NULL;
4075 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4076 0 : int *restrict arg3i, z;
4077 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4078 0 : bool nils = false;
4079 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
4080 0 : oid off1, off2, off3;
4081 0 : bat *res = getArgReference_bat(stk, pci, 0),
4082 0 : l = *getArgReference_bat(stk, pci, 1),
4083 0 : r = *getArgReference_bat(stk, pci, 2),
4084 0 : t = *getArgReference_bat(stk, pci, 3),
4085 0 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
4086 0 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
4087 0 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
4088 0 : BATiter bi;
4089 :
4090 0 : (void) cntxt;
4091 0 : (void) mb;
4092 0 : if (!buf) {
4093 0 : msg = createException(MAL, "batstr.splitpart",
4094 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4095 0 : goto bailout;
4096 : }
4097 0 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(r))
4098 0 : || !(arg3 = BATdescriptor(t))) {
4099 0 : msg = createException(MAL, "batstr.splitpart",
4100 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4101 0 : goto bailout;
4102 : }
4103 0 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) ||
4104 0 : (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) ||
4105 0 : (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3))))
4106 : {
4107 0 : msg = createException(MAL, "batstr.splitpart",
4108 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4109 0 : goto bailout;
4110 : }
4111 0 : canditer_init(&ci1, arg1, arg1s);
4112 0 : canditer_init(&ci2, arg2, arg2s);
4113 0 : canditer_init(&ci3, arg3, arg3s);
4114 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4115 0 : || ci2.hseq != ci3.hseq) {
4116 0 : msg = createException(MAL, "batstr.splitpart",
4117 : ILLEGAL_ARGUMENT
4118 : " Requires bats of identical size");
4119 0 : goto bailout;
4120 : }
4121 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4122 0 : msg = createException(MAL, "batstr.splitpart",
4123 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4124 0 : goto bailout;
4125 : }
4126 :
4127 0 : off1 = arg1->hseqbase;
4128 0 : off2 = arg2->hseqbase;
4129 0 : off3 = arg3->hseqbase;
4130 0 : arg1i = bat_iterator(arg1);
4131 0 : arg2i = bat_iterator(arg2);
4132 0 : bi = bat_iterator(arg3);
4133 0 : arg3i = bi.base;
4134 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
4135 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4136 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4137 0 : p2 = (canditer_next_dense(&ci2) - off2),
4138 0 : p3 = (canditer_next_dense(&ci3) - off3);
4139 0 : const char *x = BUNtvar(arg1i, p1);
4140 0 : const char *y = BUNtvar(arg2i, p2);
4141 0 : z = arg3i[p3];
4142 :
4143 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4144 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4145 0 : msg = createException(MAL, "batstr.splitpart",
4146 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4147 0 : goto bailout1;
4148 : }
4149 : nils = true;
4150 : } else {
4151 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4152 0 : goto bailout1;
4153 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4154 0 : msg = createException(MAL, "batstr.splitpart",
4155 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4156 0 : goto bailout1;
4157 : }
4158 : }
4159 : }
4160 : } else {
4161 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4162 0 : oid p1 = (canditer_next(&ci1) - off1),
4163 0 : p2 = (canditer_next(&ci2) - off2),
4164 0 : p3 = (canditer_next(&ci3) - off3);
4165 0 : const char *x = BUNtvar(arg1i, p1);
4166 0 : const char *y = BUNtvar(arg2i, p2);
4167 0 : z = arg3i[p3];
4168 :
4169 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
4170 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4171 0 : msg = createException(MAL, "batstr.splitpart",
4172 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4173 0 : goto bailout1;
4174 : }
4175 : nils = true;
4176 : } else {
4177 0 : if ((msg = str_splitpart(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4178 0 : goto bailout1;
4179 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4180 0 : msg = createException(MAL, "batstr.splitpart",
4181 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4182 0 : goto bailout1;
4183 : }
4184 : }
4185 : }
4186 : }
4187 0 : bailout1:
4188 0 : bat_iterator_end(&bi);
4189 0 : bat_iterator_end(&arg1i);
4190 0 : bat_iterator_end(&arg2i);
4191 0 : bailout:
4192 0 : GDKfree(buf);
4193 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4194 0 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
4195 0 : return msg;
4196 : }
4197 :
4198 : static str
4199 471 : STRbatReplacecst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4200 : {
4201 471 : bit rep = TRUE;
4202 :
4203 471 : return STRbatSubstitutecst_imp(cntxt, mb, stk, pci, 5, &rep);
4204 : }
4205 :
4206 : static str
4207 2 : STRbatReplace(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4208 : {
4209 2 : BATiter arg1i, arg2i, arg3i;
4210 2 : BAT *bn = NULL, *arg1 = NULL, *arg1s = NULL, *arg2 = NULL,
4211 2 : *arg2s = NULL, *arg3 = NULL, *arg3s = NULL;
4212 2 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4213 2 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4214 2 : bool nils = false;
4215 2 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
4216 2 : oid off1, off2, off3;
4217 2 : bat *res = getArgReference_bat(stk, pci, 0),
4218 2 : l = *getArgReference_bat(stk, pci, 1),
4219 2 : s = *getArgReference_bat(stk, pci, 2),
4220 2 : s2 = *getArgReference_bat(stk, pci, 3),
4221 2 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
4222 2 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
4223 2 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
4224 :
4225 2 : (void) cntxt;
4226 2 : (void) mb;
4227 2 : if (!buf) {
4228 0 : msg = createException(MAL, "batstr.replace",
4229 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4230 0 : goto bailout;
4231 : }
4232 2 : if (!(arg1 = BATdescriptor(l)) || !(arg2 = BATdescriptor(s))
4233 2 : || !(arg3 = BATdescriptor(s2))) {
4234 0 : msg = createException(MAL, "batstr.replace",
4235 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4236 0 : goto bailout;
4237 : }
4238 2 : if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) ||
4239 2 : (sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) ||
4240 0 : (sid3 && !is_bat_nil(*sid3) && ! (arg3s = BATdescriptor(*sid3))))
4241 : {
4242 0 : msg = createException(MAL, "batstr.replace",
4243 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4244 0 : goto bailout;
4245 : }
4246 2 : canditer_init(&ci1, arg1, arg1s);
4247 2 : canditer_init(&ci2, arg2, arg2s);
4248 2 : canditer_init(&ci3, arg3, arg3s);
4249 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4250 2 : || ci2.hseq != ci3.hseq) {
4251 0 : msg = createException(MAL, "batstr.replace",
4252 : ILLEGAL_ARGUMENT
4253 : " Requires bats of identical size");
4254 0 : goto bailout;
4255 : }
4256 2 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4257 0 : msg = createException(MAL, "batstr.replace",
4258 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4259 0 : goto bailout;
4260 : }
4261 :
4262 2 : off1 = arg1->hseqbase;
4263 2 : off2 = arg2->hseqbase;
4264 2 : off3 = arg3->hseqbase;
4265 2 : arg1i = bat_iterator(arg1);
4266 2 : arg2i = bat_iterator(arg2);
4267 2 : arg3i = bat_iterator(arg3);
4268 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
4269 6 : for (BUN i = 0; i < ci1.ncand; i++) {
4270 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
4271 4 : p2 = (canditer_next_dense(&ci2) - off2),
4272 4 : p3 = (canditer_next_dense(&ci3) - off3);
4273 4 : const char *x = BUNtvar(arg1i, p1);
4274 4 : const char *y = BUNtvar(arg2i, p2);
4275 4 : const char *z = BUNtvar(arg3i, p3);
4276 :
4277 12 : if (strNil(x) || strNil(y) || strNil(z)) {
4278 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4279 0 : msg = createException(MAL, "batstr.replace",
4280 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4281 0 : goto bailout1;
4282 : }
4283 : nils = true;
4284 : } else {
4285 4 : if ((msg = str_substitute(&buf, &buflen, x, y, z, TRUE)) != MAL_SUCCEED)
4286 0 : goto bailout1;
4287 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4288 0 : msg = createException(MAL, "batstr.replace",
4289 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4290 0 : goto bailout1;
4291 : }
4292 : }
4293 : }
4294 : } else {
4295 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4296 0 : oid p1 = (canditer_next(&ci1) - off1),
4297 0 : p2 = (canditer_next(&ci2) - off2),
4298 0 : p3 = (canditer_next(&ci3) - off3);
4299 0 : const char *x = BUNtvar(arg1i, p1);
4300 0 : const char *y = BUNtvar(arg2i, p2);
4301 0 : const char *z = BUNtvar(arg3i, p3);
4302 :
4303 0 : if (strNil(x) || strNil(y) || strNil(z)) {
4304 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4305 0 : msg = createException(MAL, "batstr.replace",
4306 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4307 0 : goto bailout1;
4308 : }
4309 : nils = true;
4310 : } else {
4311 0 : if ((msg = str_substitute(&buf, &buflen, x, y, z, TRUE)) != MAL_SUCCEED)
4312 0 : goto bailout1;
4313 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4314 0 : msg = createException(MAL, "batstr.replace",
4315 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4316 0 : goto bailout1;
4317 : }
4318 : }
4319 : }
4320 : }
4321 0 : bailout1:
4322 2 : bat_iterator_end(&arg1i);
4323 2 : bat_iterator_end(&arg2i);
4324 2 : bat_iterator_end(&arg3i);
4325 2 : bailout:
4326 2 : GDKfree(buf);
4327 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
4328 2 : unfix_inputs(6, arg1, arg1s, arg2, arg2s, arg3, arg3s);
4329 2 : return msg;
4330 : }
4331 :
4332 : static str
4333 0 : STRbatInsert(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4334 : {
4335 0 : BATiter lefti, righti, starti, ncharsi;
4336 0 : BAT *bn = NULL, *left = NULL, *ls = NULL, *start = NULL,
4337 0 : *ss = NULL, *nchars = NULL, *ns = NULL, *right = NULL, *rs = NULL;
4338 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4339 0 : int *sval, *lval, y, z;
4340 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4341 0 : bool nils = false;
4342 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 }, ci4 = { 0 };
4343 0 : oid off1, off2, off3, off4;
4344 0 : bat *res = getArgReference_bat(stk, pci, 0),
4345 0 : l = *getArgReference_bat(stk, pci, 1),
4346 0 : s = *getArgReference_bat(stk, pci, 2),
4347 0 : chars = *getArgReference_bat(stk, pci, 3),
4348 0 : s2 = *getArgReference_bat(stk, pci, 4),
4349 0 : *sid1 = pci->argc == 9 ? getArgReference_bat(stk, pci, 5) : NULL,
4350 0 : *sid2 = pci->argc == 9 ? getArgReference_bat(stk, pci, 6) : NULL,
4351 0 : *sid3 = pci->argc == 9 ? getArgReference_bat(stk, pci, 7) : NULL,
4352 0 : *sid4 = pci->argc == 9 ? getArgReference_bat(stk, pci, 8) : NULL;
4353 :
4354 0 : (void) cntxt;
4355 0 : (void) mb;
4356 0 : if (!buf) {
4357 0 : msg = createException(MAL, "batstr.insert",
4358 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4359 0 : goto bailout;
4360 : }
4361 0 : if (!(left = BATdescriptor(l)) || !(start = BATdescriptor(s))
4362 0 : || !(nchars = BATdescriptor(chars)) || !(right = BATdescriptor(s2))) {
4363 0 : msg = createException(MAL, "batstr.insert",
4364 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4365 0 : goto bailout;
4366 : }
4367 0 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1)))
4368 0 : || (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))
4369 0 : || (sid3 && !is_bat_nil(*sid3) && !(ss = BATdescriptor(*sid3)))
4370 0 : || (sid4 && !is_bat_nil(*sid4) && !(ns = BATdescriptor(*sid4)))) {
4371 0 : msg = createException(MAL, "batstr.insert",
4372 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4373 0 : goto bailout;
4374 : }
4375 0 : canditer_init(&ci1, left, ls);
4376 0 : canditer_init(&ci2, start, ss);
4377 0 : canditer_init(&ci3, nchars, ns);
4378 0 : canditer_init(&ci4, right, rs);
4379 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
4380 0 : || ci2.hseq != ci3.hseq || ci4.ncand != ci1.ncand
4381 0 : || ci3.hseq != ci4.hseq) {
4382 0 : msg = createException(MAL, "batstr.insert",
4383 : ILLEGAL_ARGUMENT
4384 : " Requires bats of identical size");
4385 0 : goto bailout;
4386 : }
4387 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4388 0 : msg = createException(MAL, "batstr.insert",
4389 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4390 0 : goto bailout;
4391 : }
4392 :
4393 0 : off1 = left->hseqbase;
4394 0 : off2 = start->hseqbase;
4395 0 : off3 = nchars->hseqbase;
4396 0 : off4 = right->hseqbase;
4397 0 : lefti = bat_iterator(left);
4398 0 : starti = bat_iterator(start);
4399 0 : ncharsi = bat_iterator(nchars);
4400 0 : sval = starti.base;
4401 0 : lval = ncharsi.base;
4402 0 : righti = bat_iterator(right);
4403 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense
4404 0 : && ci4.tpe == cand_dense) {
4405 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4406 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
4407 0 : p2 = (canditer_next_dense(&ci2) - off2),
4408 0 : p3 = (canditer_next_dense(&ci3) - off3),
4409 0 : p4 = (canditer_next_dense(&ci4) - off4);
4410 0 : const char *x = BUNtvar(lefti, p1);
4411 0 : y = sval[p2];
4412 0 : z = lval[p3];
4413 0 : const char *w = BUNtvar(righti, p4);
4414 :
4415 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4416 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4417 0 : msg = createException(MAL, "batstr.insert",
4418 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4419 0 : goto bailout1;
4420 : }
4421 : nils = true;
4422 : } else {
4423 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4424 0 : goto bailout1;
4425 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4426 0 : msg = createException(MAL, "batstr.insert",
4427 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4428 0 : goto bailout1;
4429 : }
4430 : }
4431 : }
4432 : } else {
4433 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4434 0 : oid p1 = (canditer_next(&ci1) - off1),
4435 0 : p2 = (canditer_next(&ci2) - off2),
4436 0 : p3 = (canditer_next(&ci3) - off3),
4437 0 : p4 = (canditer_next(&ci4) - off4);
4438 0 : const char *x = BUNtvar(lefti, p1);
4439 0 : y = sval[p2];
4440 0 : z = lval[p3];
4441 0 : const char *w = BUNtvar(righti, p4);
4442 :
4443 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4444 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4445 0 : msg = createException(MAL, "batstr.insert",
4446 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4447 0 : goto bailout1;
4448 : }
4449 : nils = true;
4450 : } else {
4451 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4452 0 : goto bailout1;
4453 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4454 0 : msg = createException(MAL, "batstr.insert",
4455 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4456 0 : goto bailout1;
4457 : }
4458 : }
4459 : }
4460 : }
4461 0 : bailout1:
4462 0 : bat_iterator_end(&starti);
4463 0 : bat_iterator_end(&ncharsi);
4464 0 : bat_iterator_end(&lefti);
4465 0 : bat_iterator_end(&righti);
4466 0 : bailout:
4467 0 : GDKfree(buf);
4468 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4469 0 : unfix_inputs(8, left, ls, start, ss, nchars, ns, right, rs);
4470 0 : return msg;
4471 : }
4472 :
4473 : static str
4474 0 : STRbatInsertcst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4475 : {
4476 0 : BATiter bi;
4477 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4478 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4479 0 : int y = *getArgReference_int(stk, pci, 2),
4480 0 : z = *getArgReference_int(stk, pci, 3);
4481 0 : const char *w = *getArgReference_str(stk, pci, 4);
4482 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4483 0 : bool nils = false;
4484 0 : struct canditer ci1 = { 0 };
4485 0 : oid off1;
4486 0 : bat *res = getArgReference_bat(stk, pci, 0),
4487 0 : bid = *getArgReference_bat(stk, pci, 1),
4488 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4489 :
4490 0 : (void) cntxt;
4491 0 : (void) mb;
4492 0 : if (!buf) {
4493 0 : msg = createException(MAL, "batstr.insert",
4494 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4495 0 : goto bailout;
4496 : }
4497 0 : if (!(b = BATdescriptor(bid))) {
4498 0 : msg = createException(MAL, "batstr.insert",
4499 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4500 0 : goto bailout;
4501 : }
4502 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4503 0 : msg = createException(MAL, "batstr.insert",
4504 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4505 0 : goto bailout;
4506 : }
4507 0 : canditer_init(&ci1, b, bs);
4508 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4509 0 : msg = createException(MAL, "batstr.insert",
4510 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4511 0 : goto bailout;
4512 : }
4513 :
4514 0 : off1 = b->hseqbase;
4515 0 : bi = bat_iterator(b);
4516 0 : if (ci1.tpe == cand_dense) {
4517 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4518 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
4519 0 : const char *x = BUNtvar(bi, p1);
4520 :
4521 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4522 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4523 0 : msg = createException(MAL, "batstr.insert",
4524 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4525 0 : goto bailout1;
4526 : }
4527 : nils = true;
4528 : } else {
4529 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4530 0 : goto bailout1;
4531 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4532 0 : msg = createException(MAL, "batstr.insert",
4533 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4534 0 : goto bailout1;
4535 : }
4536 : }
4537 : }
4538 : } else {
4539 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4540 0 : oid p1 = (canditer_next(&ci1) - off1);
4541 0 : const char *x = BUNtvar(bi, p1);
4542 :
4543 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z) || strNil(w)) {
4544 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4545 0 : msg = createException(MAL, "batstr.insert",
4546 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4547 0 : goto bailout1;
4548 : }
4549 : nils = true;
4550 : } else {
4551 0 : if ((msg = str_insert(&buf, &buflen, x, y, z, w)) != MAL_SUCCEED)
4552 0 : goto bailout1;
4553 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4554 0 : msg = createException(MAL, "batstr.insert",
4555 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4556 0 : goto bailout1;
4557 : }
4558 : }
4559 : }
4560 : }
4561 0 : bailout1:
4562 0 : bat_iterator_end(&bi);
4563 0 : bailout:
4564 0 : GDKfree(buf);
4565 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
4566 0 : unfix_inputs(2, b, bs);
4567 0 : return msg;
4568 : }
4569 :
4570 : /*
4571 : * The substring functions require slightly different arguments
4572 : */
4573 : static str
4574 121 : STRbatsubstring_2nd_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
4575 : InstrPtr pci)
4576 : {
4577 121 : BATiter bi;
4578 121 : BAT *bn = NULL, *b = NULL, *bs = NULL;
4579 121 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4580 121 : int y = *getArgReference_int(stk, pci, 2),
4581 121 : z = *getArgReference_int(stk, pci, 3);
4582 121 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4583 122 : bool nils = false;
4584 122 : struct canditer ci1 = { 0 };
4585 122 : oid off1;
4586 122 : bat *res = getArgReference_bat(stk, pci, 0),
4587 122 : bid = *getArgReference_bat(stk, pci, 1),
4588 122 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
4589 :
4590 122 : (void) cntxt;
4591 122 : (void) mb;
4592 122 : if (!buf) {
4593 0 : msg = createException(MAL, "batstr.substring",
4594 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4595 0 : goto bailout;
4596 : }
4597 122 : if (!(b = BATdescriptor(bid))) {
4598 0 : msg = createException(MAL, "batstr.substring",
4599 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4600 0 : goto bailout;
4601 : }
4602 123 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
4603 0 : msg = createException(MAL, "batstr.substring",
4604 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
4605 0 : goto bailout;
4606 : }
4607 123 : canditer_init(&ci1, b, bs);
4608 123 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
4609 0 : msg = createException(MAL, "batstr.substring",
4610 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4611 0 : goto bailout;
4612 : }
4613 :
4614 123 : off1 = b->hseqbase;
4615 123 : bi = bat_iterator(b);
4616 123 : if (ci1.tpe == cand_dense) {
4617 3855103 : for (BUN i = 0; i < ci1.ncand; i++) {
4618 3854980 : oid p1 = (canditer_next_dense(&ci1) - off1);
4619 3854980 : const char *x = BUNtvar(bi, p1);
4620 :
4621 7610583 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4622 86677 : 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 3768303 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4630 0 : goto bailout1;
4631 3799481 : 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 122 : bailout:
4664 122 : GDKfree(buf);
4665 122 : 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 3 : lbi = bat_iterator(lb);
4921 4 : vals1 = bi.base;
4922 4 : vals2 = lbi.base;
4923 4 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
4924 12 : for (BUN i = 0; i < ci1.ncand; i++) {
4925 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
4926 8 : p2 = (canditer_next_dense(&ci2) - off2);
4927 8 : y = vals1[p1];
4928 8 : z = vals2[p2];
4929 :
4930 16 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4931 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4932 0 : msg = createException(MAL, "batstr.substring",
4933 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4934 0 : goto bailout1;
4935 : }
4936 : nils = true;
4937 : } else {
4938 8 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4939 0 : goto bailout1;
4940 7 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4941 0 : msg = createException(MAL, "batstr.substring",
4942 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4943 0 : goto bailout1;
4944 : }
4945 : }
4946 : }
4947 : } else {
4948 0 : for (BUN i = 0; i < ci1.ncand; i++) {
4949 0 : oid p1 = (canditer_next(&ci1) - off1),
4950 0 : p2 = (canditer_next(&ci2) - off2);
4951 0 : y = vals1[p1];
4952 0 : z = vals2[p2];
4953 :
4954 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
4955 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
4956 0 : msg = createException(MAL, "batstr.substring",
4957 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4958 0 : goto bailout1;
4959 : }
4960 : nils = true;
4961 : } else {
4962 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
4963 0 : goto bailout1;
4964 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
4965 0 : msg = createException(MAL, "batstr.substring",
4966 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
4967 0 : goto bailout1;
4968 : }
4969 : }
4970 : }
4971 : }
4972 0 : bailout1:
4973 4 : bat_iterator_end(&bi);
4974 3 : bat_iterator_end(&lbi);
4975 4 : bailout:
4976 4 : GDKfree(buf);
4977 4 : finalize_output(res, bn, msg, nils, ci1.ncand);
4978 4 : unfix_inputs(4, b, bs, lb, lbs);
4979 4 : return msg;
4980 : }
4981 :
4982 : static str
4983 32 : STRbatsubstring_2nd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
4984 : {
4985 32 : BATiter bi;
4986 32 : BATiter lbi;
4987 32 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
4988 32 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
4989 32 : int y = *getArgReference_int(stk, pci, 2), *len, z;
4990 32 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
4991 32 : bool nils = false;
4992 32 : struct canditer ci1 = { 0 }, ci2 = { 0 };
4993 32 : oid off1, off2;
4994 32 : bat *res = getArgReference_bat(stk, pci, 0),
4995 32 : bid = *getArgReference_bat(stk, pci, 1),
4996 32 : l = *getArgReference_bat(stk, pci, 3),
4997 32 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
4998 32 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
4999 :
5000 32 : (void) cntxt;
5001 32 : (void) mb;
5002 32 : if (!buf) {
5003 0 : msg = createException(MAL, "batstr.substring",
5004 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5005 0 : goto bailout;
5006 : }
5007 32 : if (!(b = BATdescriptor(bid)) || !(lb = BATdescriptor(l))) {
5008 0 : msg = createException(MAL, "batstr.substring",
5009 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5010 0 : goto bailout;
5011 : }
5012 32 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
5013 32 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
5014 0 : msg = createException(MAL, "batstr.substring",
5015 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5016 0 : goto bailout;
5017 : }
5018 32 : canditer_init(&ci1, b, bs);
5019 32 : canditer_init(&ci2, lb, lbs);
5020 32 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5021 0 : msg = createException(MAL, "batstr.substring",
5022 : ILLEGAL_ARGUMENT
5023 : " Requires bats of identical size");
5024 0 : goto bailout;
5025 : }
5026 32 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5027 0 : msg = createException(MAL, "batstr.substring",
5028 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5029 0 : goto bailout;
5030 : }
5031 :
5032 32 : off1 = b->hseqbase;
5033 32 : off2 = lb->hseqbase;
5034 32 : bi = bat_iterator(b);
5035 32 : lbi = bat_iterator(lb);
5036 32 : len = lbi.base;
5037 32 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5038 36 : for (BUN i = 0; i < ci1.ncand; i++) {
5039 4 : oid p1 = (canditer_next_dense(&ci1) - off1),
5040 4 : p2 = (canditer_next_dense(&ci2) - off2);
5041 4 : const char *x = BUNtvar(bi, p1);
5042 4 : z = len[p2];
5043 :
5044 8 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5045 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5046 0 : msg = createException(MAL, "batstr.substring",
5047 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5048 0 : goto bailout1;
5049 : }
5050 : nils = true;
5051 : } else {
5052 4 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5053 0 : goto bailout1;
5054 4 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5055 0 : msg = createException(MAL, "batstr.substring",
5056 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5057 0 : goto bailout1;
5058 : }
5059 : }
5060 : }
5061 : } else {
5062 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5063 0 : oid p1 = (canditer_next(&ci1) - off1),
5064 0 : p2 = (canditer_next(&ci2) - off2);
5065 0 : const char *x = BUNtvar(bi, p1);
5066 0 : z = len[p2];
5067 :
5068 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5069 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5070 0 : msg = createException(MAL, "batstr.substring",
5071 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5072 0 : goto bailout1;
5073 : }
5074 : nils = true;
5075 : } else {
5076 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5077 0 : goto bailout1;
5078 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5079 0 : msg = createException(MAL, "batstr.substring",
5080 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5081 0 : goto bailout1;
5082 : }
5083 : }
5084 : }
5085 : }
5086 0 : bailout1:
5087 32 : bat_iterator_end(&lbi);
5088 32 : bat_iterator_end(&bi);
5089 32 : bailout:
5090 32 : GDKfree(buf);
5091 32 : finalize_output(res, bn, msg, nils, ci1.ncand);
5092 32 : unfix_inputs(4, b, bs, lb, lbs);
5093 32 : return msg;
5094 : }
5095 :
5096 : static str
5097 0 : STRbatsubstring_3rd_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5098 : {
5099 0 : BATiter bi, lbi;
5100 0 : BAT *bn = NULL, *b = NULL, *bs = NULL, *lb = NULL, *lbs = NULL;
5101 0 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
5102 0 : int *start, y, z = *getArgReference_int(stk, pci, 3);
5103 0 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
5104 0 : bool nils = false;
5105 0 : struct canditer ci1 = { 0 }, ci2 = { 0 };
5106 0 : oid off1, off2;
5107 0 : bat *res = getArgReference_bat(stk, pci, 0),
5108 0 : bid = *getArgReference_bat(stk, pci, 1),
5109 0 : l = *getArgReference_bat(stk, pci, 2),
5110 0 : *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL,
5111 0 : *sid2 = pci->argc == 6 ? getArgReference_bat(stk, pci, 5) : NULL;
5112 :
5113 0 : (void) cntxt;
5114 0 : (void) mb;
5115 0 : if (!buf) {
5116 0 : msg = createException(MAL, "batstr.substring",
5117 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5118 0 : goto bailout;
5119 : }
5120 0 : if (!(b = BATdescriptor(bid)) || !(lb = BATdescriptor(l))) {
5121 0 : msg = createException(MAL, "batstr.substring",
5122 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5123 0 : goto bailout;
5124 : }
5125 0 : if ((sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1)))
5126 0 : || (sid2 && !is_bat_nil(*sid2) && !(lbs = BATdescriptor(*sid2)))) {
5127 0 : msg = createException(MAL, "batstr.substring",
5128 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5129 0 : goto bailout;
5130 : }
5131 0 : canditer_init(&ci1, b, bs);
5132 0 : canditer_init(&ci2, lb, lbs);
5133 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5134 0 : msg = createException(MAL, "batstr.substring",
5135 : ILLEGAL_ARGUMENT
5136 : " Requires bats of identical size");
5137 0 : goto bailout;
5138 : }
5139 0 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5140 0 : msg = createException(MAL, "batstr.substring",
5141 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5142 0 : goto bailout;
5143 : }
5144 :
5145 0 : off1 = b->hseqbase;
5146 0 : off2 = lb->hseqbase;
5147 0 : bi = bat_iterator(b);
5148 0 : lbi = bat_iterator(lb);
5149 0 : start = lbi.base;
5150 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5151 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5152 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
5153 0 : p2 = (canditer_next_dense(&ci2) - off2);
5154 0 : const char *x = BUNtvar(bi, p1);
5155 0 : y = start[p2];
5156 :
5157 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5158 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5159 0 : msg = createException(MAL, "batstr.substring",
5160 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5161 0 : goto bailout1;
5162 : }
5163 : nils = true;
5164 : } else {
5165 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5166 0 : goto bailout1;
5167 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5168 0 : msg = createException(MAL, "batstr.substring",
5169 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5170 0 : goto bailout1;
5171 : }
5172 : }
5173 : }
5174 : } else {
5175 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5176 0 : oid p1 = (canditer_next(&ci1) - off1),
5177 0 : p2 = (canditer_next(&ci2) - off2);
5178 0 : const char *x = BUNtvar(bi, p1);
5179 0 : y = start[p2];
5180 :
5181 0 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5182 0 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5183 0 : msg = createException(MAL, "batstr.substring",
5184 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5185 0 : goto bailout1;
5186 : }
5187 : nils = true;
5188 : } else {
5189 0 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5190 0 : goto bailout1;
5191 0 : if (tfastins_nocheckVAR(bn, i, buf) != GDK_SUCCEED) {
5192 0 : msg = createException(MAL, "batstr.substring",
5193 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5194 0 : goto bailout1;
5195 : }
5196 : }
5197 : }
5198 : }
5199 0 : bailout1:
5200 0 : bat_iterator_end(&lbi);
5201 0 : bat_iterator_end(&bi);
5202 0 : bailout:
5203 0 : GDKfree(buf);
5204 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5205 0 : unfix_inputs(4, b, bs, lb, lbs);
5206 0 : return msg;
5207 : }
5208 :
5209 : static str
5210 28 : STRbatsubstring(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5211 : {
5212 28 : BATiter lefti, starti, lengthi;
5213 28 : BAT *bn = NULL, *left = NULL, *ls = NULL, *start = NULL,
5214 28 : *ss = NULL, *length = NULL, *lens = NULL;
5215 28 : size_t buflen = INITIAL_STR_BUFFER_LENGTH;
5216 28 : int *svals, *lvals, y, z;
5217 28 : str buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
5218 28 : bool nils = false;
5219 28 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
5220 28 : oid off1, off2, off3;
5221 28 : bat *res = getArgReference_bat(stk, pci, 0),
5222 28 : l = *getArgReference_bat(stk, pci, 1),
5223 28 : r = *getArgReference_bat(stk, pci, 2),
5224 28 : t = *getArgReference_bat(stk, pci, 3),
5225 28 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
5226 28 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
5227 28 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
5228 :
5229 28 : (void) cntxt;
5230 28 : (void) mb;
5231 28 : if (!buf) {
5232 0 : msg = createException(MAL, "batstr.substring",
5233 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5234 0 : goto bailout;
5235 : }
5236 28 : if (!(left = BATdescriptor(l)) || !(start = BATdescriptor(r))
5237 28 : || !(length = BATdescriptor(t))) {
5238 0 : msg = createException(MAL, "batstr.substring",
5239 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5240 0 : goto bailout;
5241 : }
5242 28 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5243 28 : (sid2 && !is_bat_nil(*sid2) && !(ss = BATdescriptor(*sid2))) ||
5244 0 : (sid3 && !is_bat_nil(*sid3) && !(lens = BATdescriptor(*sid3)))) {
5245 0 : msg = createException(MAL, "batstr.substring",
5246 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5247 0 : goto bailout;
5248 : }
5249 28 : canditer_init(&ci1, left, ls);
5250 28 : canditer_init(&ci2, start, ss);
5251 28 : canditer_init(&ci3, length, lens);
5252 28 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
5253 28 : || ci2.hseq != ci3.hseq) {
5254 0 : msg = createException(MAL, "batstr.substring",
5255 : ILLEGAL_ARGUMENT
5256 : " Requires bats of identical size");
5257 0 : goto bailout;
5258 : }
5259 28 : if (!(bn = COLnew(ci1.hseq, TYPE_str, ci1.ncand, TRANSIENT))) {
5260 0 : msg = createException(MAL, "batstr.substring",
5261 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5262 0 : goto bailout;
5263 : }
5264 :
5265 28 : off1 = left->hseqbase;
5266 28 : off2 = start->hseqbase;
5267 28 : off3 = length->hseqbase;
5268 28 : lefti = bat_iterator(left);
5269 28 : starti = bat_iterator(start);
5270 28 : lengthi = bat_iterator(length);
5271 28 : svals = starti.base;
5272 28 : lvals = lengthi.base;
5273 28 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
5274 3818 : for (BUN i = 0; i < ci1.ncand; i++) {
5275 3790 : oid p1 = (canditer_next_dense(&ci1) - off1),
5276 3790 : p2 = (canditer_next_dense(&ci2) - off2),
5277 3790 : p3 = (canditer_next_dense(&ci3) - off3);
5278 3790 : const char *x = BUNtvar(lefti, p1);
5279 3790 : y = svals[p2];
5280 3790 : z = lvals[p3];
5281 :
5282 7550 : if (strNil(x) || is_int_nil(y) || is_int_nil(z)) {
5283 48 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
5284 0 : msg = createException(MAL, "batstr.substring",
5285 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5286 0 : goto bailout1;
5287 : }
5288 : nils = true;
5289 : } else {
5290 3742 : if ((msg = str_sub_string(&buf, &buflen, x, y, z)) != MAL_SUCCEED)
5291 0 : goto bailout1;
5292 3682 : 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 3746 : for (BUN i = 0; i < ci1.ncand; i++) {
5445 3694 : oid p1 = (canditer_next_dense(&ci1) - off1);
5446 3694 : const char *y = BUNtvar(bi, p1);
5447 :
5448 7388 : if (strNil(x) || strNil(y)) {
5449 0 : vals[i] = int_nil;
5450 0 : nils = true;
5451 : } else {
5452 3694 : vals[i] = str_locate2(x, y, 1);
5453 : }
5454 : }
5455 : } else {
5456 1 : for (BUN i = 0; i < ci1.ncand; i++) {
5457 1 : oid p1 = (canditer_next(&ci1) - off1);
5458 0 : const char *y = BUNtvar(bi, p1);
5459 :
5460 0 : if (strNil(x) || strNil(y)) {
5461 0 : vals[i] = int_nil;
5462 0 : nils = true;
5463 : } else {
5464 0 : vals[i] = str_locate2(x, y, 1);
5465 : }
5466 : }
5467 : }
5468 52 : bat_iterator_end(&bi);
5469 51 : bailout:
5470 51 : finalize_output(res, bn, msg, nils, ci1.ncand);
5471 52 : unfix_inputs(2, b, bs);
5472 52 : return msg;
5473 : }
5474 :
5475 : static str
5476 2 : STRbatstrLocate(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5477 : {
5478 2 : BATiter lefti, righti;
5479 2 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL, *rs = NULL;
5480 2 : int *restrict vals;
5481 2 : str msg = MAL_SUCCEED;
5482 2 : bool nils = false;
5483 2 : struct canditer ci1 = { 0 }, ci2 = { 0 };
5484 2 : oid off1, off2;
5485 2 : bat *res = getArgReference_bat(stk, pci, 0),
5486 2 : l = *getArgReference_bat(stk, pci, 1),
5487 2 : r = *getArgReference_bat(stk, pci, 2),
5488 2 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
5489 2 : *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
5490 :
5491 2 : (void) cntxt;
5492 2 : (void) mb;
5493 2 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))) {
5494 0 : msg = createException(MAL, "batstr.locate",
5495 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5496 0 : goto bailout;
5497 : }
5498 2 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5499 2 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2)))) {
5500 0 : msg = createException(MAL, "batstr.locate",
5501 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5502 0 : goto bailout;
5503 : }
5504 2 : canditer_init(&ci1, left, ls);
5505 2 : canditer_init(&ci2, right, rs);
5506 2 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
5507 0 : msg = createException(MAL, "batstr.locate",
5508 : ILLEGAL_ARGUMENT
5509 : " Requires bats of identical size");
5510 0 : goto bailout;
5511 : }
5512 2 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5513 0 : msg = createException(MAL, "batstr.locate",
5514 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5515 0 : goto bailout;
5516 : }
5517 :
5518 2 : off1 = left->hseqbase;
5519 2 : off2 = right->hseqbase;
5520 2 : lefti = bat_iterator(left);
5521 2 : righti = bat_iterator(right);
5522 2 : vals = Tloc(bn, 0);
5523 2 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
5524 10 : for (BUN i = 0; i < ci1.ncand; i++) {
5525 8 : oid p1 = (canditer_next_dense(&ci1) - off1),
5526 8 : p2 = (canditer_next_dense(&ci2) - off2);
5527 8 : const char *x = BUNtvar(lefti, p1);
5528 8 : const char *y = BUNtvar(righti, p2);
5529 :
5530 16 : if (strNil(x) || strNil(y)) {
5531 0 : vals[i] = int_nil;
5532 0 : nils = true;
5533 : } else {
5534 8 : vals[i] = str_locate2(x, y, 1);
5535 : }
5536 : }
5537 : } else {
5538 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5539 0 : oid p1 = (canditer_next(&ci1) - off1),
5540 0 : p2 = (canditer_next(&ci2) - off2);
5541 0 : const char *x = BUNtvar(lefti, p1);
5542 0 : const char *y = BUNtvar(righti, p2);
5543 :
5544 0 : if (strNil(x) || strNil(y)) {
5545 0 : vals[i] = int_nil;
5546 0 : nils = true;
5547 : } else {
5548 0 : vals[i] = str_locate2(x, y, 1);
5549 : }
5550 : }
5551 : }
5552 2 : bat_iterator_end(&lefti);
5553 2 : bat_iterator_end(&righti);
5554 2 : bailout:
5555 2 : finalize_output(res, bn, msg, nils, ci1.ncand);
5556 2 : unfix_inputs(4, left, ls, right, rs);
5557 2 : return msg;
5558 : }
5559 :
5560 : static str
5561 0 : STRbatstrLocate3cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5562 : {
5563 0 : BATiter bi;
5564 0 : BAT *bn = NULL, *b = NULL, *bs = NULL;
5565 0 : int *restrict vals, z = *getArgReference_int(stk, pci, 3);
5566 0 : const char *y = *getArgReference_str(stk, pci, 2);
5567 0 : str msg = MAL_SUCCEED;
5568 0 : bool nils = false;
5569 0 : struct canditer ci1 = { 0 };
5570 0 : oid off1;
5571 0 : bat *res = getArgReference_bat(stk, pci, 0),
5572 0 : l = *getArgReference_bat(stk, pci, 1),
5573 0 : *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
5574 :
5575 0 : (void) cntxt;
5576 0 : (void) mb;
5577 0 : if (!(b = BATdescriptor(l))) {
5578 0 : msg = createException(MAL, "batstr.locate2",
5579 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5580 0 : goto bailout;
5581 : }
5582 0 : if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
5583 0 : msg = createException(MAL, "batstr.locate2",
5584 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5585 0 : goto bailout;
5586 : }
5587 0 : canditer_init(&ci1, b, bs);
5588 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5589 0 : msg = createException(MAL, "batstr.locate2",
5590 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5591 0 : goto bailout;
5592 : }
5593 :
5594 0 : off1 = b->hseqbase;
5595 0 : bi = bat_iterator(b);
5596 0 : vals = Tloc(bn, 0);
5597 0 : if (ci1.tpe == cand_dense) {
5598 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5599 0 : oid p1 = (canditer_next_dense(&ci1) - off1);
5600 0 : const char *x = BUNtvar(bi, p1);
5601 :
5602 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5603 0 : vals[i] = int_nil;
5604 0 : nils = true;
5605 : } else {
5606 0 : vals[i] = str_locate2(x, y, z);
5607 : }
5608 : }
5609 : } else {
5610 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5611 0 : oid p1 = (canditer_next(&ci1) - off1);
5612 0 : const char *x = BUNtvar(bi, p1);
5613 :
5614 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5615 0 : vals[i] = int_nil;
5616 0 : nils = true;
5617 : } else {
5618 0 : vals[i] = str_locate2(x, y, z);
5619 : }
5620 : }
5621 : }
5622 0 : bat_iterator_end(&bi);
5623 0 : bailout:
5624 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5625 0 : unfix_inputs(2, b, bs);
5626 0 : return msg;
5627 : }
5628 :
5629 : static str
5630 0 : STRbatstrLocate3(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5631 : {
5632 0 : BATiter lefti, righti, starti;
5633 0 : BAT *bn = NULL, *left = NULL, *ls = NULL, *right = NULL,
5634 0 : *rs = NULL, *start = NULL, *ss = NULL;
5635 0 : int *restrict vals, *restrict svals, z;
5636 0 : str msg = MAL_SUCCEED;
5637 0 : bool nils = false;
5638 0 : struct canditer ci1 = { 0 }, ci2 = { 0 }, ci3 = { 0 };
5639 0 : oid off1, off2, off3;
5640 0 : bat *res = getArgReference_bat(stk, pci, 0),
5641 0 : l = *getArgReference_bat(stk, pci, 1),
5642 0 : r = *getArgReference_bat(stk, pci, 2),
5643 0 : s = *getArgReference_bat(stk, pci, 3),
5644 0 : *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL,
5645 0 : *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL,
5646 0 : *sid3 = pci->argc == 7 ? getArgReference_bat(stk, pci, 6) : NULL;
5647 :
5648 0 : (void) cntxt;
5649 0 : (void) mb;
5650 0 : if (!(left = BATdescriptor(l)) || !(right = BATdescriptor(r))
5651 0 : || !(start = BATdescriptor(s))) {
5652 0 : msg = createException(MAL, "batstr.locate2",
5653 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5654 0 : goto bailout;
5655 : }
5656 0 : if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) ||
5657 0 : (sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2))) ||
5658 0 : (sid3 && !is_bat_nil(*sid3) && !(ss = BATdescriptor(*sid3)))) {
5659 0 : msg = createException(MAL, "batstr.locate2",
5660 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
5661 0 : goto bailout;
5662 : }
5663 0 : canditer_init(&ci1, left, ls);
5664 0 : canditer_init(&ci2, right, rs);
5665 0 : canditer_init(&ci3, start, ss);
5666 0 : if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq || ci3.ncand != ci1.ncand
5667 0 : || ci2.hseq != ci3.hseq) {
5668 0 : msg = createException(MAL, "batstr.locate2",
5669 : ILLEGAL_ARGUMENT
5670 : " Requires bats of identical size");
5671 0 : goto bailout;
5672 : }
5673 0 : if (!(bn = COLnew(ci1.hseq, TYPE_int, ci1.ncand, TRANSIENT))) {
5674 0 : msg = createException(MAL, "batstr.locate2",
5675 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
5676 0 : goto bailout;
5677 : }
5678 :
5679 0 : off1 = left->hseqbase;
5680 0 : off2 = right->hseqbase;
5681 0 : off3 = start->hseqbase;
5682 0 : lefti = bat_iterator(left);
5683 0 : righti = bat_iterator(right);
5684 0 : starti = bat_iterator(start);
5685 0 : svals = starti.base;
5686 0 : vals = Tloc(bn, 0);
5687 0 : if (ci1.tpe == cand_dense && ci2.tpe == cand_dense && ci3.tpe == cand_dense) {
5688 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5689 0 : oid p1 = (canditer_next_dense(&ci1) - off1),
5690 0 : p2 = (canditer_next_dense(&ci2) - off2),
5691 0 : p3 = (canditer_next_dense(&ci3) - off3);
5692 0 : const char *x = BUNtvar(lefti, p1);
5693 0 : const char *y = BUNtvar(righti, p2);
5694 0 : z = svals[p3];
5695 :
5696 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5697 0 : vals[i] = int_nil;
5698 0 : nils = true;
5699 : } else {
5700 0 : vals[i] = str_locate2(x, y, z);
5701 : }
5702 : }
5703 : } else {
5704 0 : for (BUN i = 0; i < ci1.ncand; i++) {
5705 0 : oid p1 = (canditer_next(&ci1) - off1),
5706 0 : p2 = (canditer_next(&ci2) - off2),
5707 0 : p3 = (canditer_next(&ci3) - off3);
5708 0 : const char *x = BUNtvar(lefti, p1);
5709 0 : const char *y = BUNtvar(righti, p2);
5710 0 : z = svals[p3];
5711 :
5712 0 : if (strNil(x) || strNil(y) || is_int_nil(z)) {
5713 0 : vals[i] = int_nil;
5714 0 : nils = true;
5715 : } else {
5716 0 : vals[i] = str_locate2(x, y, z);
5717 : }
5718 : }
5719 : }
5720 0 : bat_iterator_end(&starti);
5721 0 : bat_iterator_end(&lefti);
5722 0 : bat_iterator_end(&righti);
5723 0 : bailout:
5724 0 : finalize_output(res, bn, msg, nils, ci1.ncand);
5725 0 : unfix_inputs(6, left, ls, right, rs, start, ss);
5726 0 : return msg;
5727 : }
5728 :
5729 : static str
5730 33 : BATSTRasciify(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
5731 : {
5732 33 : return STRbatConvert(cntxt, mb, stk, pci, BATasciify, "batstr.asciify");
5733 : }
5734 :
5735 : #include "mel.h"
5736 : mel_func batstr_init_funcs[] = {
5737 : pattern("batstr", "length", STRbatLength, false, "Return the length of a string.", args(1,2, batarg("",int),batarg("s",str))),
5738 : pattern("batstr", "length", STRbatLength, false, "Return the length of a string.", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5739 : pattern("batstr", "nbytes", STRbatBytes, false, "Return the string length in bytes.", args(1,2, batarg("",int),batarg("s",str))),
5740 : pattern("batstr", "nbytes", STRbatBytes, false, "Return the string length in bytes.", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5741 : pattern("batstr", "toLower", STRbatLower, false, "Convert a string to lower case.", args(1,2, batarg("",str),batarg("s",str))),
5742 : pattern("batstr", "toLower", STRbatLower, false, "Convert a string to lower case.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5743 : pattern("batstr", "toUpper", STRbatUpper, false, "Convert a string to upper case.", args(1,2, batarg("",str),batarg("s",str))),
5744 : pattern("batstr", "toUpper", STRbatUpper, false, "Convert a string to upper case.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5745 : pattern("batstr", "caseFold", STRbatCaseFold, false, "Fold the case of a string.", args(1,2, batarg("",str),batarg("s",str))),
5746 : pattern("batstr", "caseFold", STRbatCaseFold, false, "Fold the case of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5747 : pattern("batstr", "trim", STRbatStrip, false, "Strip whitespaces around a string.", args(1,2, batarg("",str),batarg("s",str))),
5748 : pattern("batstr", "trim", STRbatStrip, false, "Strip whitespaces around a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5749 : pattern("batstr", "ltrim", STRbatLtrim, false, "Strip whitespaces from start of a string.", args(1,2, batarg("",str),batarg("s",str))),
5750 : pattern("batstr", "ltrim", STRbatLtrim, false, "Strip whitespaces from start of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5751 : pattern("batstr", "rtrim", STRbatRtrim, false, "Strip whitespaces from end of a string.", args(1,2, batarg("",str),batarg("s",str))),
5752 : pattern("batstr", "rtrim", STRbatRtrim, false, "Strip whitespaces from end of a string.", args(1,3, batarg("",str),batarg("s",str),batarg("s",oid))),
5753 : pattern("batstr", "trim2", STRbatStrip2_const, false, "Strip characters in the second string around the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5754 : pattern("batstr", "trim2", STRbatStrip2_const, false, "Strip characters in the second string around the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5755 : pattern("batstr", "trim2", STRbatStrip2_1st_const, false, "Strip characters in the second string around the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5756 : pattern("batstr", "trim2", STRbatStrip2_1st_const, false, "Strip characters in the second string around the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5757 : pattern("batstr", "ltrim2", STRbatLtrim2_const, false, "Strip characters in the second string from start of the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5758 : pattern("batstr", "ltrim2", STRbatLtrim2_const, false, "Strip characters in the second string from start of the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5759 : pattern("batstr", "ltrim2", STRbatLtrim2_1st_const, false, "Strip characters in the second string from start of the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5760 : pattern("batstr", "ltrim2", STRbatLtrim2_1st_const, false, "Strip characters in the second string from start of the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5761 : pattern("batstr", "rtrim2", STRbatRtrim2_const, false, "Strip characters in the second string from end of the first strings.", args(1,3, batarg("",str),batarg("s",str),arg("s2",str))),
5762 : pattern("batstr", "rtrim2", STRbatRtrim2_const, false, "Strip characters in the second string from end of the first strings.", args(1,4, batarg("",str),batarg("s",str),arg("s2",str),batarg("s",oid))),
5763 : pattern("batstr", "rtrim2", STRbatRtrim2_1st_const, false, "Strip characters in the second string from end of the first strings.", args(1,3, batarg("",str),arg("s",str),batarg("s2",str))),
5764 : pattern("batstr", "rtrim2", STRbatRtrim2_1st_const, false, "Strip characters in the second string from end of the first strings.", args(1,4, batarg("",str),arg("s",str),batarg("s2",str),batarg("s",oid))),
5765 : pattern("batstr", "trim2", STRbatStrip2_bat, false, "Strip characters in the second strings around the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5766 : pattern("batstr", "trim2", STRbatStrip2_bat, false, "Strip characters in the second strings around the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5767 : pattern("batstr", "ltrim2", STRbatLtrim2_bat, false, "Strip characters in the second strings from start of the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5768 : pattern("batstr", "ltrim2", STRbatLtrim2_bat, false, "Strip characters in the second strings from start of the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5769 : pattern("batstr", "rtrim2", STRbatRtrim2_bat, false, "Strip characters in the second strings from end of the first strings.", args(1,3, batarg("",str),batarg("s",str),batarg("s2",str))),
5770 : pattern("batstr", "rtrim2", STRbatRtrim2_bat, false, "Strip characters in the second strings from end of the first strings.", args(1,5, batarg("",str),batarg("s",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5771 : pattern("batstr", "lpad", STRbatLpad_const, false, "Prepend whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,3, batarg("",str),batarg("s",str),arg("n",int))),
5772 : pattern("batstr", "lpad", STRbatLpad_const, false, "Prepend whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s",oid))),
5773 : pattern("batstr", "rpad", STRbatRpad_const, false, "Append whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,3, batarg("",str),batarg("s",str),arg("n",int))),
5774 : pattern("batstr", "rpad", STRbatRpad_const, false, "Append whitespaces to the strings to reach the given length. Truncate the strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s",oid))),
5775 : pattern("batstr", "lpad", STRbatLpad_1st_const, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),arg("s",str),batarg("n",int))),
5776 : pattern("batstr", "lpad", STRbatLpad_1st_const, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),arg("s",str),batarg("n",int),batarg("s",oid))),
5777 : pattern("batstr", "rpad", STRbatRpad_1st_const, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),arg("s",str),batarg("n",int))),
5778 : pattern("batstr", "rpad", STRbatRpad_1st_const, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),arg("s",str),batarg("n",int),batarg("s",oid))),
5779 : pattern("batstr", "lpad", STRbatLpad_bat, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),batarg("s",str),batarg("n",int))),
5780 : pattern("batstr", "lpad", STRbatLpad_bat, false, "Prepend whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,5, batarg("",str),batarg("s",str),batarg("n",int),batarg("s1",oid),batarg("s2",oid))),
5781 : pattern("batstr", "rpad", STRbatRpad_bat, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,3, batarg("",str),batarg("s",str),batarg("n",int))),
5782 : pattern("batstr", "rpad", STRbatRpad_bat, false, "Append whitespaces to the strings to reach the given lengths. Truncate the strings on the right if their lengths is larger than the given lengths.", args(1,5, batarg("",str),batarg("s",str),batarg("n",int),batarg("s1",oid),batarg("s2",oid))),
5783 : pattern("batstr", "lpad3", STRbatLpad3_const_const, false, "Prepend the second string to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),arg("s2",str))),
5784 : pattern("batstr", "rpad3", STRbatRpad3_const_const, false, "Append the second string to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),arg("s2",str))),
5785 : pattern("batstr", "lpad3", STRbatLpad3_bat_const, false, "Prepend the second string to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),arg("s2",str))),
5786 : pattern("batstr", "rpad3", STRbatRpad3_bat_const, false, "Append the second string to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),arg("s2",str))),
5787 : pattern("batstr", "lpad3", STRbatLpad3_const_bat, false, "Prepend the second strings to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s2",str))),
5788 : pattern("batstr", "rpad3", STRbatRpad3_const_bat, false, "Append the second strings to the first strings to reach the given length. Truncate the first strings on the right if their lengths is larger than the given length.", args(1,4, batarg("",str),batarg("s",str),arg("n",int),batarg("s2",str))),
5789 : pattern("batstr", "lpad3", STRbatLpad3_bat_bat, false, "Prepend the second strings to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),batarg("s2",str))),
5790 : pattern("batstr", "rpad3", STRbatRpad3_bat_bat, false, "Append the second strings to the first strings to reach the given lengths. Truncate the first strings on the right if their lengths is larger than the given lengths.", args(1,4, batarg("",str),batarg("s",str),batarg("n",int),batarg("s2",str))),
5791 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5792 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5793 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5794 : pattern("batstr", "startswith", BATSTRstarts_with, false, "Check if bat string starts with bat substring (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5795 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string starts with substring.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5796 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string starts with substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5797 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string(with CL) starts with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5798 : pattern("batstr", "startswith", BATSTRstarts_with_cst, false, "Check if bat string(with CL) starts with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5799 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5800 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5801 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring(with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5802 : pattern("batstr", "startswith", BATSTRstarts_with_strcst, false, "Check if string starts with bat substring(with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5803 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5804 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5805 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5806 : pattern("batstr", "endswith", BATSTRends_with, false, "Check if bat string ends with bat substring (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5807 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string ends with substring.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5808 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string ends with substring, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5809 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string(with CL) ends with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5810 : pattern("batstr", "endswith", BATSTRends_with_cst, false, "Check if bat string(with CL) ends with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5811 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5812 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5813 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring(with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5814 : pattern("batstr", "endswith", BATSTRends_with_strcst, false, "Check if string ends with bat substring(with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5815 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle.", args(1,3, batarg("",bit),batarg("s",str),batarg("prefix",str))),
5816 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle, icase flag.", args(1,4, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit))),
5817 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle (with CLs).", args(1,5, batarg("",bit),batarg("s",str),batarg("prefix",str),batarg("s1",oid),batarg("s2",oid))),
5818 : pattern("batstr", "contains", BATSTRcontains, false, "Check if bat string haystack contains bat string needle (with CLs) + icase flag.", args(1,6, batarg("",bit),batarg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5819 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle.", args(1,3, batarg("",bit),batarg("s",str),arg("prefix",str))),
5820 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle, icase flag.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit))),
5821 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle (with CL) ends with substring.", args(1,4, batarg("",bit),batarg("s",str),arg("prefix",str),batarg("s",oid))),
5822 : pattern("batstr", "contains", BATSTRcontains_cst, false, "Check if bat string haystack contains string needle (with CL) ends with substring + icase flag.", args(1,5, batarg("",bit),batarg("s",str),arg("prefix",str),arg("icase",bit),batarg("s",oid))),
5823 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle.", args(1,3, batarg("",bit),arg("s",str),batarg("prefix",str))),
5824 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle + icase flag.", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit))),
5825 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle (with CL).", args(1,4, batarg("",bit),arg("s",str),batarg("prefix",str),batarg("s",oid))),
5826 : pattern("batstr", "contains", BATSTRcontains_strcst, false, "Check if string haystack contains bat string needle (with CL) + icase flag.", args(1,5, batarg("",bit),arg("s",str),batarg("prefix",str),arg("icase",bit),batarg("s",oid))),
5827 : pattern("batstr", "splitpart", STRbatsplitpart, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),batarg("needle",str),batarg("field",int))),
5828 : pattern("batstr", "splitpart", STRbatsplitpartcst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),arg("needle",str),arg("field",int))),
5829 : pattern("batstr", "splitpart", STRbatsplitpart_needlecst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),arg("needle",str),batarg("field",int))),
5830 : pattern("batstr", "splitpart", STRbatsplitpart_fieldcst, false, "Split string on delimiter. Returns\ngiven field (counting from one.)", args(1,4, batarg("",str),batarg("s",str),batarg("needle",str),arg("field",int))),
5831 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),batarg("c",str))),
5832 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit))),
5833 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),batarg("c",str),batarg("s1",oid),batarg("s2",oid))),
5834 : pattern("batstr", "search", BATSTRstr_search, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,6, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5835 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),arg("c",str))),
5836 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit))),
5837 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),batarg("s",oid))),
5838 : pattern("batstr", "search", BATSTRstr_search_cst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,5, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit),batarg("s",oid))),
5839 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),arg("s",str),batarg("c",str))),
5840 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit))),
5841 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),batarg("s",oid))),
5842 : pattern("batstr", "search", BATSTRstr_search_strcst, false, "Search for a substring. Returns position, -1 if not found, icase flag.", args(1,5, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit),batarg("s",oid))),
5843 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),batarg("c",str))),
5844 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit))),
5845 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring (with CLs). Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),batarg("c",str),batarg("s1",oid),batarg("s2",oid))),
5846 : pattern("batstr", "r_search", BATSTRrevstr_search, false, "Reverse search for a substring (with CLs) + icase flag. Returns position, -1 if not found.", args(1,6, batarg("",int),batarg("s",str),batarg("c",str),arg("icase",bit),batarg("s1",oid),batarg("s2",oid))),
5847 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),batarg("s",str),arg("c",str))),
5848 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit))),
5849 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring (with CL). Returns position, -1 if not found.", args(1,4, batarg("",int),batarg("s",str),arg("c",str),batarg("s",oid))),
5850 : pattern("batstr", "r_search", BATSTRrevstr_search_cst, false, "Reverse search for a substring (with CL) + icase flag. Returns position, -1 if not found.", args(1,5, batarg("",int),batarg("s",str),arg("c",str),arg("icase",bit),batarg("s",oid))),
5851 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring. Returns position, -1 if not found.", args(1,3, batarg("",int),arg("s",str),batarg("c",str))),
5852 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring + icase flag. Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit))),
5853 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring (with CL). Returns position, -1 if not found.", args(1,4, batarg("",int),arg("s",str),batarg("c",str),batarg("s",oid))),
5854 : pattern("batstr", "r_search", BATSTRrevstr_search_strcst, false, "Reverse search for a substring (with CL) + icase flag. Returns position, -1 if not found.", args(1,5, batarg("",int),arg("s",str),batarg("c",str),arg("icase",bit),batarg("s",oid))),
5855 : pattern("batstr", "string", STRbatTail, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),batarg("b",str),batarg("offset",int))),
5856 : pattern("batstr", "string", STRbatTail, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,5, batarg("",str),batarg("b",str),batarg("offset",int),batarg("s1",oid),batarg("s2",oid))),
5857 : pattern("batstr", "string", STRbatTailcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),batarg("b",str),arg("offset",int))),
5858 : pattern("batstr", "string", STRbatTailcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,4, batarg("",str),batarg("b",str),arg("offset",int),batarg("s",oid))),
5859 : pattern("batstr", "string", STRbatTail_strcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,3, batarg("",str),arg("b",str),batarg("offset",int))),
5860 : pattern("batstr", "string", STRbatTail_strcst, false, "Return the tail s[offset..n] of a string s[0..n].", args(1,4, batarg("",str),arg("b",str),batarg("offset",int),batarg("s",oid))),
5861 : pattern("batstr", "ascii", STRbatAscii, false, "Return unicode of head of string", args(1,2, batarg("",int),batarg("s",str))),
5862 : pattern("batstr", "ascii", STRbatAscii, false, "Return unicode of head of string", args(1,3, batarg("",int),batarg("s",str),batarg("s",oid))),
5863 : pattern("batstr", "substring", STRbatsubstringTail, false, "Extract the tail of a string", args(1,3, batarg("",str),batarg("s",str),batarg("start",int))),
5864 : pattern("batstr", "substring", STRbatsubstringTail, false, "Extract the tail of a string", args(1,5, batarg("",str),batarg("s",str),batarg("start",int),batarg("s1",oid),batarg("s2",oid))),
5865 : pattern("batstr", "substring", STRbatsubstringTailcst, false, "Extract the tail of a string", args(1,3, batarg("",str),batarg("s",str),arg("start",int))),
5866 : pattern("batstr", "substring", STRbatsubstringTailcst, false, "Extract the tail of a string", args(1,4, batarg("",str),batarg("s",str),arg("start",int),batarg("s",oid))),
5867 : pattern("batstr", "substring", STRbatsubstringTail_strcst, false, "Extract the tail of a string", args(1,3, batarg("",str),arg("s",str),batarg("start",int))),
5868 : pattern("batstr", "substring", STRbatsubstringTail_strcst, false, "Extract the tail of a string", args(1,4, batarg("",str),arg("s",str),batarg("start",int),batarg("s",oid))),
5869 : pattern("batstr", "substring3", STRbatsubstring, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),batarg("start",int),batarg("index",int))),
5870 : pattern("batstr", "substring3", STRbatsubstring, false, "Substring extraction using [start,start+length]", args(1,7, batarg("",str),batarg("s",str),batarg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid),batarg("s3",oid))),
5871 : pattern("batstr", "substring3", STRbatsubstring_2nd_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),arg("start",int),arg("index",int))),
5872 : pattern("batstr", "substring3", STRbatsubstring_2nd_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),batarg("s",str),arg("start",int),arg("index",int),batarg("s",oid))),
5873 : pattern("batstr", "substring3", STRbatsubstring_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),arg("start",int),batarg("index",int))),
5874 : pattern("batstr", "substring3", STRbatsubstring_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),batarg("s",str),arg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5875 : pattern("batstr", "substring3", STRbatsubstring_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),batarg("s",str),batarg("start",int),arg("index",int))),
5876 : pattern("batstr", "substring3", STRbatsubstring_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),batarg("s",str),batarg("start",int),arg("index",int),batarg("s1",oid),batarg("s2",oid))),
5877 : pattern("batstr", "substring3", STRbatsubstring_1st_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),arg("start",int),batarg("index",int))),
5878 : pattern("batstr", "substring3", STRbatsubstring_1st_2nd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),arg("s",str),arg("start",int),batarg("index",int),batarg("s",oid))),
5879 : pattern("batstr", "substring3", STRbatsubstring_1st_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),batarg("start",int),arg("index",int))),
5880 : pattern("batstr", "substring3", STRbatsubstring_1st_3rd_cst, false, "Substring extraction using [start,start+length]", args(1,5, batarg("",str),arg("s",str),batarg("start",int),arg("index",int),batarg("s",oid))),
5881 : pattern("batstr", "substring3", STRbatsubstring_1st_cst, false, "Substring extraction using [start,start+length]", args(1,4, batarg("",str),arg("s",str),batarg("start",int),batarg("index",int))),
5882 : pattern("batstr", "substring3", STRbatsubstring_1st_cst, false, "Substring extraction using [start,start+length]", args(1,6, batarg("",str),arg("s",str),batarg("start",int),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5883 : pattern("batstr", "unicode", STRbatFromWChr, false, "convert a unicode to a character.", args(1,2, batarg("",str),batarg("wchar",int))),
5884 : pattern("batstr", "unicode", STRbatFromWChr, false, "convert a unicode to a character.", args(1,3, batarg("",str),batarg("wchar",int),batarg("s",oid))),
5885 : pattern("batstr", "unicodeAt", STRbatWChrAt, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),batarg("s",str),batarg("index",int))),
5886 : pattern("batstr", "unicodeAt", STRbatWChrAt, false, "get a unicode character (as an int) from a string position.", args(1,5, batarg("",int),batarg("s",str),batarg("index",int),batarg("s1",oid),batarg("s2",oid))),
5887 : pattern("batstr", "unicodeAt", STRbatWChrAtcst, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),batarg("s",str),arg("index",int))),
5888 : pattern("batstr", "unicodeAt", STRbatWChrAtcst, false, "get a unicode character (as an int) from a string position.", args(1,4, batarg("",int),batarg("s",str),arg("index",int),batarg("s",oid))),
5889 : pattern("batstr", "unicodeAt", STRbatWChrAt_strcst, false, "get a unicode character (as an int) from a string position.", args(1,3, batarg("",int),arg("s",str),batarg("index",int))),
5890 : pattern("batstr", "unicodeAt", STRbatWChrAt_strcst, false, "get a unicode character (as an int) from a string position.", args(1,4, batarg("",int),arg("s",str),batarg("index",int),batarg("s",oid))),
5891 : pattern("batstr", "substitute", STRbatSubstitute, false, "Substitute first occurrence of 'src' by\n'dst'. Iff repeated = true this is\nrepeated while 'src' can be found in the\nresult string. In order to prevent\nrecursion and result strings of unlimited\nsize, repeating is only done iff src is\nnot a substring of dst.", args(1,5, batarg("",str),batarg("s",str),batarg("src",str),batarg("dst",str),batarg("rep",bit))),
5892 : pattern("batstr", "substitute", STRbatSubstitutecst, false, "Substitute first occurrence of 'src' by\n'dst'. Iff repeated = true this is\nrepeated while 'src' can be found in the\nresult string. In order to prevent\nrecursion and result strings of unlimited\nsize, repeating is only done iff src is\nnot a substring of dst.", args(1,5, batarg("",str),batarg("s",str),arg("src",str),arg("dst",str),arg("rep",bit))),
5893 : pattern("batstr", "stringleft", STRbatprefix, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("l",int))),
5894 : pattern("batstr", "stringleft", STRbatprefix, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("l",int),batarg("s1",oid),batarg("s2",oid))),
5895 : pattern("batstr", "stringleft", STRbatprefixcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("l",int))),
5896 : pattern("batstr", "stringleft", STRbatprefixcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("l",int),batarg("s",oid))),
5897 : pattern("batstr", "stringleft", STRbatprefix_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("l",int))),
5898 : pattern("batstr", "stringleft", STRbatprefix_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("l",int),batarg("s",oid))),
5899 : pattern("batstr", "stringright", STRbatsuffix, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("l",int))),
5900 : pattern("batstr", "stringright", STRbatsuffix, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("l",int),batarg("s1",oid),batarg("s2",oid))),
5901 : pattern("batstr", "stringright", STRbatsuffixcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("l",int))),
5902 : pattern("batstr", "stringright", STRbatsuffixcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("l",int),batarg("s",oid))),
5903 : pattern("batstr", "stringright", STRbatsuffix_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("l",int))),
5904 : pattern("batstr", "stringright", STRbatsuffix_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("l",int),batarg("s",oid))),
5905 : pattern("batstr", "locate", STRbatstrLocate, false, "Locate the start position of a string", args(1,3, batarg("",int),batarg("s1",str),batarg("s2",str))),
5906 : pattern("batstr", "locate", STRbatstrLocate, false, "Locate the start position of a string", args(1,5, batarg("",int),batarg("s1",str),batarg("s2",str),batarg("s1",oid),batarg("s2",oid))),
5907 : pattern("batstr", "locate", STRbatstrLocatecst, false, "Locate the start position of a string", args(1,3, batarg("",int),batarg("s1",str),arg("s2",str))),
5908 : pattern("batstr", "locate", STRbatstrLocatecst, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),arg("s2",str),batarg("s",oid))),
5909 : pattern("batstr", "locate", STRbatstrLocate_strcst, false, "Locate the start position of a string", args(1,3, batarg("",int),arg("s1",str),batarg("s2",str))),
5910 : pattern("batstr", "locate", STRbatstrLocate_strcst, false, "Locate the start position of a string", args(1,4, batarg("",int),arg("s1",str),batarg("s2",str),batarg("s",oid))),
5911 : pattern("batstr", "locate3", STRbatstrLocate3, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),batarg("s2",str),batarg("start",int))),
5912 : pattern("batstr", "locate3", STRbatstrLocate3cst, false, "Locate the start position of a string", args(1,4, batarg("",int),batarg("s1",str),arg("s2",str),arg("start",int))),
5913 : pattern("batstr", "insert", STRbatInsert, false, "Insert a string into another", args(1,5, batarg("",str),batarg("s",str),batarg("start",int),batarg("l",int),batarg("s2",str))),
5914 : pattern("batstr", "insert", STRbatInsertcst, false, "Insert a string into another", args(1,5, batarg("",str),batarg("s",str),arg("start",int),arg("l",int),arg("s2",str))),
5915 : pattern("batstr", "replace", STRbatReplace, false, "Insert a string into another", args(1,4, batarg("",str),batarg("s",str),batarg("pat",str),batarg("s2",str))),
5916 : pattern("batstr", "replace", STRbatReplacecst, false, "Insert a string into another", args(1,4, batarg("",str),batarg("s",str),arg("pat",str),arg("s2",str))),
5917 : pattern("batstr", "repeat", STRbatrepeat, false, "", args(1,3, batarg("",str),batarg("s",str),batarg("c",int))),
5918 : pattern("batstr", "repeat", STRbatrepeat, false, "", args(1,5, batarg("",str),batarg("s",str),batarg("c",int),batarg("s1",oid),batarg("s2",oid))),
5919 : pattern("batstr", "repeat", STRbatrepeatcst, false, "", args(1,3, batarg("",str),batarg("s",str),arg("c",int))),
5920 : pattern("batstr", "repeat", STRbatrepeatcst, false, "", args(1,4, batarg("",str),batarg("s",str),arg("c",int),batarg("s",oid))),
5921 : pattern("batstr", "repeat", STRbatrepeat_strcst, false, "", args(1,3, batarg("",str),arg("s",str),batarg("c",int))),
5922 : pattern("batstr", "repeat", STRbatrepeat_strcst, false, "", args(1,4, batarg("",str),arg("s",str),batarg("c",int),batarg("s",oid))),
5923 : pattern("batstr", "space", STRbatSpace, false, "", args(1,2, batarg("",str),batarg("l",int))),
5924 : pattern("batstr", "space", STRbatSpace, false, "", args(1,3, batarg("",str),batarg("l",int),batarg("s",oid))),
5925 : pattern("batstr", "asciify", BATSTRasciify, false, "Transform BAT of strings from UTF8 to ASCII", args(1, 2, batarg("",str), batarg("b",str))),
5926 : pattern("batstr", "asciify", BATSTRasciify, false, "Transform BAT of strings from UTF8 to ASCII", args(1, 3, batarg("",str), batarg("b",str),batarg("s",oid))),
5927 : { .imp=NULL }
5928 : };
5929 : #include "mal_import.h"
5930 : #ifdef _MSC_VER
5931 : #undef read
5932 : #pragma section(".CRT$XCU",read)
5933 : #endif
5934 351 : LIB_STARTUP_FUNC(init_batstr_mal)
5935 351 : { mal_module("batstr", NULL, batstr_init_funcs); }
|