PostgreSQL Source Code git master
jsonpath_scan.l
Go to the documentation of this file.
1%top{
2/*-------------------------------------------------------------------------
3 *
4 * jsonpath_scan.l
5 * Lexical parser for jsonpath datatype
6 *
7 * Splits jsonpath string into tokens represented as JsonPathString structs.
8 * Decodes unicode and hex escaped strings.
9 *
10 * Copyright (c) 2019-2025, PostgreSQL Global Development Group
11 *
12 * IDENTIFICATION
13 * src/backend/utils/adt/jsonpath_scan.l
14 *
15 *-------------------------------------------------------------------------
16 */
17
18#include "postgres.h"
19
20/*
21 * NB: include jsonpath_gram.h only AFTER including jsonpath_internal.h,
22 * because jsonpath_internal.h contains the declaration for JsonPathString.
23 */
24#include "jsonpath_internal.h"
25#include "jsonpath_gram.h"
26
27#include "mb/pg_wchar.h"
28#include "nodes/miscnodes.h"
29#include "nodes/pg_list.h"
30}
31
32%{
34{
36};
37
38static void addstring(bool init, char *s, int l, yyscan_t yyscanner);
39static void addchar(bool init, char c, yyscan_t yyscanner);
40static enum yytokentype checkKeyword(yyscan_t yyscanner);
41static bool parseUnicode(char *s, int l, struct Node *escontext, yyscan_t yyscanner);
42static bool parseHexChar(char *s, struct Node *escontext, yyscan_t yyscanner);
43
44/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
45#undef fprintf
46#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
47
48static void
49fprintf_to_ereport(const char *fmt, const char *msg)
50{
51 ereport(ERROR, (errmsg_internal("%s", msg)));
52}
53
54/* LCOV_EXCL_START */
55
void * yyscan_t
Definition: cubedata.h:67
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int init
Definition: isn.c:74
static bool parseHexChar(char *s, struct Node *escontext, yyscan_t yyscanner)
static bool parseUnicode(char *s, int l, struct Node *escontext, yyscan_t yyscanner)
static void addchar(bool init, char c, yyscan_t yyscanner)
static void fprintf_to_ereport(const char *fmt, const char *msg)
Definition: jsonpath_scan.l:49
static enum yytokentype checkKeyword(yyscan_t yyscanner)
static void addstring(bool init, char *s, int l, yyscan_t yyscanner)
static void const char * fmt
char * c
Definition: nodes.h:129
JsonPathString scanstring
Definition: jsonpath_scan.l:35
56%}
57
58%option 8bit
59%option never-interactive
60%option nodefault
61%option noinput
62%option nounput
63%option noyywrap
64%option warn
65%option prefix="jsonpath_yy"
66%option extra-type="struct jsonpath_yy_extra_type *"
67%option reentrant
68%option bison-bridge
69%option noyyalloc
70%option noyyrealloc
71%option noyyfree
72
73/*
74 * We use exclusive states for quoted and non-quoted strings,
75 * quoted variable names and C-style comments.
76 * Exclusive states:
77 * <xq> - quoted strings
78 * <xnq> - non-quoted strings
79 * <xvq> - quoted variable names
80 * <xc> - C-style comment
81 */
82
83%x xq
84%x xnq
85%x xvq
86%x xc
87
88special [\?\%\$\.\[\]\{\}\‍(\‍)\|\&\!\=<>\@\#\,\*:\-\+\/]
89blank [ \t\n\r\f]
90/* "other" means anything that's not special, blank, or '\' or '"' */
91other [^\?\%\$\.\[\]\{\}\‍(\‍)\|\&\!\=<>\@\#\,\*:\-\+\/\\\" \t\n\r\f]
92
93decdigit [0-9]
94hexdigit [0-9A-Fa-f]
95octdigit [0-7]
96bindigit [0-1]
97
98/* DecimalInteger in ECMAScript; must not start with 0 unless it's exactly 0 */
99decinteger (0|[1-9](_?{decdigit})*)
100/* DecimalDigits in ECMAScript; only used as part of other rules */
101decdigits {decdigit}(_?{decdigit})*
102/* Non-decimal integers; in ECMAScript, these must not have underscore after prefix */
103hexinteger 0[xX]{hexdigit}(_?{hexdigit})*
104octinteger 0[oO]{octdigit}(_?{octdigit})*
105bininteger 0[bB]{bindigit}(_?{bindigit})*
106
107decimal ({decinteger}\.{decdigits}?|\.{decdigits})
108real ({decinteger}|{decimal})[Ee][-+]?{decdigits}
109realfail ({decinteger}|{decimal})[Ee][-+]
110
111decinteger_junk {decinteger}{other}
112decimal_junk {decimal}{other}
113real_junk {real}{other}
114
115unicode \\u({hexdigit}{4}|\{{hexdigit}{1,6}\})
116unicodefail \\u({hexdigit}{0,3}|\{{hexdigit}{0,6})
117hex_char \\x{hexdigit}{2}
118hex_fail \\x{hexdigit}{0,1}
119
121
122<xnq>{other}+ {
123 addstring(false, yytext, yyleng, yyscanner);
124 }
#define yyleng
Definition: scan.l:1124
125
126<xnq>{blank}+ {
127 yylval->str = yyextra->scanstring;
128 BEGIN INITIAL;
129 return checkKeyword(yyscanner);
130 }
#define yyextra
131
132<xnq>\/\* {
133 yylval->str = yyextra->scanstring;
134 BEGIN xc;
135 }
136
137<xnq>({special}|\") {
138 yylval->str = yyextra->scanstring;
139 yyless(0);
140 BEGIN INITIAL;
141 return checkKeyword(yyscanner);
142 }
143
144<xnq><<EOF>> {
145 yylval->str = yyextra->scanstring;
146 BEGIN INITIAL;
147 return checkKeyword(yyscanner);
148 }
149
150<xnq,xq,xvq>\\b { addchar(false, '\b', yyscanner); }
151
152<xnq,xq,xvq>\\f { addchar(false, '\f', yyscanner); }
153
154<xnq,xq,xvq>\\n { addchar(false, '\n', yyscanner); }
155
156<xnq,xq,xvq>\\r { addchar(false, '\r', yyscanner); }
157
158<xnq,xq,xvq>\\t { addchar(false, '\t', yyscanner); }
159
160<xnq,xq,xvq>\\v { addchar(false, '\v', yyscanner); }
161
162<xnq,xq,xvq>{unicode}+ {
163 if (!parseUnicode(yytext, yyleng, escontext, yyscanner))
164 yyterminate();
165 }
166
167<xnq,xq,xvq>{hex_char} {
168 if (!parseHexChar(yytext, escontext, yyscanner))
169 yyterminate();
170 }
171
172<xnq,xq,xvq>{unicode}*{unicodefail} {
173 jsonpath_yyerror(NULL, escontext, yyscanner,
174 "invalid Unicode escape sequence");
175 yyterminate();
176 }
void jsonpath_yyerror(JsonPathParseResult **result, struct Node *escontext, yyscan_t yyscanner, const char *message)
177
178<xnq,xq,xvq>{hex_fail} {
179 jsonpath_yyerror(NULL, escontext, yyscanner,
180 "invalid hexadecimal character sequence");
181 yyterminate();
182 }
183
184<xnq,xq,xvq>{unicode}+\\ {
185 /* throw back the \\, and treat as unicode */
186 yyless(yyleng - 1);
187 if (!parseUnicode(yytext, yyleng, escontext, yyscanner))
188 yyterminate();
189 }
190
191<xnq,xq,xvq>\\. { addchar(false, yytext[1], yyscanner); }
192
193<xnq,xq,xvq>\\ {
194 jsonpath_yyerror(NULL, escontext, yyscanner,
195 "unexpected end after backslash");
196 yyterminate();
197 }
198
199<xq,xvq><<EOF>> {
200 jsonpath_yyerror(NULL, escontext, yyscanner,
201 "unterminated quoted string");
202 yyterminate();
203 }
204
205<xq>\" {
206 yylval->str = yyextra->scanstring;
207 BEGIN INITIAL;
208 return STRING_P;
209 }
210
211<xvq>\" {
212 yylval->str = yyextra->scanstring;
213 BEGIN INITIAL;
214 return VARIABLE_P;
215 }
216
217<xq,xvq>[^\\\"]+ { addstring(false, yytext, yyleng, yyscanner); }
218
219<xc>\*\/ { BEGIN INITIAL; }
220
221<xc>[^\*]+ { }
222
223<xc>\* { }
224
225<xc><<EOF>> {
226 jsonpath_yyerror(NULL, escontext, yyscanner,
227 "unexpected end of comment");
228 yyterminate();
229 }
230\&\& { return AND_P; }
231
232\|\| { return OR_P; }
233
234\! { return NOT_P; }
235
236\*\* { return ANY_P; }
237
238< { return LESS_P; }
239
240<\= { return LESSEQUAL_P; }
241
242\=\= { return EQUAL_P; }
243
244<> { return NOTEQUAL_P; }
245
246\!\= { return NOTEQUAL_P; }
247
248>\= { return GREATEREQUAL_P; }
249
250> { return GREATER_P; }
251
252\${other}+ {
253 addstring(true, yytext + 1, yyleng - 1, yyscanner);
254 addchar(false, '\0', yyscanner);
255 yylval->str = yyextra->scanstring;
256 return VARIABLE_P;
257 }
258
259\$\" {
260 addchar(true, '\0', yyscanner);
261 BEGIN xvq;
262 }
263
264{special} { return *yytext; }
265
266{blank}+ { /* ignore */ }
267
268\/\* {
269 addchar(true, '\0', yyscanner);
270 BEGIN xc;
271 }
272
273{real} {
274 addstring(true, yytext, yyleng, yyscanner);
275 addchar(false, '\0', yyscanner);
276 yylval->str = yyextra->scanstring;
277 return NUMERIC_P;
278 }
279
280{decimal} {
281 addstring(true, yytext, yyleng, yyscanner);
282 addchar(false, '\0', yyscanner);
283 yylval->str = yyextra->scanstring;
284 return NUMERIC_P;
285 }
286
287{decinteger} {
288 addstring(true, yytext, yyleng, yyscanner);
289 addchar(false, '\0', yyscanner);
290 yylval->str = yyextra->scanstring;
291 return INT_P;
292 }
293
294{hexinteger} {
295 addstring(true, yytext, yyleng, yyscanner);
296 addchar(false, '\0', yyscanner);
297 yylval->str = yyextra->scanstring;
298 return INT_P;
299 }
300
301{octinteger} {
302 addstring(true, yytext, yyleng, yyscanner);
303 addchar(false, '\0', yyscanner);
304 yylval->str = yyextra->scanstring;
305 return INT_P;
306 }
307
308{bininteger} {
309 addstring(true, yytext, yyleng, yyscanner);
310 addchar(false, '\0', yyscanner);
311 yylval->str = yyextra->scanstring;
312 return INT_P;
313 }
314
315{realfail} {
316 jsonpath_yyerror(NULL, escontext, yyscanner,
317 "invalid numeric literal");
318 yyterminate();
319 }
320{decinteger_junk} {
321 jsonpath_yyerror(NULL, escontext, yyscanner,
322 "trailing junk after numeric literal");
323 yyterminate();
324 }
325{decimal_junk} {
326 jsonpath_yyerror(NULL, escontext, yyscanner,
327 "trailing junk after numeric literal");
328 yyterminate();
329 }
330{real_junk} {
331 jsonpath_yyerror(NULL, escontext, yyscanner,
332 "trailing junk after numeric literal");
333 yyterminate();
334 }
335\" {
336 addchar(true, '\0', yyscanner);
337 BEGIN xq;
338 }
339
340\\ {
341 yyless(0);
342 addchar(true, '\0', yyscanner);
343 BEGIN xnq;
344 }
345
346{other}+ {
347 addstring(true, yytext, yyleng, yyscanner);
348 BEGIN xnq;
349 }
350
351<<EOF>> { yyterminate(); }
352
353%%
354
355/* LCOV_EXCL_STOP */
356
357/* see scan.l */
358#undef yyextra
359#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
360
361void
362jsonpath_yyerror(JsonPathParseResult **result, struct Node *escontext,
363 yyscan_t yyscanner,
364 const char *message)
365{
366 struct yyguts_t *yyg = (struct yyguts_t *) yyscanner; /* needed for yytext
367 * macro */
368
369 /* don't overwrite escontext if it's already been set */
370 if (SOFT_ERROR_OCCURRED(escontext))
371 return;
372
373 if (*yytext == YY_END_OF_BUFFER_CHAR)
374 {
375 errsave(escontext,
376 (errcode(ERRCODE_SYNTAX_ERROR),
377 /* translator: %s is typically "syntax error" */
378 errmsg("%s at end of jsonpath input", _(message))));
379 }
380 else
381 {
382 errsave(escontext,
383 (errcode(ERRCODE_SYNTAX_ERROR),
384 /* translator: first %s is typically "syntax error" */
385 errmsg("%s at or near \"%s\" of jsonpath input",
386 _(message), yytext)));
387 }
388}
389
390typedef struct JsonPathKeyword
391{
394 int val;
395 const char *keyword;
397
398/*
399 * Array of key words should be sorted by length and then
400 * alphabetical order
401 */
402static const JsonPathKeyword keywords[] = {
403 {2, false, IS_P, "is"},
404 {2, false, TO_P, "to"},
405 {3, false, ABS_P, "abs"},
406 {3, false, LAX_P, "lax"},
407 {4, false, DATE_P, "date"},
408 {4, false, FLAG_P, "flag"},
409 {4, false, LAST_P, "last"},
410 {4, true, NULL_P, "null"},
411 {4, false, SIZE_P, "size"},
412 {4, false, TIME_P, "time"},
413 {4, true, TRUE_P, "true"},
414 {4, false, TYPE_P, "type"},
415 {4, false, WITH_P, "with"},
416 {5, true, FALSE_P, "false"},
417 {5, false, FLOOR_P, "floor"},
418 {6, false, BIGINT_P, "bigint"},
419 {6, false, DOUBLE_P, "double"},
420 {6, false, EXISTS_P, "exists"},
421 {6, false, NUMBER_P, "number"},
422 {6, false, STARTS_P, "starts"},
423 {6, false, STRICT_P, "strict"},
424 {6, false, STRINGFUNC_P, "string"},
425 {7, false, BOOLEAN_P, "boolean"},
426 {7, false, CEILING_P, "ceiling"},
427 {7, false, DECIMAL_P, "decimal"},
428 {7, false, INTEGER_P, "integer"},
429 {7, false, TIME_TZ_P, "time_tz"},
430 {7, false, UNKNOWN_P, "unknown"},
431 {8, false, DATETIME_P, "datetime"},
432 {8, false, KEYVALUE_P, "keyvalue"},
433 {9, false, TIMESTAMP_P, "timestamp"},
434 {10, false, LIKE_REGEX_P, "like_regex"},
435 {12, false, TIMESTAMP_TZ_P, "timestamp_tz"},
436};
437
438/*
439 * Check if current scanstring value is a keyword
440 */
441static enum yytokentype
443{
444 int res = IDENT_P;
445 int diff;
446 const JsonPathKeyword *StopLow = keywords,
447 *StopHigh = keywords + lengthof(keywords),
448 *StopMiddle;
449
450 if (yyextra->scanstring.len > keywords[lengthof(keywords) - 1].len)
451 return res;
452
453 while (StopLow < StopHigh)
454 {
455 StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
456
457 if (StopMiddle->len == yyextra->scanstring.len)
458 diff = pg_strncasecmp(StopMiddle->keyword, yyextra->scanstring.val,
459 yyextra->scanstring.len);
460 else
461 diff = StopMiddle->len - yyextra->scanstring.len;
462
463 if (diff < 0)
464 StopLow = StopMiddle + 1;
465 else if (diff > 0)
466 StopHigh = StopMiddle;
467 else
468 {
469 if (StopMiddle->lowercase)
470 diff = strncmp(StopMiddle->keyword, yyextra->scanstring.val,
471 yyextra->scanstring.len);
472
473 if (diff == 0)
474 res = StopMiddle->val;
475
476 break;
477 }
478 }
479
480 return res;
481}
482
483/*
484 * Resize scanstring so that it can append string of given length.
485 * Reinitialize if required.
486 */
487static void
488resizeString(bool init, int appendLen, yyscan_t yyscanner)
489{
490 if (init)
491 {
492 yyextra->scanstring.total = Max(32, appendLen);
493 yyextra->scanstring.val = (char *) palloc(yyextra->scanstring.total);
494 yyextra->scanstring.len = 0;
495 }
496 else
497 {
498 if (yyextra->scanstring.len + appendLen >= yyextra->scanstring.total)
499 {
500 while (yyextra->scanstring.len + appendLen >= yyextra->scanstring.total)
501 yyextra->scanstring.total *= 2;
502 yyextra->scanstring.val = repalloc(yyextra->scanstring.val, yyextra->scanstring.total);
503 }
504 }
505}
506
507/* Add set of bytes at "s" of length "l" to scanstring */
508static void
509addstring(bool init, char *s, int l, yyscan_t yyscanner)
510{
511 resizeString(init, l + 1, yyscanner);
512 memcpy(yyextra->scanstring.val + yyextra->scanstring.len, s, l);
513 yyextra->scanstring.len += l;
514}
515
516/* Add single byte "c" to scanstring */
517static void
518addchar(bool init, char c, yyscan_t yyscanner)
519{
520 resizeString(init, 1, yyscanner);
521 yyextra->scanstring.val[yyextra->scanstring.len] = c;
522 if (c != '\0')
523 yyextra->scanstring.len++;
524}
525
526/* Interface to jsonpath parser */
528parsejsonpath(const char *str, int len, struct Node *escontext)
529{
531 yyscan_t scanner;
532 struct jsonpath_yy_extra_type yyext;
533
534 if (jsonpath_yylex_init(&scanner) != 0)
535 elog(ERROR, "yylex_init() failed: %m");
536
537 yyset_extra(&yyext, scanner);
538
539 if (len <= 0)
540 len = strlen(str);
541
542 jsonpath_yy_scan_bytes(str, len, scanner);
543
544 if (jsonpath_yyparse(&parseresult, escontext, scanner) != 0)
545 jsonpath_yyerror(NULL, escontext, scanner, "invalid input"); /* shouldn't happen */
546
547 jsonpath_yylex_destroy(scanner);
548
549 return parseresult;
550}
551
552/* Turn hex character into integer */
553static bool
554hexval(char c, int *result, struct Node *escontext, yyscan_t yyscanner)
555{
556 if (c >= '0' && c <= '9')
557 {
558 *result = c - '0';
559 return true;
560 }
561 if (c >= 'a' && c <= 'f')
562 {
563 *result = c - 'a' + 0xA;
564 return true;
565 }
566 if (c >= 'A' && c <= 'F')
567 {
568 *result = c - 'A' + 0xA;
569 return true;
570 }
571 jsonpath_yyerror(NULL, escontext, yyscanner, "invalid hexadecimal digit");
572 return false;
573}
574
575/* Add given unicode character to scanstring */
576static bool
577addUnicodeChar(int ch, struct Node *escontext, yyscan_t yyscanner)
578{
579 if (ch == 0)
580 {
581 /* We can't allow this, since our TEXT type doesn't */
582 ereturn(escontext, false,
583 (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER),
584 errmsg("unsupported Unicode escape sequence"),
585 errdetail("\\u0000 cannot be converted to text.")));
586 }
587 else
588 {
589 char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
590
591 /*
592 * If we're trapping the error status, call the noerror form of the
593 * conversion function. Otherwise call the normal form which provides
594 * more detailed errors.
595 */
596
597 if (!escontext || !IsA(escontext, ErrorSaveContext))
598 pg_unicode_to_server(ch, (unsigned char *) cbuf);
599 else if (!pg_unicode_to_server_noerror(ch, (unsigned char *) cbuf))
600 ereturn(escontext, false,
601 (errcode(ERRCODE_SYNTAX_ERROR),
602 errmsg("could not convert Unicode to server encoding")));
603 addstring(false, cbuf, strlen(cbuf), yyscanner);
604 }
605 return true;
606}
607
608/* Add unicode character, processing any surrogate pairs */
609static bool
610addUnicode(int ch, int *hi_surrogate, struct Node *escontext, yyscan_t yyscanner)
611{
613 {
614 if (*hi_surrogate != -1)
615 ereturn(escontext, false,
616 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
617 errmsg("invalid input syntax for type %s", "jsonpath"),
618 errdetail("Unicode high surrogate must not follow "
619 "a high surrogate.")));
620 *hi_surrogate = ch;
621 return true;
622 }
623 else if (is_utf16_surrogate_second(ch))
624 {
625 if (*hi_surrogate == -1)
626 ereturn(escontext, false,
627 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
628 errmsg("invalid input syntax for type %s", "jsonpath"),
629 errdetail("Unicode low surrogate must follow a high "
630 "surrogate.")));
631 ch = surrogate_pair_to_codepoint(*hi_surrogate, ch);
632 *hi_surrogate = -1;
633 }
634 else if (*hi_surrogate != -1)
635 {
636 ereturn(escontext, false,
637 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
638 errmsg("invalid input syntax for type %s", "jsonpath"),
639 errdetail("Unicode low surrogate must follow a high "
640 "surrogate.")));
641 }
642
643 return addUnicodeChar(ch, escontext, yyscanner);
644}
645
646/*
647 * parseUnicode was adopted from json_lex_string() in
648 * src/backend/utils/adt/json.c
649 */
650static bool
651parseUnicode(char *s, int l, struct Node *escontext, yyscan_t yyscanner)
652{
653 int i = 2;
654 int hi_surrogate = -1;
655
656 for (i = 2; i < l; i += 2) /* skip '\u' */
657 {
658 int ch = 0;
659 int j,
660 si;
661
662 if (s[i] == '{') /* parse '\u{XX...}' */
663 {
664 while (s[++i] != '}' && i < l)
665 {
666 if (!hexval(s[i], &si, escontext, yyscanner))
667 return false;
668 ch = (ch << 4) | si;
669 }
670 i++; /* skip '}' */
671 }
672 else /* parse '\uXXXX' */
673 {
674 for (j = 0; j < 4 && i < l; j++)
675 {
676 if (!hexval(s[i++], &si, escontext, yyscanner))
677 return false;
678 ch = (ch << 4) | si;
679 }
680 }
681
682 if (!addUnicode(ch, &hi_surrogate, escontext, yyscanner))
683 return false;
684 }
685
686 if (hi_surrogate != -1)
687 {
688 ereturn(escontext, false,
689 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
690 errmsg("invalid input syntax for type %s", "jsonpath"),
691 errdetail("Unicode low surrogate must follow a high "
692 "surrogate.")));
693 }
694
695 return true;
696}
697
698/* Parse sequence of hex-encoded characters */
699static bool
700parseHexChar(char *s, struct Node *escontext, yyscan_t yyscanner)
701{
702 int s2,
703 s3,
704 ch;
705
706 if (!hexval(s[2], &s2, escontext, yyscanner))
707 return false;
708 if (!hexval(s[3], &s3, escontext, yyscanner))
709 return false;
710
711 ch = (s2 << 4) | s3;
712
713 return addUnicodeChar(ch, escontext, yyscanner);
714}
715
716/*
717 * Interface functions to make flex use palloc() instead of malloc().
718 * It'd be better to make these static, but flex insists otherwise.
719 */
720
721void *
722jsonpath_yyalloc(yy_size_t bytes, yyscan_t yyscanner)
723{
724 return palloc(bytes);
725}
726
727void *
728jsonpath_yyrealloc(void *ptr, yy_size_t bytes, yyscan_t yyscanner)
729{
730 if (ptr)
731 return repalloc(ptr, bytes);
732 else
733 return palloc(bytes);
734}
735
736void
737jsonpath_yyfree(void *ptr, yyscan_t yyscanner)
738{
739 if (ptr)
740 pfree(ptr);
741}
#define Max(x, y)
Definition: c.h:955
int16_t int16
Definition: c.h:483
#define lengthof(array)
Definition: c.h:745
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define _(x)
Definition: elog.c:90
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
#define errsave(context,...)
Definition: elog.h:261
#define elog(elevel,...)
Definition: elog.h:225
const char * str
int j
Definition: isn.c:73
int i
Definition: isn.c:72
TestSpec parseresult
int jsonpath_yyparse(JsonPathParseResult **result, struct Node *escontext, yyscan_t yyscanner)
static void resizeString(bool init, int appendLen, yyscan_t yyscanner)
struct JsonPathKeyword JsonPathKeyword
void jsonpath_yyfree(void *ptr, yyscan_t yyscanner)
void * jsonpath_yyrealloc(void *ptr, yy_size_t bytes, yyscan_t yyscanner)
JsonPathParseResult * parsejsonpath(const char *str, int len, struct Node *escontext)
static bool addUnicode(int ch, int *hi_surrogate, struct Node *escontext, yyscan_t yyscanner)
static const JsonPathKeyword keywords[]
void * jsonpath_yyalloc(yy_size_t bytes, yyscan_t yyscanner)
static bool hexval(char c, int *result, struct Node *escontext, yyscan_t yyscanner)
static bool addUnicodeChar(int ch, struct Node *escontext, yyscan_t yyscanner)
bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s)
Definition: mbutils.c:926
void pg_unicode_to_server(pg_wchar c, unsigned char *s)
Definition: mbutils.c:864
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:53
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
const void size_t len
#define MAX_UNICODE_EQUIVALENT_STRING
Definition: pg_wchar.h:329
static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
Definition: pg_wchar.h:537
static bool is_utf16_surrogate_first(pg_wchar c)
Definition: pg_wchar.h:525
static bool is_utf16_surrogate_second(pg_wchar c)
Definition: pg_wchar.h:531
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
char * s2
char * s3
const char * keyword