Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c527c29

Browse files
author
Nikita Glukhov
committed
WIP: optimize jsonb
1 parent 375e8a0 commit c527c29

File tree

8 files changed

+266
-300
lines changed

8 files changed

+266
-300
lines changed

src/backend/utils/adt/json.c

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3713,41 +3713,44 @@ JsonGetArraySize(JsonContainer *jc)
37133713
* Find last key in a json object by name. Returns palloc()'d copy of the
37143714
* corresponding value, or NULL if is not found.
37153715
*/
3716-
static inline JsonbValue *
3717-
jsonFindLastKeyInObject(JsonContainer *obj, const JsonbValue *key)
3716+
JsonbValue *
3717+
jsonFindLastKeyInObject(JsonContainer *obj, const char *keyval, int keylen,
3718+
JsonbValue *res)
37183719
{
3719-
JsonbValue *res = NULL;
3720+
JsonbValue *val = NULL;
37203721
JsonbValue jbv;
37213722
JsonIterator *it;
37223723
JsonbIteratorToken tok;
37233724

37243725
Assert(JsonContainerIsObject(obj));
3725-
Assert(key->type == jbvString);
37263726

37273727
it = JsonIteratorInit(obj);
37283728

37293729
while ((tok = JsonIteratorNext(&it, &jbv, true)) != WJB_DONE)
37303730
{
3731-
if (tok == WJB_KEY && !lengthCompareJsonbStringValue(key, &jbv))
3731+
if (tok == WJB_KEY &&
3732+
jbv.val.string.len == keylen &&
3733+
!memcmp(jbv.val.string.val, keyval, keylen))
37323734
{
3733-
if (!res)
3734-
res = palloc(sizeof(*res));
3735+
if (!val)
3736+
val = res ? res : palloc(sizeof(*val));
37353737

37363738
tok = JsonIteratorNext(&it, res, true);
37373739
Assert(tok == WJB_VALUE);
37383740
}
37393741
}
37403742

3741-
return res;
3743+
return val;
37423744
}
37433745

37443746
/*
37453747
* Find scalar element in a array. Returns palloc()'d copy of value or NULL.
37463748
*/
37473749
static JsonbValue *
3748-
jsonFindValueInArray(JsonContainer *array, const JsonbValue *elem)
3750+
jsonFindValueInArray(JsonContainer *array, const JsonbValue *elem,
3751+
JsonbValue *res)
37493752
{
3750-
JsonbValue *val = palloc(sizeof(*val));
3753+
JsonbValue *val = res ? res : palloc(sizeof(*val));
37513754
JsonIterator *it;
37523755
JsonbIteratorToken tok;
37533756

@@ -3766,7 +3769,8 @@ jsonFindValueInArray(JsonContainer *array, const JsonbValue *elem)
37663769
}
37673770
}
37683771

3769-
pfree(val);
3772+
if (!res)
3773+
pfree(val);
37703774
return NULL;
37713775
}
37723776

@@ -3780,18 +3784,23 @@ jsonFindValueInArray(JsonContainer *array, const JsonbValue *elem)
37803784
* For more details, see findJsonbValueFromContainer().
37813785
*/
37823786
JsonbValue *
3783-
findJsonValueFromContainer(JsonContainer *jc, uint32 flags, JsonbValue *key)
3787+
findJsonValueFromContainer(JsonContainer *jc, uint32 flags, JsonbValue *key,
3788+
JsonbValue *val)
37843789
{
37853790
Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0);
37863791

37873792
if (!JsonContainerSize(jc))
37883793
return NULL;
37893794

37903795
if ((flags & JB_FARRAY) && JsonContainerIsArray(jc))
3791-
return jsonFindValueInArray(jc, key);
3796+
return jsonFindValueInArray(jc, key, val);
37923797

37933798
if ((flags & JB_FOBJECT) && JsonContainerIsObject(jc))
3794-
return jsonFindLastKeyInObject(jc, key);
3799+
{
3800+
Assert(key->type == jbvString);
3801+
return jsonFindLastKeyInObject(jc, key->val.string.val,
3802+
key->val.string.len, val);
3803+
}
37953804

