25#include "utils/fmgrprotos.h"
74 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
75 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
76 errdetail(
"Initial element must be an array."));
82 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
83 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
90 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
91 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
92 errdetail(
"Value of \"%s\" must be an array of attribute numbers.",
99 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
100 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
101 errdetail(
"Attribute lists can only contain attribute numbers."));
107 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
108 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
109 errdetail(
"Value of \"%s\" must be an integer.",
115 "object start of \"%s\" found in unexpected parse state: %d.",
116 "pg_ndistinct", (
int)
parse->state);
139 "object end of \"%s\" found in unexpected parse state: %d.",
140 "pg_ndistinct", (
int)
parse->state);
142 if (!
parse->found_attributes)
145 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
146 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
147 errdetail(
"Item must contain \"%s\" key.",
152 if (!
parse->found_ndistinct)
155 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
156 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
157 errdetail(
"Item must contain \"%s\" key.",
170 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
171 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
172 errdetail(
"The \"%s\" key must contain an array of at least %d and no more than %d attributes.",
183 for (
int i = 0;
i < natts;
i++)
191 parse->ndistinct = 0;
192 parse->found_attributes =
false;
193 parse->found_ndistinct =
false;
212 switch (
parse->state)
224 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
225 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
226 errdetail(
"Array has been found at an unexpected location."));
244 switch (
parse->state)
258 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
259 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
260 errdetail(
"The \"%s\" key must be a non-empty array.",
273 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
274 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
275 errdetail(
"Item array cannot be empty."));
285 "array end of \"%s\" found in unexpected parse state: %d.",
286 "pg_ndistinct", (
int)
parse->state);
307 if (
parse->found_attributes)
310 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
311 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
312 errdetail(
"Multiple \"%s\" keys are not allowed.",
316 parse->found_attributes =
true;
323 if (
parse->found_ndistinct)
326 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
327 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
328 errdetail(
"Multiple \"%s\" keys are not allowed.",
332 parse->found_ndistinct =
true;
338 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
339 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
340 errdetail(
"Only allowed keys are \"%s\" and \"%s\".",
357 switch (
parse->state)
364 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
365 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
366 errdetail(
"Attribute number array cannot be null."));
374 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
375 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
376 errdetail(
"Item list elements cannot be null."));
382 "array element start of \"%s\" found in unexpected parse state: %d.",
383 "pg_ndistinct", (
int)
parse->state);
408 return ((
cur > prev) || (
cur < 0));
426 switch (
parse->state)
431 if (escontext.error_occurred)
434 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
435 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
447 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
448 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
449 errdetail(
"Invalid \"%s\" element has been found: %d.",
461 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
462 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
463 errdetail(
"Invalid \"%s\" element has been found: %d cannot follow %d.",
481 if (!escontext.error_occurred)
488 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
489 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
490 errdetail(
"Key \"%s\" has an incorrect value.",
496 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
497 errmsg(
"malformed pg_ndistinct: \"%s\"",
parse->str),
498 errdetail(
"Unexpected scalar has been found."));
517 if (
a->nattributes !=
b->nattributes)
520 for (
int i = 0;
i <
a->nattributes;
i++)
522 if (
a->attributes[
i] !=
b->attributes[
i])
593 int item_most_attrs = 0;
594 int item_most_attrs_idx = 0;
596 switch (
parse->state)
607 "cannot have empty item list after parsing success.");
613 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
614 errmsg(
"malformed pg_ndistinct: \"%s\"",
str),
621 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
622 errmsg(
"malformed pg_ndistinct: \"%s\"",
str),
623 errdetail(
"Unexpected end state has been found: %d.",
parse->state));
642 for (
int j = 0;
j <
i;
j++)
649 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
650 errmsg(
"malformed pg_ndistinct: \"%s\"",
str),
651 errdetail(
"Duplicated \"%s\" array has been found: [%s].",
674 item_most_attrs_idx =
i;
687 if (
i == item_most_attrs_idx)
691 &ndistinct->
items[item_most_attrs_idx]))
699 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
700 errmsg(
"malformed pg_ndistinct: \"%s\"",
str),
701 errdetail(
"\"%s\" array [%s] must be a subset of array [%s].",
703 item_list, refitem_list));
747 sem_action.
semstate = (
void *) &parse_state;
778 errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
779 errmsg(
"malformed pg_ndistinct: \"%s\"",
str),
780 errdetail(
"Input data must be valid JSON."));
810 elog(
ERROR,
"invalid zero-length attribute array in MVNDistinct");
835 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
836 errmsg(
"cannot accept a value of type %s",
"pg_ndistinct")));
Datum byteasend(PG_FUNCTION_ARGS)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define errsave(context,...)
#define ereport(elevel,...)
#define palloc_object(type)
#define PG_GETARG_BYTEA_PP(n)
#define PG_RETURN_BYTEA_P(x)
#define PG_RETURN_CSTRING(x)
#define PG_GETARG_CSTRING(n)
Assert(PointerIsAligned(start, uint64))
JsonParseErrorType pg_parse_json(JsonLexContext *lex, const JsonSemAction *sem)
JsonLexContext * makeJsonLexContextCstringLen(JsonLexContext *lex, const char *json, size_t len, int encoding, bool need_escapes)
void freeJsonLexContext(JsonLexContext *lex)
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
void list_free(List *list)
void list_free_deep(List *list)
void pfree(void *pointer)
void * palloc0(Size size)
#define SOFT_ERROR_OCCURRED(escontext)
MVNDistinct * statext_ndistinct_deserialize(bytea *data)
bytea * statext_ndistinct_serialize(MVNDistinct *ndistinct)
int32 pg_strtoint32_safe(const char *s, Node *escontext)
int16 pg_strtoint16_safe(const char *s, Node *escontext)
static int list_length(const List *l)
static void * list_nth(const List *list, int n)
static int list_nth_int(const List *list, int n)
Datum pg_ndistinct_out(PG_FUNCTION_ARGS)
static char * item_attnum_list(const MVNDistinctItem *item)
static JsonParseErrorType ndistinct_array_element_start(void *state, bool isnull)
static JsonParseErrorType ndistinct_array_end(void *state)
static JsonParseErrorType ndistinct_object_start(void *state)
Datum pg_ndistinct_in(PG_FUNCTION_ARGS)
static JsonParseErrorType ndistinct_array_start(void *state)
Datum pg_ndistinct_recv(PG_FUNCTION_ARGS)
static JsonParseErrorType ndistinct_scalar(void *state, char *token, JsonTokenType tokentype)
static bytea * build_mvndistinct(NDistinctParseState *parse, char *str)
static JsonParseErrorType ndistinct_object_end(void *state)
static bool item_attributes_eq(const MVNDistinctItem *a, const MVNDistinctItem *b)
@ NDIST_EXPECT_ATTNUM_LIST
static JsonParseErrorType ndistinct_object_field_start(void *state, char *fname, bool isnull)
Datum pg_ndistinct_send(PG_FUNCTION_ARGS)
static bool item_has_attnum(const MVNDistinctItem *item, AttrNumber attnum)
static bool item_is_attnum_subset(const MVNDistinctItem *item, const MVNDistinctItem *refitem)
static bool valid_subsequent_attnum(AttrNumber prev, AttrNumber cur)
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
#define STATS_NDISTINCT_MAGIC
#define STATS_NDISTINCT_TYPE_BASIC
#define STATS_MAX_DIMENSIONS
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
json_struct_action array_end
json_struct_action object_start
json_ofield_action object_field_start
json_aelem_action array_element_start
json_scalar_action scalar
json_aelem_action array_element_end
json_struct_action array_start
json_struct_action object_end
json_ofield_action object_field_end
MVNDistinctItem items[FLEXIBLE_ARRAY_MEMBER]
NDistinctSemanticState state