/* * Create a textual representation of a JsonbValue that will serve as a GIN * key in a jsonb_ops index. is_key is true if the JsonbValue is a key, * or if it is a string array element (since we pretend those are keys, * see jsonb.h). */ static Datum make_scalar_key(const JsonbValue *scalarVal, bool is_key) { Datum item; char *cstr; switch (scalarVal->type) { case jbvNull: Assert(!is_key); item = make_text_key(JGINFLAG_NULL, "", 0); break; case jbvBool: Assert(!is_key); item = make_text_key(JGINFLAG_BOOL, scalarVal->val.boolean ? "t" : "f", 1); break; case jbvNumeric: Assert(!is_key); /* * A normalized textual representation, free of trailing zeroes, * is required so that numerically equal values will produce equal * strings. * * It isn't ideal that numerics are stored in a relatively bulky * textual format. However, it's a notationally convenient way of * storing a "union" type in the GIN B-Tree, and indexing Jsonb * strings takes precedence. */ cstr = numeric_normalize(scalarVal->val.numeric); item = make_text_key(JGINFLAG_NUM, cstr, strlen(cstr)); pfree(cstr); break; case jbvString: item = make_text_key(is_key ? JGINFLAG_KEY : JGINFLAG_STR, scalarVal->val.string.val, scalarVal->val.string.len); break; default: elog(ERROR, "unrecognized jsonb scalar type: %d", scalarVal->type); item = 0; /* keep compiler quiet */ break; } return item; }
/* * Create a textual representation of a jsonbValue for GIN storage. */ static text * make_scalar_key(const JsonbValue * scalarVal, char flag) { text *item; char *cstr; switch (scalarVal->type) { case jbvNull: item = make_text_key("n", 1, flag); break; case jbvBool: item = make_text_key(scalarVal->val.boolean ? "t" : "f", 1, flag); break; case jbvNumeric: /* * A normalized textual representation, free of trailing zeroes is * is required. * * It isn't ideal that numerics are stored in a relatively bulky * textual format. However, it's a notationally convenient way of * storing a "union" type in the GIN B-Tree, and indexing Jsonb * strings takes precedence. */ cstr = numeric_normalize(scalarVal->val.numeric); item = make_text_key(cstr, strlen(cstr), flag); pfree(cstr); break; case jbvString: item = make_text_key(scalarVal->val.string.val, scalarVal->val.string.len, flag); break; default: elog(ERROR, "invalid jsonb scalar type"); } return item; }