37963805
/* Not found */
37973806
return NULL;
@@ -3803,9 +3812,10 @@ findJsonValueFromContainer(JsonContainer *jc, uint32 flags, JsonbValue *key)
38033812
* Returns palloc()'d copy of the value, or NULL if it does not exist.
38043813
*/
38053814
JsonbValue *
3806-
getIthJsonValueFromContainer(JsonContainer *array, uint32 index)
3815+
getIthJsonValueFromContainer(JsonContainer *array, uint32 index,
3816+
JsonbValue *res)
38073817
{
3808-
JsonbValue *val = palloc(sizeof(JsonbValue));
3818+
JsonbValue *val = res ? res : palloc(sizeof(*val));
38093819
JsonIterator *it;
38103820
JsonbIteratorToken tok;
38113821

@@ -3825,7 +3835,8 @@ getIthJsonValueFromContainer(JsonContainer *array, uint32 index)
38253835
}
38263836
}
38273837

3828-
pfree(val);
3838+
if (!res)
3839+
pfree(val);
38293840

38303841
return NULL;
38313842
}

src/backend/utils/adt/jsonb.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2161,9 +2161,12 @@ jsonb_is_valid(PG_FUNCTION_ARGS)
21612161
bool
21622162
JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
21632163
{
2164+
#if 0
21642165
JsonbIterator *it;
21652166
JsonbIteratorToken tok PG_USED_FOR_ASSERTS_ONLY;
21662167
JsonbValue tmp;
2168+
#endif
2169+
JsonbValue *scalar PG_USED_FOR_ASSERTS_ONLY;
21672170

21682171
if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc))
21692172
{
@@ -2172,6 +2175,10 @@ JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
21722175
return false;
21732176
}
21742177

2178+
#if 1
2179+
scalar = getIthJsonbValueFromContainer(jbc, 0, res);
2180+
Assert(scalar);
2181+
#else
21752182
/*
21762183
* A root scalar is stored as an array of one element, so we get the array
21772184
* and then its first (and only) member.
@@ -2191,7 +2198,7 @@ JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
21912198

21922199
tok = JsonbIteratorNext(&it, &tmp, true);
21932200
Assert(tok == WJB_DONE);
2194-
2201+
#endif
21952202
return true;
21962203
}
21972204

src/backend/utils/adt/jsonb_op.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jsonb_exists(PG_FUNCTION_ARGS)
2424
Jsonb *jb = PG_GETARG_JSONB_P(0);
2525
text *key = PG_GETARG_TEXT_PP(1);
2626
JsonbValue kval;
27+
JsonbValue vval;
2728
JsonbValue *v = NULL;
2829

2930
/*
@@ -38,7 +39,7 @@ jsonb_exists(PG_FUNCTION_ARGS)
3839

3940
v = findJsonbValueFromContainer(&jb->root,
4041
JB_FOBJECT | JB_FARRAY,
41-
&kval);
42+
&kval, &vval);
4243

4344
PG_RETURN_BOOL(v != NULL);
4445
}
@@ -59,6 +60,7 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
5960
for (i = 0; i < elem_count; i++)
6061
{
6162
JsonbValue strVal;
63+
JsonbValue valVal;
6264

6365
if (key_nulls[i])
6466
continue;
@@ -69,7 +71,7 @@ jsonb_exists_any(PG_FUNCTION_ARGS)
6971

7072
if (findJsonbValueFromContainer(&jb->root,
7173
JB_FOBJECT | JB_FARRAY,
72-
&strVal) != NULL)
74+
&strVal, &valVal) != NULL)
7375
PG_RETURN_BOOL(true);
7476
}
7577

@@ -92,6 +94,7 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
9294
for (i = 0; i < elem_count; i++)
9395
{
9496
JsonbValue strVal;
97+
JsonbValue valVal;
9598

9699
if (key_nulls[i])
97100
continue;
@@ -102,7 +105,7 @@ jsonb_exists_all(PG_FUNCTION_ARGS)
102105

103106
if (findJsonbValueFromContainer(&jb->root,
104107
JB_FOBJECT | JB_FARRAY,
105-
&strVal) == NULL)
108+
&strVal, &valVal) == NULL)
106109
PG_RETURN_BOOL(false);
107110
}
108111

0 commit comments

Comments
 (0)