codestyle

This commit is contained in:
gentle_hu
2021-09-02 20:28:19 +08:00
parent a326d87e6d
commit ecf980b67b
8 changed files with 690 additions and 1382 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
/*-------------------------------------------------------------------------
/* -------------------------------------------------------------------------
*
* jsonb.c
* jsonb.cpp
* I/O routines for jsonb type
*
* Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
* Portions Copyright (c) 2021 Huawei Technologies Co.,Ltd.
* Copyright (c) 2014, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/utils/adt/jsonb.c
* src/common/backend/utils/adt/jsonb.cpp
*
*-------------------------------------------------------------------------
* -------------------------------------------------------------------------
*/
#include "postgres.h"
@ -19,8 +19,7 @@
#include "utils/jsonapi.h"
#include "utils/jsonb.h"
typedef struct JsonbInState
{
typedef struct JsonbInState {
JsonbParseState *parseState;
JsonbValue *res;
} JsonbInState;
@ -32,17 +31,16 @@ static void jsonb_in_object_end(void *pstate);
static void jsonb_in_array_start(void *pstate);
static void jsonb_in_array_end(void *pstate);
static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull);
static void jsonb_put_escaped_value(StringInfo out, JsonbValue * scalarVal);
static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal);
static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype);
char *JsonbToCString(StringInfo out, char *in, int estimated_len);
/*
* jsonb type input function
*/
Datum
jsonb_in(PG_FUNCTION_ARGS)
Datum jsonb_in(PG_FUNCTION_ARGS)
{
char *json = PG_GETARG_CSTRING(0);
char *json = PG_GETARG_CSTRING(0);
json = json == NULL ? pstrdup("") : json;
return jsonb_from_cstring(json, strlen(json));
@ -56,8 +54,7 @@ jsonb_in(PG_FUNCTION_ARGS)
* can change the binary format sent in future if necessary. For now,
* only version 1 is supported.
*/
Datum
jsonb_recv(PG_FUNCTION_ARGS)
Datum jsonb_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
int version = pq_getmsgint(buf, 1);
@ -75,8 +72,7 @@ jsonb_recv(PG_FUNCTION_ARGS)
/*
* jsonb type output function
*/
Datum
jsonb_out(PG_FUNCTION_ARGS)
Datum jsonb_out(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB(0);
char *out = NULL;
@ -91,8 +87,7 @@ jsonb_out(PG_FUNCTION_ARGS)
*
* Just send jsonb as a version number, then a string of text
*/
Datum
jsonb_send(PG_FUNCTION_ARGS)
Datum jsonb_send(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB(0);
StringInfoData buf;
@ -116,8 +111,7 @@ jsonb_send(PG_FUNCTION_ARGS)
* This function is here because the analog json function is in json.c, since
* it uses the json parser internals not exposed elsewhere.
*/
Datum
jsonb_typeof(PG_FUNCTION_ARGS)
Datum jsonb_typeof(PG_FUNCTION_ARGS)
{
Jsonb *in = PG_GETARG_JSONB(0);
JsonbIterator *it = NULL;
@ -130,9 +124,7 @@ jsonb_typeof(PG_FUNCTION_ARGS)
result = "array";
} else {
Assert(JB_ROOT_IS_SCALAR(in));
it = JsonbIteratorInit(VARDATA_ANY(in));
/*
* A root scalar is stored as an array of one element, so we get the
* array and then its first (and only) member.
@ -168,8 +160,7 @@ jsonb_typeof(PG_FUNCTION_ARGS)
*
* Uses the json parser (with hooks) to construct a jsonb.
*/
static inline Datum
jsonb_from_cstring(char *json, int len)
static inline Datum jsonb_from_cstring(char *json, int len)
{
JsonLexContext *lex = NULL;
JsonbInState state;
@ -182,7 +173,6 @@ jsonb_from_cstring(char *json, int len)
lex = makeJsonLexContextCstringLen(json, len, true);
sem.semstate = (void *) &state;
sem.object_start = jsonb_in_object_start;
sem.array_start = jsonb_in_array_start;
sem.object_end = jsonb_in_object_end;
@ -196,8 +186,7 @@ jsonb_from_cstring(char *json, int len)
PG_RETURN_POINTER(JsonbValueToJsonb(state.res));
}
static size_t
checkStringLen(size_t len)
static size_t checkStringLen(size_t len)
{
if (len > JENTRY_POSMASK) {
ereport(ERROR,
@ -210,40 +199,31 @@ checkStringLen(size_t len)
return len;
}
static void
jsonb_in_object_start(void *pstate)
static void jsonb_in_object_start(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_OBJECT, NULL);
}
static void
jsonb_in_object_end(void *pstate)
static void jsonb_in_object_end(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_END_OBJECT, NULL);
}
static void
jsonb_in_array_start(void *pstate)
static void jsonb_in_array_start(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_BEGIN_ARRAY, NULL);
}
static void
jsonb_in_array_end(void *pstate)
static void jsonb_in_array_end(void *pstate)
{
JsonbInState *_state = (JsonbInState *) pstate;
_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
}
static void
jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
{
JsonbInState *_state = (JsonbInState *) pstate;
JsonbValue v;
@ -257,8 +237,7 @@ jsonb_in_object_field_start(void *pstate, char *fname, bool isnull)
_state->res = pushJsonbValue(&_state->parseState, WJB_KEY, &v);
}
static void
jsonb_put_escaped_value(StringInfo out, JsonbValue * scalarVal)
static void jsonb_put_escaped_value(StringInfo out, JsonbValue * scalarVal)
{
switch (scalarVal->type) {
case jbvNull:
@ -286,16 +265,13 @@ jsonb_put_escaped_value(StringInfo out, JsonbValue * scalarVal)
/*
* For jsonb we always want the de-escaped value - that's what's in token
*/
static void
jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
{
JsonbInState *_state = (JsonbInState *) pstate;
JsonbValue v;
v.estSize = sizeof(JEntry);
switch (tokentype) {
case JSON_TOKEN_STRING:
Assert (token != NULL);
v.type = jbvString;
@ -311,7 +287,7 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
Assert (token != NULL);
v.type = jbvNumeric;
v.numeric = DatumGetNumeric(DirectFunctionCall3(numeric_in, CStringGetDatum(token), 0, -1));
v.estSize += VARSIZE_ANY(v.numeric) + sizeof(JEntry) /* alignment */ ;
v.estSize += VARSIZE_ANY(v.numeric) + sizeof(JEntry); /* alignment */
break;
case JSON_TOKEN_TRUE:
v.type = jbvBool;
@ -343,7 +319,6 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
_state->res = pushJsonbValue(&_state->parseState, WJB_END_ARRAY, NULL);
} else {
JsonbValue *o = &_state->parseState->contVal;
switch (o->type) {
case jbvArray:
_state->res = pushJsonbValue(&_state->parseState, WJB_ELEM, &v);
@ -368,8 +343,7 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype)
* caller wants access to the len attribute without having to call strlen, e.g.
* if they are converting it to a text* object.
*/
char *
JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len)
char *JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len)
{
bool first = true;
JsonbIterator *it = NULL;
@ -382,11 +356,9 @@ JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len)
out = makeStringInfo();
enlargeStringInfo(out, (estimated_len >= 0) ? estimated_len : 64);
it = JsonbIteratorInit(in);
while (redo_switch ||
((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)) {
while (redo_switch || ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE)) {
redo_switch = false;
switch (type) {
case WJB_BEGIN_ARRAY:
@ -421,7 +393,6 @@ JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len)
jsonb_put_escaped_value(out, &v);
} else {
Assert(type == WJB_BEGIN_OBJECT || type == WJB_BEGIN_ARRAY);
/*
* We need to rerun the current switch() since we need to
* output the object which we just got from the iterator
@ -435,7 +406,6 @@ JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len)
appendBinaryStringInfo(out, ", ", 2);
else
first = false;
jsonb_put_escaped_value(out, &v);
break;
case WJB_END_ARRAY:
@ -453,8 +423,6 @@ JsonbToCString(StringInfo out, JsonbSuperHeader in, int estimated_len)
elog(ERROR, "unknown flag of jsonb iterator");
}
}
Assert(level == 0);
return out->data;
}

View File

@ -1,19 +1,18 @@
/*-------------------------------------------------------------------------
/* -------------------------------------------------------------------------
*
* jsonb_gin.c
* jsonb_gin.cpp
* GIN support functions for jsonb
*
* Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
* Portions Copyright (c) 2021 Huawei Technologies Co.,Ltd.
* Copyright (c) 2014, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src/backend/utils/adt/jsonb_gin.c
* src/common/backend/utils/adt/jsonb_gin.cpp
*
*-------------------------------------------------------------------------
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/gin.h"
#include "access/skey.h"
#include "catalog/pg_collation.h"
@ -21,22 +20,20 @@
#include "utils/builtins.h"
#include "utils/jsonb.h"
typedef struct PathHashStack
{
typedef struct PathHashStack {
uint32 hash;
struct PathHashStack *parent;
} PathHashStack;
static text *make_text_key(const char *str, int len, char flag);
static text *make_scalar_key(const JsonbValue * scalarVal, char flag);
static text *make_scalar_key(const JsonbValue *scalarVal, char flag);
/*
*
* jsonb_ops GIN opclass support functions
*
*/
Datum
gin_compare_jsonb(PG_FUNCTION_ARGS)
Datum gin_compare_jsonb(PG_FUNCTION_ARGS)
{
text *arg1 = PG_GETARG_TEXT_PP(0);
text *arg2 = PG_GETARG_TEXT_PP(1);
@ -48,21 +45,18 @@ gin_compare_jsonb(PG_FUNCTION_ARGS)
a1p = VARDATA_ANY(arg1);
a2p = VARDATA_ANY(arg2);
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
/* Compare text as bttextcmp does, but always using C collation */
result = varstr_cmp(a1p, len1, a2p, len2, C_COLLATION_OID);
PG_FREE_IF_COPY(arg1, 0);
PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_INT32(result);
}
Datum
gin_extract_jsonb(PG_FUNCTION_ARGS)
Datum gin_extract_jsonb(PG_FUNCTION_ARGS)
{
Jsonb *jb = (Jsonb *) PG_GETARG_JSONB(0);
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
@ -79,9 +73,7 @@ gin_extract_jsonb(PG_FUNCTION_ARGS)
}
entries = (Datum *) palloc(sizeof(Datum) * total);
it = JsonbIteratorInit(VARDATA(jb));
while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) {
if (i >= total) {
total *= 2;
@ -141,12 +133,10 @@ gin_extract_jsonb(PG_FUNCTION_ARGS)
}
*nentries = i;
PG_RETURN_POINTER(entries);
}
Datum
gin_extract_jsonb_query(PG_FUNCTION_ARGS)
Datum gin_extract_jsonb_query(PG_FUNCTION_ARGS)
{
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
StrategyNumber strategy = PG_GETARG_UINT16(2);
@ -156,9 +146,7 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS)
if (strategy == JsonbContainsStrategyNumber) {
/* Query is a jsonb, so just apply gin_extract_jsonb... */
entries = (Datum *)
DatumGetPointer(DirectFunctionCall2(gin_extract_jsonb,
PG_GETARG_DATUM(0),
PointerGetDatum(nentries)));
DatumGetPointer(DirectFunctionCall2(gin_extract_jsonb, PG_GETARG_DATUM(0), PointerGetDatum(nentries)));
/* ...although "contains {}" requires a full index scan */
if (entries == NULL) {
*searchMode = GIN_SEARCH_MODE_ALL;
@ -169,11 +157,9 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS)
*nentries = 1;
entries = (Datum *) palloc(sizeof(Datum));
item = make_text_key(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query),
JKEYELEM);
item = make_text_key(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query), JKEYELEM);
entries[0] = PointerGetDatum(item);
} else if (strategy == JsonbExistsAnyStrategyNumber ||
strategy == JsonbExistsAllStrategyNumber) {
} else if (strategy == JsonbExistsAnyStrategyNumber || strategy == JsonbExistsAllStrategyNumber) {
ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
Datum *key_datums = NULL;
bool *key_nulls = NULL;
@ -181,11 +167,7 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS)
int i,
j;
text *item = NULL;
deconstruct_array(query,
TEXTOID, -1, false, 'i',
&key_datums, &key_nulls, &key_count);
deconstruct_array(query, TEXTOID, -1, false, 'i', &key_datums, &key_nulls, &key_count);
entries = (Datum *) palloc(sizeof(Datum) * key_count);
for (i = 0, j = 0; i < key_count; ++i) {
@ -193,9 +175,7 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS)
if (key_nulls[i]) {
continue;
}
item = make_text_key(VARDATA(key_datums[i]),
VARSIZE(key_datums[i]) - VARHDRSZ,
JKEYELEM);
item = make_text_key(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ, JKEYELEM);
entries[j++] = PointerGetDatum(item);
}
@ -212,16 +192,13 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(entries);
}
Datum
gin_consistent_jsonb(PG_FUNCTION_ARGS)
Datum gin_consistent_jsonb(PG_FUNCTION_ARGS)
{
bool *check = (bool *) PG_GETARG_POINTER(0);
StrategyNumber strategy = PG_GETARG_UINT16(1);
/* Jsonb *query = PG_GETARG_JSONB(2); */
/* example: Jsonb *query = PG_GETARG_JSONB(2); */
int32 nkeys = PG_GETARG_INT32(3);
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
/* example: Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
bool *recheck = (bool *) PG_GETARG_POINTER(5);
bool res = true;
int32 i;
@ -267,21 +244,16 @@ gin_consistent_jsonb(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(res);
}
Datum
gin_triconsistent_jsonb(PG_FUNCTION_ARGS)
Datum gin_triconsistent_jsonb(PG_FUNCTION_ARGS)
{
GinLogicValue *check = (GinLogicValue *) PG_GETARG_POINTER(0);
StrategyNumber strategy = PG_GETARG_UINT16(1);
/* Jsonb *query = PG_GETARG_JSONB(2); */
int32 nkeys = PG_GETARG_INT32(3);
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
GinLogicValue res = GIN_TRUE;
StrategyNumber strategy = PG_GETARG_UINT16(1);
int32 nkeys = PG_GETARG_INT32(3);
GinLogicValue res = GIN_TRUE;
int32 i;
if (strategy == JsonbContainsStrategyNumber) {
bool has_maybe = false;
/*
* All extracted keys must be present. Combination of GIN_MAYBE and
* GIN_TRUE gives GIN_MAYBE result because then all keys may be
@ -307,8 +279,7 @@ gin_triconsistent_jsonb(PG_FUNCTION_ARGS)
if (!has_maybe && res == GIN_TRUE) {
res = GIN_MAYBE;
}
} else if (strategy == JsonbExistsStrategyNumber ||
strategy == JsonbExistsAnyStrategyNumber) {
} else if (strategy == JsonbExistsStrategyNumber || strategy == JsonbExistsAnyStrategyNumber) {
/* Existence of key guaranteed in default search mode */
res = GIN_FALSE;
for (i = 0; i < nkeys; i++) {
@ -339,21 +310,16 @@ gin_triconsistent_jsonb(PG_FUNCTION_ARGS)
}
/*
*
* jsonb_hash_ops GIN opclass support functions
*
*/
Datum
gin_consistent_jsonb_hash(PG_FUNCTION_ARGS)
Datum gin_consistent_jsonb_hash(PG_FUNCTION_ARGS)
{
bool *check = (bool *) PG_GETARG_POINTER(0);
bool *check = (bool *) PG_GETARG_POINTER(0);
StrategyNumber strategy = PG_GETARG_UINT16(1);
/* Jsonb *query = PG_GETARG_JSONB(2); */
int32 nkeys = PG_GETARG_INT32(3);
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
bool *recheck = (bool *) PG_GETARG_POINTER(5);
bool res = true;
int32 i;
int32 nkeys = PG_GETARG_INT32(3);
bool *recheck = (bool *) PG_GETARG_POINTER(5);
bool res = true;
int32 i;
if (strategy != JsonbContainsStrategyNumber) {
elog(ERROR, "unrecognized strategy number: %d", strategy);
@ -379,17 +345,14 @@ gin_consistent_jsonb_hash(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(res);
}
Datum
gin_triconsistent_jsonb_hash(PG_FUNCTION_ARGS)
Datum gin_triconsistent_jsonb_hash(PG_FUNCTION_ARGS)
{
GinLogicValue *check = (GinLogicValue *) PG_GETARG_POINTER(0);
StrategyNumber strategy = PG_GETARG_UINT16(1);
/* Jsonb *query = PG_GETARG_JSONB(2); */
int32 nkeys = PG_GETARG_INT32(3);
/* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
GinLogicValue res = GIN_TRUE;
int32 i;
bool has_maybe = false;
StrategyNumber strategy = PG_GETARG_UINT16(1);
int32 nkeys = PG_GETARG_INT32(3);
GinLogicValue res = GIN_TRUE;
int32 i;
bool has_maybe = false;
if (strategy != JsonbContainsStrategyNumber) {
elog(ERROR, "unrecognized strategy number: %d", strategy);
@ -425,8 +388,7 @@ gin_triconsistent_jsonb_hash(PG_FUNCTION_ARGS)
PG_RETURN_GIN_LOGIC_VALUE(res);
}
Datum
gin_extract_jsonb_hash(PG_FUNCTION_ARGS)
Datum gin_extract_jsonb_hash(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB(0);
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
@ -445,16 +407,13 @@ gin_extract_jsonb_hash(PG_FUNCTION_ARGS)
}
entries = (Datum *) palloc(sizeof(Datum) * total);
it = JsonbIteratorInit(VARDATA(jb));
tail.parent = NULL;
tail.hash = 0;
stack = &tail;
while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) {
PathHashStack *tmp = NULL;
if (i >= total) {
total *= 2;
entries = (Datum *) repalloc(entries, sizeof(Datum) * total);
@ -516,12 +475,10 @@ gin_extract_jsonb_hash(PG_FUNCTION_ARGS)
}
*nentries = i;
PG_RETURN_POINTER(entries);
}
Datum
gin_extract_jsonb_query_hash(PG_FUNCTION_ARGS)
Datum gin_extract_jsonb_query_hash(PG_FUNCTION_ARGS)
{
int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
StrategyNumber strategy = PG_GETARG_UINT16(2);
@ -550,29 +507,26 @@ gin_extract_jsonb_query_hash(PG_FUNCTION_ARGS)
* Build a text value from a cstring and flag suitable for storage as a key
* value
*/
static text *
make_text_key(const char *str, int len, char flag)
static text *make_text_key(const char *str, int len, char flag)
{
text *item = NULL;
text *item = NULL;
item = (text *) palloc(VARHDRSZ + len + 1);
item = (text *)palloc(VARHDRSZ + len + 1);
SET_VARSIZE(item, VARHDRSZ + len + 1);
*VARDATA(item) = flag;
memcpy(VARDATA(item) + 1, str, len);
errno_t rc = memcpy_s(VARDATA(item) + 1, len, str, len);
securec_check(rc, "\0", "\0");
return item;
}
/*
* Create a textual representation of a jsonbValue for GIN storage.
*/
static text *
make_scalar_key(const JsonbValue * scalarVal, char flag)
static text *make_scalar_key(const JsonbValue *scalarVal, char flag)
{
text *item = NULL;
char *cstr = NULL;
text *item = NULL;
char *cstr = NULL;
switch (scalarVal->type) {
case jbvNull:
@ -596,8 +550,7 @@ make_scalar_key(const JsonbValue * scalarVal, char flag)
pfree(cstr);
break;
case jbvString:
item = make_text_key(scalarVal->string.val, scalarVal->string.len,
flag);
item = make_text_key(scalarVal->string.val, scalarVal->string.len, flag);
break;
default:
elog(ERROR, "invalid jsonb scalar type");

View File

@ -1,24 +1,23 @@
/*-------------------------------------------------------------------------
/* -------------------------------------------------------------------------
*
* jsonb_op.c
* jsonb_op.cpp
* Special operators for jsonb only, used by various index access methods
*
* Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
* Portions Copyright (c) 2021 Huawei Technologies Co.,Ltd.
* Copyright (c) 2014, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src/backend/utils/adt/jsonb_op.c
* src/common/backend/utils/adt/jsonb_op.cpp
*
*-------------------------------------------------------------------------
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include "miscadmin.h"
#include "utils/jsonb.h"
Datum
jsonb_exists(PG_FUNCTION_ARGS)
Datum jsonb_exists(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB(0);
text *key = PG_GETARG_TEXT_PP(1);
@ -35,22 +34,18 @@ jsonb_exists(PG_FUNCTION_ARGS)
kval.string.val = VARDATA_ANY(key);
kval.string.len = VARSIZE_ANY_EXHDR(key);
v = findJsonbValueFromSuperHeader(VARDATA(jb),
JB_FOBJECT | JB_FARRAY,
NULL,
&kval);
v = findJsonbValueFromSuperHeader(VARDATA(jb), JB_FOBJECT | JB_FARRAY, NULL, &kval);
PG_RETURN_BOOL(v != NULL);
}
Datum
jsonb_exists_any(PG_FUNCTION_ARGS)
Datum jsonb_exists_any(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB(0);
ArrayType *keys = PG_GETARG_ARRAYTYPE_P(1);
JsonbValue *arrKey = arrayToJsonbSortedArray(keys);
uint32 *plowbound = NULL,
lowbound = 0;
uint32 *plowbound = NULL;
uint32 lowbound = 0;
int i;
if (arrKey == NULL || arrKey->object.nPairs == 0) {
@ -68,10 +63,8 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
* the lower bound of the last search.
*/
for (i = 0; i < arrKey->array.nElems; i++) {
if (findJsonbValueFromSuperHeader(VARDATA(jb),
JB_FOBJECT | JB_FARRAY,
plowbound,
arrKey->array.elems + i) != NULL) {
if (findJsonbValueFromSuperHeader(VARDATA(jb), JB_FOBJECT | JB_FARRAY,
plowbound, arrKey->array.elems + i) != NULL) {
PG_RETURN_BOOL(true);
}
}
@ -79,8 +72,7 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(false);
}
Datum
jsonb_exists_all(PG_FUNCTION_ARGS)
Datum jsonb_exists_all(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB(0);
ArrayType *keys = PG_GETARG_ARRAYTYPE_P(1);
@ -104,10 +96,8 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
* the lower bound of the last search.
*/
for (i = 0; i < arrKey->array.nElems; i++) {
if (findJsonbValueFromSuperHeader(VARDATA(jb),
JB_FOBJECT | JB_FARRAY,
plowbound,
arrKey->array.elems + i) == NULL) {
if (findJsonbValueFromSuperHeader(VARDATA(jb), JB_FOBJECT | JB_FARRAY,
plowbound, arrKey->array.elems + i) == NULL) {
PG_RETURN_BOOL(false);
}
}
@ -115,11 +105,10 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(true);
}
Datum
jsonb_contains(PG_FUNCTION_ARGS)
Datum jsonb_contains(PG_FUNCTION_ARGS)
{
Jsonb *val = PG_GETARG_JSONB(0);
Jsonb *tmpl = PG_GETARG_JSONB(1);
Jsonb *val = PG_GETARG_JSONB(0);
Jsonb *tmpl = PG_GETARG_JSONB(1);
JsonbIterator *it1 = NULL;
JsonbIterator *it2 = NULL;
@ -134,12 +123,11 @@ jsonb_contains(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
}
Datum
jsonb_contained(PG_FUNCTION_ARGS)
Datum jsonb_contained(PG_FUNCTION_ARGS)
{
/* Commutator of "contains" */
Jsonb *tmpl = PG_GETARG_JSONB(0);
Jsonb *val = PG_GETARG_JSONB(1);
Jsonb *tmpl = PG_GETARG_JSONB(0);
Jsonb *val = PG_GETARG_JSONB(1);
JsonbIterator *it1 = NULL;
JsonbIterator *it2 = NULL;
@ -154,12 +142,11 @@ jsonb_contained(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
}
Datum
jsonb_ne(PG_FUNCTION_ARGS)
Datum jsonb_ne(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res;
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res = false;
res = (compareJsonbSuperHeaderValue(VARDATA(jba), VARDATA(jbb)) != 0);
@ -171,12 +158,11 @@ jsonb_ne(PG_FUNCTION_ARGS)
/*
* B-Tree operator class operators, support function
*/
Datum
jsonb_lt(PG_FUNCTION_ARGS)
Datum jsonb_lt(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res;
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res = false;
res = (compareJsonbSuperHeaderValue(VARDATA(jba), VARDATA(jbb)) < 0);
@ -185,12 +171,11 @@ jsonb_lt(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(res);
}
Datum
jsonb_gt(PG_FUNCTION_ARGS)
Datum jsonb_gt(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res;
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res = false;
res = (compareJsonbSuperHeaderValue(VARDATA(jba), VARDATA(jbb)) > 0);
@ -199,12 +184,11 @@ jsonb_gt(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(res);
}
Datum
jsonb_le(PG_FUNCTION_ARGS)
Datum jsonb_le(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res;
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res = false;
res = (compareJsonbSuperHeaderValue(VARDATA(jba), VARDATA(jbb)) <= 0);
@ -213,13 +197,11 @@ jsonb_le(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(res);
}
Datum
jsonb_ge(PG_FUNCTION_ARGS)
Datum jsonb_ge(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res;
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res = false;
res = (compareJsonbSuperHeaderValue(VARDATA(jba), VARDATA(jbb)) >= 0);
@ -228,12 +210,11 @@ jsonb_ge(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(res);
}
Datum
jsonb_eq(PG_FUNCTION_ARGS)
Datum jsonb_eq(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res;
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
bool res = false;
res = (compareJsonbSuperHeaderValue(VARDATA(jba), VARDATA(jbb)) == 0);
@ -242,12 +223,11 @@ jsonb_eq(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(res);
}
Datum
jsonb_cmp(PG_FUNCTION_ARGS)
Datum jsonb_cmp(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
int res;
Jsonb *jba = PG_GETARG_JSONB(0);
Jsonb *jbb = PG_GETARG_JSONB(1);
int res = false;
res = compareJsonbSuperHeaderValue(VARDATA(jba), VARDATA(jbb));
@ -259,8 +239,7 @@ jsonb_cmp(PG_FUNCTION_ARGS)
/*
* Hash operator class jsonb hashing function
*/
Datum
jsonb_hash(PG_FUNCTION_ARGS)
Datum jsonb_hash(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB(0);
JsonbIterator *it = NULL;

View File

@ -3,7 +3,7 @@
* jsonb_util.c
* Utilities for jsonb datatype
*
* Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
* Portions Copyright (c) 2021 Huawei Technologies Co.,Ltd.
* Copyright (c) 2014, PostgreSQL Global Development Group
*
*
@ -35,8 +35,7 @@
* object.
*/
#define JSONB_MAX_ELEMS (Min(MaxAllocSize / sizeof(JsonbValue), JENTRY_POSMASK))
#define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), \
JENTRY_POSMASK))
#define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), JENTRY_POSMASK))
/*
* State used while converting an arbitrary JsonbValue into a Jsonb value
@ -44,8 +43,7 @@
*
* ConvertLevel: Bookkeeping around particular level when converting.
*/
typedef struct convertLevel
{
typedef struct convertLevel {
uint32 i; /* Iterates once per element, or once per pair */
uint32 *header; /* Pointer to current container header */
JEntry *meta; /* This level's metadata */
@ -55,44 +53,39 @@ typedef struct convertLevel
/*
* convertState: Overall bookkeeping state for conversion
*/
typedef struct convertState
{
typedef struct convertState {
/* Preallocated buffer in which to form varlena/Jsonb value */
Jsonb *buffer;
/* Pointer into buffer */
char *ptr;
/* State for */
convertLevel *allState, /* Overall state array */
*contPtr; /* Cur container pointer (in allState) */
convertLevel *allState; /* Overall state array */
convertLevel *contPtr; /* Cur container pointer (in allState) */
/* Current size of buffer containing allState array */
Size levelSz;
} convertState;
static int compareJsonbScalarValue(JsonbValue * a, JsonbValue * b);
static int lexicalCompareJsonbStringValue(const void *a, const void *b);
static Size convertJsonb(JsonbValue * val, Jsonb* buffer);
static inline short addPaddingInt(convertState * cstate);
static void walkJsonbValueConversion(JsonbValue * val, convertState * cstate,
uint32 nestlevel);
static void putJsonbValueConversion(convertState * cstate, JsonbValue * val,
uint32 flags, uint32 level);
static void putScalarConversion(convertState * cstate, JsonbValue * scalarVal,
uint32 level, uint32 i);
static void iteratorFromContainerBuf(JsonbIterator * it, char *buffer);
static bool formIterIsContainer(JsonbIterator ** it, JsonbValue * val,
JEntry * ent, bool skipNested);
static JsonbIterator *freeAndGetParent(JsonbIterator * it);
static JsonbParseState *pushState(JsonbParseState ** pstate);
static void appendKey(JsonbParseState * pstate, JsonbValue * scalarVal);
static void appendValue(JsonbParseState * pstate, JsonbValue * scalarVal);
static void appendElement(JsonbParseState * pstate, JsonbValue * scalarVal);
static int lengthCompareJsonbStringValue(const void *a, const void *b, void *arg);
static int lengthCompareJsonbPair(const void *a, const void *b, void *arg);
static void uniqueifyJsonbObject(JsonbValue * object);
static void uniqueifyJsonbArray(JsonbValue * array);
static int compareJsonbScalarValue(JsonbValue* a, JsonbValue* b);
static int lexicalCompareJsonbStringValue(const void* a, const void* b);
static Size convertJsonb(JsonbValue* val, Jsonb* buffer);
static inline short addPaddingInt(convertState* cstate);
static void walkJsonbValueConversion(JsonbValue* val, convertState* cstate, uint32 nestlevel);
static void putJsonbValueConversion(convertState* cstate, JsonbValue* val, uint32 flags, uint32 level);
static void putScalarConversion(convertState* cstate, JsonbValue* scalarVal, uint32 level, uint32 i);
static void iteratorFromContainerBuf(JsonbIterator* it, char* buffer);
static bool formIterIsContainer(JsonbIterator** it, JsonbValue* val, JEntry* ent, bool skipNested);
static JsonbIterator* freeAndGetParent(JsonbIterator* it);
static JsonbParseState* pushState(JsonbParseState** pstate);
static void appendKey(JsonbParseState* pstate, JsonbValue* scalarVal);
static void appendValue(JsonbParseState* pstate, JsonbValue* scalarVal);
static void appendElement(JsonbParseState* pstate, JsonbValue* scalarVal);
static int lengthCompareJsonbStringValue(const void* a, const void* b, void* binequal);
static int lengthCompareJsonbPair(const void* a, const void* b, void* binequal);
static void uniqueifyJsonbObject(JsonbValue* object);
static void uniqueifyJsonbArray(JsonbValue* array);
/*
* Turn an in-memory JsonbValue into a Jsonb for on-disk storage.
@ -107,11 +100,10 @@ static void uniqueifyJsonbArray(JsonbValue * array);
* values, or simple containers of scalar values, where it would be
* inconvenient to deal with a great amount of other state.
*/
Jsonb *
JsonbValueToJsonb(JsonbValue * val)
Jsonb* JsonbValueToJsonb(JsonbValue *val)
{
Jsonb *out = NULL;
Size sz;
Jsonb *out = NULL;
Size sz;
if (IsAJsonbScalar(val)) {
/* Scalar value */
@ -131,7 +123,7 @@ JsonbValueToJsonb(JsonbValue * val)
sz = convertJsonb(res, out);
Assert(sz <= (uint)res->estSize);
SET_VARSIZE(out, sz + VARHDRSZ);
} else if (val->type == jbvObject || val->type == jbvArray){
} else if (val->type == jbvObject || val->type == jbvArray) {
out = (Jsonb*)palloc(VARHDRSZ + val->estSize);
sz = convertJsonb(val, out);
Assert(sz <= (uint)val->estSize);
@ -140,7 +132,7 @@ JsonbValueToJsonb(JsonbValue * val)
Assert(val->type == jbvBinary);
out = (Jsonb*)palloc(VARHDRSZ + val->binary.len);
SET_VARSIZE(out, VARHDRSZ + val->binary.len);
errno_t rc = memcpy_s(VARDATA(out), VARHDRSZ + val->binary.len, val->binary.data, val->binary.len);
securec_check(rc, "\0", "\0");
}
@ -158,8 +150,7 @@ JsonbValueToJsonb(JsonbValue * val)
* called from B-Tree support function 1, we're careful about not leaking
* memory here.
*/
int
compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
int compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
{
JsonbIterator *ita = NULL;
JsonbIterator *itb = NULL;
@ -190,13 +181,13 @@ compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
break;
}
if (ra == WJB_END_ARRAY || ra == WJB_END_OBJECT) {
/*
* There is no array or object to compare at this stage of
* processing. jbvArray/jbvObject values are compared
* initially, at the WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT
* tokens.
*/
continue;
/*
* There is no array or object to compare at this stage of
* processing. jbvArray/jbvObject values are compared
* initially, at the WJB_BEGIN_ARRAY and WJB_BEGIN_OBJECT
* tokens.
*/
continue;
}
if (va.type == vb.type) {
@ -215,7 +206,7 @@ compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
* special case here though, since we still want the
* general type-based comparisons to apply, and as far
* as we're concerned a pseudo array is just a scalar.
*/
*/
if (va.array.rawScalar != vb.array.rawScalar) {
res = (va.array.rawScalar) ? -1 : 1;
} else if (va.array.nElems != vb.array.nElems) {
@ -311,23 +302,21 @@ compareJsonbSuperHeaderValue(JsonbSuperHeader a, JsonbSuperHeader b)
* presumably anyone exploiting this is only interested in matching Object keys
* with a String. lowbound is given in units of pairs, not underlying values.
*/
JsonbValue *
findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags,
uint32 *lowbound, JsonbValue * key)
JsonbValue *findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags, uint32 *lowbound, JsonbValue *key)
{
uint32 superheader = *(uint32 *) sheader;
JEntry *array = (JEntry *) (sheader + sizeof(uint32));
uint count = (superheader & JB_CMASK);
JsonbValue *result = (JsonbValue*)palloc(sizeof(JsonbValue));
uint32 superheader = *(uint32 *)sheader;
JEntry *array = (JEntry *)(sheader + sizeof(uint32));
uint count = (superheader & JB_CMASK);
JsonbValue *result = (JsonbValue*)palloc(sizeof(JsonbValue));
Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
if (flags & JB_FARRAY & superheader) {
char *data = (char *) (array + (superheader & JB_CMASK));
uint i;
char *data = (char *)(array + (superheader & JB_CMASK));
uint i;
for (i = 0; i < count; i++) {
JEntry *e = array + i;
JEntry *e = array + i;
if (JBE_ISNULL(*e) && key->type == jbvNull) {
result->type = jbvNull;
@ -446,8 +435,7 @@ findJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 flags,
*
* Returns palloc()'d copy of value.
*/
JsonbValue *
getIthJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 i)
JsonbValue *getIthJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 i)
{
uint32 superheader = *(uint32 *) sheader;
JsonbValue *result = NULL;
@ -509,8 +497,7 @@ getIthJsonbValueFromSuperHeader(JsonbSuperHeader sheader, uint32 i)
* JsonbValue. There is one exception -- WJB_BEGIN_ARRAY callers may pass a
* "raw scalar" pseudo array to append that.
*/
JsonbValue *
pushJsonbValue(JsonbParseState ** pstate, int seq, JsonbValue * scalarVal)
JsonbValue *pushJsonbValue(JsonbParseState **pstate, int seq, JsonbValue *scalarVal)
{
JsonbValue *result = NULL;
@ -531,8 +518,7 @@ pushJsonbValue(JsonbParseState ** pstate, int seq, JsonbValue * scalarVal)
} else {
(*pstate)->size = 4;
}
(*pstate)->contVal.array.elems = (JsonbValue*)palloc(sizeof(JsonbValue) *
(*pstate)->size);
(*pstate)->contVal.array.elems = (JsonbValue*)palloc(sizeof(JsonbValue) * (*pstate)->size);
break;
case WJB_BEGIN_OBJECT:
Assert(!scalarVal);
@ -542,21 +528,18 @@ pushJsonbValue(JsonbParseState ** pstate, int seq, JsonbValue * scalarVal)
(*pstate)->contVal.estSize = 3 * sizeof(JEntry);
(*pstate)->contVal.object.nPairs = 0;
(*pstate)->size = 4;
(*pstate)->contVal.object.pairs = (JsonbPair*)palloc(sizeof(JsonbPair) *
(*pstate)->size);
(*pstate)->contVal.object.pairs = (JsonbPair*)palloc(sizeof(JsonbPair) * (*pstate)->size);
break;
case WJB_KEY:
Assert(scalarVal->type == jbvString);
appendKey(*pstate, scalarVal);
break;
case WJB_VALUE:
Assert(IsAJsonbScalar(scalarVal) ||
scalarVal->type == jbvBinary);
Assert(IsAJsonbScalar(scalarVal) || scalarVal->type == jbvBinary);
appendValue(*pstate, scalarVal);
break;
case WJB_ELEM:
Assert(IsAJsonbScalar(scalarVal) ||
scalarVal->type == jbvBinary);
Assert(IsAJsonbScalar(scalarVal) || scalarVal->type == jbvBinary);
appendElement(*pstate, scalarVal);
break;
case WJB_END_OBJECT:
@ -597,8 +580,7 @@ pushJsonbValue(JsonbParseState ** pstate, int seq, JsonbValue * scalarVal)
*
* See JsonbIteratorNext() for notes on memory management.
*/
JsonbIterator *
JsonbIteratorInit(JsonbSuperHeader sheader)
JsonbIterator *JsonbIteratorInit(JsonbSuperHeader sheader)
{
JsonbIterator *it = (JsonbIterator*)palloc(sizeof(JsonbIterator));
@ -636,8 +618,7 @@ JsonbIteratorInit(JsonbSuperHeader sheader)
* or Object element/pair buffers, since their element/pair pointers are
* garbage.
*/
int
JsonbIteratorNext(JsonbIterator ** it, JsonbValue * val, bool skipNested)
int JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, bool skipNested)
{
JsonbIterState state;
@ -675,8 +656,7 @@ JsonbIteratorNext(JsonbIterator ** it, JsonbValue * val, bool skipNested)
*/
*it = freeAndGetParent(*it);
return WJB_END_ARRAY;
} else if (formIterIsContainer(it, val, &(*it)->meta[(*it)->i++],
skipNested)) {
} else if (formIterIsContainer(it, val, &(*it)->meta[(*it)->i++], skipNested)) {
/*
* New child iterator acquired within formIterIsContainer.
* Recurse into container. Don't directly return jbvBinary
@ -736,8 +716,7 @@ JsonbIteratorNext(JsonbIterator ** it, JsonbValue * val, bool skipNested)
* child iterator. If it is, don't bother !skipNested callers with
* dealing with the jbvBinary representation.
*/
if (formIterIsContainer(it, val, &(*it)->meta[((*it)->i++) * 2 + 1],
skipNested)) {
if (formIterIsContainer(it, val, &(*it)->meta[((*it)->i++) * 2 + 1], skipNested)) {
return JsonbIteratorNext(it, val, skipNested);
} else {
return WJB_VALUE;
@ -761,8 +740,7 @@ JsonbIteratorNext(JsonbIterator ** it, JsonbValue * val, bool skipNested)
* "val" is lhs Jsonb, and mContained is rhs Jsonb when called from top level.
* We determine if mContained is contained within val.
*/
bool
JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained)
bool JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
{
uint32 rval,
rcont;
@ -810,10 +788,7 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained)
Assert(rcont == WJB_KEY);
/* First, find value by key... */
lhsVal = findJsonbValueFromSuperHeader((*val)->buffer,
JB_FOBJECT,
NULL,
&vcontained);
lhsVal = findJsonbValueFromSuperHeader((*val)->buffer, JB_FOBJECT, NULL, &vcontained);
if (!lhsVal) {
return false;
@ -907,10 +882,7 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained)
Assert(rcont == WJB_ELEM);
if (IsAJsonbScalar(&vcontained)) {
if (!findJsonbValueFromSuperHeader((*val)->buffer,
JB_FARRAY,
NULL,
&vcontained)) {
if (!findJsonbValueFromSuperHeader((*val)->buffer, JB_FARRAY, NULL, &vcontained)) {
return false;
}
} else {
@ -927,7 +899,7 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained)
lhsConts = (JsonbValue*)palloc(sizeof(JsonbValue) * nLhsElems);
for (i = 0; i < nLhsElems; i++) {
/* Store all lhs elements in temp array*/
/* Store all lhs elements in temp array */
rcont = JsonbIteratorNext(val, &vval, true);
Assert(rcont == WJB_ELEM);
@ -991,8 +963,7 @@ JsonbDeepContains(JsonbIterator ** val, JsonbIterator ** mContained)
* in the array, so we enforce that the number of strings cannot exceed
* JSONB_MAX_PAIRS.
*/
JsonbValue *
arrayToJsonbSortedArray(ArrayType *array)
JsonbValue *arrayToJsonbSortedArray(ArrayType *array)
{
Datum *key_datums = NULL;
bool *key_nulls = NULL;
@ -1002,8 +973,7 @@ arrayToJsonbSortedArray(ArrayType *array)
j;
/* Extract data for sorting */
deconstruct_array(array, TEXTOID, -1, false, 'i', &key_datums, &key_nulls,
&elem_count);
deconstruct_array(array, TEXTOID, -1, false, 'i', &key_datums, &key_nulls, &elem_count);
if (elem_count == 0) {
return NULL;
@ -1049,8 +1019,7 @@ arrayToJsonbSortedArray(ArrayType *array)
* Some callers may wish to independently XOR in JB_FOBJECT and JB_FARRAY
* flags.
*/
void
JsonbHashScalarValue(const JsonbValue * scalarVal, uint32 * hash)
void JsonbHashScalarValue(const JsonbValue * scalarVal, uint32 * hash)
{
int tmp;
@ -1065,14 +1034,12 @@ JsonbHashScalarValue(const JsonbValue * scalarVal, uint32 * hash)
*hash ^= 0x01;
return;
case jbvString:
tmp = hash_any((unsigned char *) scalarVal->string.val,
scalarVal->string.len);
tmp = hash_any((unsigned char *) scalarVal->string.val, scalarVal->string.len);
*hash ^= tmp;
return;
case jbvNumeric:
/* Must be unaffected by trailing zeroes */
tmp = DatumGetInt32(DirectFunctionCall1(hash_numeric,
NumericGetDatum(scalarVal->numeric)));
tmp = DatumGetInt32(DirectFunctionCall1(hash_numeric, NumericGetDatum(scalarVal->numeric)));
*hash ^= tmp;
return;
case jbvBool:
@ -1090,8 +1057,7 @@ JsonbHashScalarValue(const JsonbValue * scalarVal, uint32 * hash)
* never be used against Strings for anything other than searching for values
* within a single jsonb.
*/
static int
compareJsonbScalarValue(JsonbValue * aScalar, JsonbValue * bScalar)
static int compareJsonbScalarValue(JsonbValue * aScalar, JsonbValue * bScalar)
{
if (aScalar->type == bScalar->type) {
switch (aScalar->type) {
@ -1123,8 +1089,7 @@ compareJsonbScalarValue(JsonbValue * aScalar, JsonbValue * bScalar)
* Sorts strings lexically, using the default database collation. Used by
* B-Tree operators, where a lexical sort order is generally expected.
*/
static int
lexicalCompareJsonbStringValue(const void *a, const void *b)
static int lexicalCompareJsonbStringValue(const void *a, const void *b)
{
const JsonbValue *va = (const JsonbValue *) a;
const JsonbValue *vb = (const JsonbValue *) b;
@ -1132,16 +1097,14 @@ lexicalCompareJsonbStringValue(const void *a, const void *b)
Assert(va->type == jbvString);
Assert(vb->type == jbvString);
return varstr_cmp(va->string.val, va->string.len, vb->string.val,
vb->string.len, DEFAULT_COLLATION_OID);
return varstr_cmp(va->string.val, va->string.len, vb->string.val, vb->string.len, DEFAULT_COLLATION_OID);
}
/*
* Given a JsonbValue, convert to Jsonb and store in preallocated Jsonb buffer
* sufficiently large to fit the value
*/
static Size
convertJsonb(JsonbValue * val, Jsonb *buffer)
static Size convertJsonb(JsonbValue * val, Jsonb *buffer)
{
convertState state;
Size len;
@ -1171,12 +1134,9 @@ convertJsonb(JsonbValue * val, Jsonb *buffer)
* the top level calls putJsonbValueConversion once per sequential processing
* token (in a manner similar to generic iteration).
*/
static void
walkJsonbValueConversion(JsonbValue * val, convertState * cstate,
uint32 nestlevel)
static void walkJsonbValueConversion(JsonbValue * val, convertState * cstate, uint32 nestlevel)
{
int i;
check_stack_depth();
if (!val)
@ -1184,40 +1144,29 @@ walkJsonbValueConversion(JsonbValue * val, convertState * cstate,
switch (val->type) {
case jbvArray:
putJsonbValueConversion(cstate, val, WJB_BEGIN_ARRAY, nestlevel);
for (i = 0; i < val->array.nElems; i++) {
if (IsAJsonbScalar(&val->array.elems[i]) ||
val->array.elems[i].type == jbvBinary) {
putJsonbValueConversion(cstate, val->array.elems + i,
WJB_ELEM, nestlevel);
putJsonbValueConversion(cstate, val->array.elems + i, WJB_ELEM, nestlevel);
} else {
walkJsonbValueConversion(val->array.elems + i, cstate,
nestlevel + 1);
walkJsonbValueConversion(val->array.elems + i, cstate, nestlevel + 1);
}
}
putJsonbValueConversion(cstate, val, WJB_END_ARRAY, nestlevel);
break;
case jbvObject:
putJsonbValueConversion(cstate, val, WJB_BEGIN_OBJECT, nestlevel);
for (i = 0; i < val->object.nPairs; i++) {
putJsonbValueConversion(cstate, &val->object.pairs[i].key,
WJB_KEY, nestlevel);
putJsonbValueConversion(cstate, &val->object.pairs[i].key, WJB_KEY, nestlevel);
if (IsAJsonbScalar(&val->object.pairs[i].value) ||
val->object.pairs[i].value.type == jbvBinary) {
putJsonbValueConversion(cstate,
&val->object.pairs[i].value,
WJB_VALUE, nestlevel);
putJsonbValueConversion(cstate, &val->object.pairs[i].value, WJB_VALUE, nestlevel);
} else {
walkJsonbValueConversion(&val->object.pairs[i].value,
cstate, nestlevel + 1);
walkJsonbValueConversion(&val->object.pairs[i].value, cstate, nestlevel + 1);
}
}
putJsonbValueConversion(cstate, val, WJB_END_OBJECT, nestlevel);
break;
default:
elog(ERROR, "unknown type of jsonb container");
@ -1228,13 +1177,11 @@ walkJsonbValueConversion(JsonbValue * val, convertState * cstate,
* walkJsonbValueConversion() worker. Add padding sufficient to int-align our
* access to conversion buffer.
*/
static inline
short addPaddingInt(convertState * cstate)
static inline short addPaddingInt(convertState *cstate)
{
short padlen, p;
padlen = INTALIGN(cstate->ptr - VARDATA(cstate->buffer)) -
(cstate->ptr - VARDATA(cstate->buffer));
padlen = INTALIGN(cstate->ptr - VARDATA(cstate->buffer)) - (cstate->ptr - VARDATA(cstate->buffer));
for (p = padlen; p > 0; p--) {
*cstate->ptr = '\0';
@ -1257,14 +1204,11 @@ short addPaddingInt(convertState * cstate)
* rather, the function is called as required for the start of an Object/Array,
* and the end (i.e. there is one call per sequential processing WJB_* token).
*/
static void
putJsonbValueConversion(convertState * cstate, JsonbValue * val, uint32 flags,
uint32 level)
static void putJsonbValueConversion(convertState *cstate, JsonbValue *val, uint32 flags, uint32 level)
{
if (level == cstate->levelSz) {
cstate->levelSz *= 2;
cstate->allState = (convertLevel*)repalloc(cstate->allState,
sizeof(convertLevel) * cstate->levelSz);
cstate->allState = (convertLevel*)repalloc(cstate->allState, sizeof(convertLevel) * cstate->levelSz);
}
cstate->contPtr = cstate->allState + level;
@ -1303,7 +1247,6 @@ putJsonbValueConversion(convertState * cstate, JsonbValue * val, uint32 flags,
cstate->contPtr->i++;
} else if (flags & WJB_KEY) {
Assert(val->type == jbvString);
putScalarConversion(cstate, val, level, cstate->contPtr->i * 2);
} else if (flags & WJB_VALUE) {
putScalarConversion(cstate, val, level, cstate->contPtr->i * 2 + 1);
@ -1321,27 +1264,23 @@ putJsonbValueConversion(convertState * cstate, JsonbValue * val, uint32 flags,
}
len = cstate->ptr - (char *) cstate->contPtr->begin;
prevPtr = cstate->contPtr - 1;
if (*prevPtr->header & JB_FARRAY) {
i = prevPtr->i;
prevPtr->meta[i].header = JENTRY_ISNEST;
if (i == 0) {
prevPtr->meta[0].header |= JENTRY_ISFIRST | len;
} else {
prevPtr->meta[i].header |=
(prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
prevPtr->meta[i].header |= (prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
}
} else if (*prevPtr->header & JB_FOBJECT) {
i = 2 * prevPtr->i + 1; /* Value, not key */
prevPtr->meta[i].header = JENTRY_ISNEST;
prevPtr->meta[i].header |=
(prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
prevPtr->meta[i].header |= (prevPtr->meta[i - 1].header & JENTRY_POSMASK) + len;
} else {
elog(ERROR, "invalid jsonb container type");
}
@ -1361,14 +1300,12 @@ putJsonbValueConversion(convertState * cstate, JsonbValue * val, uint32 flags,
* walkJsonbValueConversion()). It handles the details with regard to Jentry
* metadata peculiar to each scalar type.
*/
static void
putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level,
uint32 i)
static void putScalarConversion(convertState *cstate, JsonbValue *scalarVal, uint32 level, uint32 i)
{
int strlen;
int numlen;
short padlen;
errno_t rc = 0;
int strlen;
int numlen;
short padlen;
errno_t rc = 0;
cstate->contPtr = cstate->allState + level;
@ -1388,7 +1325,7 @@ putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level,
}
break;
case jbvString:
strlen = scalarVal->string.len > 0 ? scalarVal->string.len : 1;
strlen = scalarVal->string.len > 0 ? scalarVal->string.len : 1;
rc = memcpy_s(cstate->ptr, strlen, scalarVal->string.val, strlen);
securec_check(rc, "\0", "\0");
cstate->ptr += scalarVal->string.len;
@ -1397,8 +1334,7 @@ putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level,
cstate->contPtr->meta[0].header |= scalarVal->string.len;
} else {
cstate->contPtr->meta[i].header |=
(cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK) +
scalarVal->string.len;
(cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK) + scalarVal->string.len;
}
break;
case jbvNumeric:
@ -1414,17 +1350,14 @@ putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level,
cstate->contPtr->meta[0].header |= padlen + numlen;
} else {
cstate->contPtr->meta[i].header |=
(cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK)
+ padlen + numlen;
(cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK) + padlen + numlen;
}
break;
case jbvBool:
cstate->contPtr->meta[i].header |= (scalarVal->boolean) ?
JENTRY_ISTRUE : JENTRY_ISFALSE;
cstate->contPtr->meta[i].header |= (scalarVal->boolean) ? JENTRY_ISTRUE : JENTRY_ISFALSE;
if (i > 0) {
cstate->contPtr->meta[i].header |=
cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK;
cstate->contPtr->meta[i].header |= cstate->contPtr->meta[i - 1].header & JENTRY_POSMASK;
}
break;
default:
@ -1436,8 +1369,7 @@ putScalarConversion(convertState * cstate, JsonbValue * scalarVal, uint32 level,
* Given superheader pointer into buffer, initialize iterator. Must be a
* container type.
*/
static void
iteratorFromContainerBuf(JsonbIterator * it, JsonbSuperHeader sheader)
static void iteratorFromContainerBuf(JsonbIterator *it, JsonbSuperHeader sheader)
{
uint32 superheader = *(uint32 *) sheader;
@ -1462,8 +1394,7 @@ iteratorFromContainerBuf(JsonbIterator * it, JsonbSuperHeader sheader)
* Offset reflects that nElems indicates JsonbPairs in an object.
* Each key and each value contain Jentry metadata just the same.
*/
it->dataProper =
(char *) it->meta + it->nElems * sizeof(JEntry) * 2;
it->dataProper = (char *) it->meta + it->nElems * sizeof(JEntry) * 2;
break;
default:
elog(ERROR, "unknown type of jsonb container");
@ -1488,40 +1419,33 @@ iteratorFromContainerBuf(JsonbIterator * it, JsonbSuperHeader sheader)
* to do this. The point is that our JsonbValues scalars can be passed around
* anywhere).
*/
static bool
formIterIsContainer(JsonbIterator ** it, JsonbValue * val, JEntry * ent,
bool skipNested)
static bool formIterIsContainer(JsonbIterator **it, JsonbValue *val, JEntry *ent, bool skipNested)
{
if (JBE_ISNULL(*ent)) {
val->type = jbvNull;
val->estSize = sizeof(JEntry);
return false;
} else if (JBE_ISSTRING(*ent)) {
val->type = jbvString;
val->string.val = (*it)->dataProper + JBE_OFF(*ent);
val->string.len = JBE_LEN(*ent);
val->estSize = sizeof(JEntry) + val->string.len;
return false;
} else if (JBE_ISNUMERIC(*ent)) {
val->type = jbvNumeric;
val->numeric = (Numeric) ((*it)->dataProper + INTALIGN(JBE_OFF(*ent)));
val->estSize = 2 * sizeof(JEntry) + VARSIZE_ANY(val->numeric);
return false;
} else if (JBE_ISBOOL(*ent)) {
val->type = jbvBool;
val->boolean = JBE_ISBOOL_TRUE(*ent) != 0;
val->estSize = sizeof(JEntry);
return false;
} else if (skipNested) {
val->type = jbvBinary;
val->binary.data = (*it)->dataProper + INTALIGN(JBE_OFF(*ent));
val->binary.len = JBE_LEN(*ent) - (INTALIGN(JBE_OFF(*ent)) - JBE_OFF(*ent));
val->estSize = val->binary.len + 2 * sizeof(JEntry);
return false;
} else {
/*
@ -1531,13 +1455,9 @@ formIterIsContainer(JsonbIterator ** it, JsonbValue * val, JEntry * ent,
* Get child iterator.
*/
JsonbIterator *child = (JsonbIterator*)palloc(sizeof(JsonbIterator));
iteratorFromContainerBuf(child,
(*it)->dataProper + INTALIGN(JBE_OFF(*ent)));
iteratorFromContainerBuf(child, (*it)->dataProper + INTALIGN(JBE_OFF(*ent)));
child->parent = *it;
*it = child;
return true;
}
}
@ -1546,8 +1466,7 @@ formIterIsContainer(JsonbIterator ** it, JsonbValue * val, JEntry * ent,
* JsonbIteratorNext() worker: Return parent, while freeing memory for current
* iterator
*/
static JsonbIterator *
freeAndGetParent(JsonbIterator * it)
static JsonbIterator *freeAndGetParent(JsonbIterator *it)
{
JsonbIterator *v = it->parent;
@ -1558,8 +1477,7 @@ freeAndGetParent(JsonbIterator * it)
/*
* pushJsonbValue() worker: Iteration-like forming of Jsonb
*/
static JsonbParseState *
pushState(JsonbParseState ** pstate)
static JsonbParseState *pushState(JsonbParseState **pstate)
{
JsonbParseState *ns = (JsonbParseState*)palloc(sizeof(JsonbParseState));
@ -1570,8 +1488,7 @@ pushState(JsonbParseState ** pstate)
/*
* pushJsonbValue() worker: Append a pair key to state when generating a Jsonb
*/
static void
appendKey(JsonbParseState * pstate, JsonbValue * string)
static void appendKey(JsonbParseState *pstate, JsonbValue *string)
{
JsonbValue *object = &pstate->contVal;
@ -1587,8 +1504,7 @@ appendKey(JsonbParseState * pstate, JsonbValue * string)
if ((uint)object->object.nPairs >= pstate->size) {
pstate->size *= 2;
object->object.pairs = (JsonbPair*)repalloc(object->object.pairs,
sizeof(JsonbPair) * pstate->size);
object->object.pairs = (JsonbPair*)repalloc(object->object.pairs, sizeof(JsonbPair) * pstate->size);
}
object->object.pairs[object->object.nPairs].key = *string;
@ -1601,8 +1517,7 @@ appendKey(JsonbParseState * pstate, JsonbValue * string)
* pushJsonbValue() worker: Append a pair value to state when generating a
* Jsonb
*/
static void
appendValue(JsonbParseState * pstate, JsonbValue * scalarVal)
static void appendValue(JsonbParseState *pstate, JsonbValue *scalarVal)
{
JsonbValue *object = &pstate->contVal;
@ -1615,8 +1530,7 @@ appendValue(JsonbParseState * pstate, JsonbValue * scalarVal)
/*
* pushJsonbValue() worker: Append an element to state when generating a Jsonb
*/
static void
appendElement(JsonbParseState * pstate, JsonbValue * scalarVal)
static void appendElement(JsonbParseState *pstate, JsonbValue *scalarVal)
{
JsonbValue *array = &pstate->contVal;
@ -1631,8 +1545,7 @@ appendElement(JsonbParseState * pstate, JsonbValue * scalarVal)
if ((uint)array->array.nElems >= pstate->size) {
pstate->size *= 2;
array->array.elems = (JsonbValue*)repalloc(array->array.elems,
sizeof(JsonbValue) * pstate->size);
array->array.elems = (JsonbValue*)repalloc(array->array.elems, sizeof(JsonbValue) * pstate->size);
}
array->array.elems[array->array.nElems++] = *scalarVal;
@ -1655,8 +1568,7 @@ appendElement(JsonbParseState * pstate, JsonbValue * scalarVal)
* to true iff a and b have full binary equality, since some callers have an
* interest in whether the two values are equal or merely equivalent.
*/
static int
lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal)
static int lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal)
{
const JsonbValue *va = (const JsonbValue *) a;
const JsonbValue *vb = (const JsonbValue *) b;
@ -1688,12 +1600,11 @@ lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal)
*
* Pairs with equals keys are ordered such that the order field is respected.
*/
static int
lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
static int lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
{
const JsonbPair *pa = (const JsonbPair *) a;
const JsonbPair *pb = (const JsonbPair *) b;
int res;
int res;
res = lengthCompareJsonbStringValue(&pa->key, &pb->key, binequal);
@ -1711,16 +1622,14 @@ lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
/*
* Sort and unique-ify pairs in JsonbValue object
*/
static void
uniqueifyJsonbObject(JsonbValue * object)
static void uniqueifyJsonbObject(JsonbValue * object)
{
bool hasNonUniq = false;
bool hasNonUniq = false;
Assert(object->type == jbvObject);
if (object->object.nPairs > 1) {
qsort_arg(object->object.pairs, object->object.nPairs, sizeof(JsonbPair),
lengthCompareJsonbPair, &hasNonUniq);
qsort_arg(object->object.pairs, object->object.nPairs, sizeof(JsonbPair), lengthCompareJsonbPair, &hasNonUniq);
}
if (hasNonUniq) {
@ -1750,8 +1659,7 @@ uniqueifyJsonbObject(JsonbValue * object)
*
* Sorting uses internal ordering.
*/
static void
uniqueifyJsonbArray(JsonbValue * array)
static void uniqueifyJsonbArray(JsonbValue *array)
{
bool hasNonUniq = false;

File diff suppressed because it is too large Load Diff

View File

@ -454,37 +454,32 @@ char* numeric_out_sci(Numeric num, int scale)
*
* Output function for numeric data type without trailing zeroes.
*/
char *
numeric_normalize(Numeric num)
char *numeric_normalize(Numeric num)
{
NumericVar x;
char *str;
int orig, last;
NumericVar x;
char *str = NULL;
int orig, last;
/*
* Handle NaN
*/
if (NUMERIC_IS_NAN(num))
return pstrdup("NaN");
/*
* Handle NaN
*/
if (NUMERIC_IS_NAN(num)) {
return pstrdup("NaN");
}
init_var_from_num(num, &x);
str = get_str_from_var(&x);
orig = last = strlen(str) - 1;
init_var_from_num(num, &x);
str = get_str_from_var(&x);
orig = last = strlen(str) - 1;
for (;;)
{
if (last == 0 || str[last] != '0')
break;
last--;
}
if (last > 0 && last != orig)
str[last] = '\0';
return str;
for (;;) {
if (last == 0 || str[last] != '0') {
break;
}
last--;
}
if (last > 0 && last != orig) {
str[last] = '\0';
}
return str;
}

View File

@ -2331,8 +2331,8 @@ bool pgxc_is_internal_agg_final_func(Oid funcid)
case TIMESTAMPTZLISTAGGNOARG2FUNCOID: // timestamptz_listagg_noarg2_finalfn
case INTERVALLISTAGGFUNCOID: // interval_listagg_finalfn
case INTERVALLISTAGGNOARG2FUNCOID: // interval_listagg_noarg2_finalfn
case JSONAGGFUNCOID: //json_agg_finalfn
case JSONOBJECTAGGFUNCOID: //json_object_agg_finalfn
case JSONAGGFUNCOID: // json_agg_finalfn
case JSONOBJECTAGGFUNCOID: // json_object_agg_finalfn
is_internal_func = false;
break;
default: