SSL jsonb_op.c
Interaktion und Portierbarkeitunbekannt
/*-------------------------------------------------------------------------
*
* jsonb_op . c
* Special operators for jsonb only , used by various index access methods
*
* Copyright ( c ) 2014 - 2025 , PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src / backend / utils / adt / jsonb_op . c
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#include "postgres.h"
#include "catalog/pg_type.h"
#include "utils/fmgrprotos.h"
#include "utils/jsonb.h"
Datum
jsonb_exists(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB_P(0 );
text *key = PG_GETARG_TEXT_PP(1 );
JsonbValue kval;
JsonbValue *v = NULL;
/*
* We only match Object keys ( which are naturally always Strings ) , or
* string elements in arrays . In particular , we do not match non - string
* scalar elements . Existence of a key / element is only considered at the
* top level . No recursion occurs .
*/
kval.type = jbvString;
kval.val.string.val = VARDATA_ANY(key);
kval.val.string.len = VARSIZE_ANY_EXHDR(key);
v = findJsonbValueFromContainer(&jb->root,
JB_FOBJECT | JB_FARRAY,
&kval);
PG_RETURN_BOOL(v != NULL);
}
Datum
jsonb_exists_any(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB_P(0 );
ArrayType *keys = PG_GETARG_ARRAYTYPE_P(1 );
int i;
Datum *key_datums;
bool *key_nulls;
int elem_count;
deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, &elem_count);
for (i = 0 ; i < elem_count; i++)
{
JsonbValue strVal;
if (key_nulls[i])
continue ;
strVal.type = jbvString;
/* We rely on the array elements not being toasted */
strVal.val.string.val = VARDATA_ANY(key_datums[i]);
strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]);
if (findJsonbValueFromContainer(&jb->root,
JB_FOBJECT | JB_FARRAY,
&strVal) != NULL)
PG_RETURN_BOOL(true );
}
PG_RETURN_BOOL(false );
}
Datum
jsonb_exists_all(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB_P(0 );
ArrayType *keys = PG_GETARG_ARRAYTYPE_P(1 );
int i;
Datum *key_datums;
bool *key_nulls;
int elem_count;
deconstruct_array_builtin(keys, TEXTOID, &key_datums, &key_nulls, &elem_count);
for (i = 0 ; i < elem_count; i++)
{
JsonbValue strVal;
if (key_nulls[i])
continue ;
strVal.type = jbvString;
/* We rely on the array elements not being toasted */
strVal.val.string.val = VARDATA_ANY(key_datums[i]);
strVal.val.string.len = VARSIZE_ANY_EXHDR(key_datums[i]);
if (findJsonbValueFromContainer(&jb->root,
JB_FOBJECT | JB_FARRAY,
&strVal) == NULL)
PG_RETURN_BOOL(false );
}
PG_RETURN_BOOL(true );
}
Datum
jsonb_contains(PG_FUNCTION_ARGS)
{
Jsonb *val = PG_GETARG_JSONB_P(0 );
Jsonb *tmpl = PG_GETARG_JSONB_P(1 );
JsonbIterator *it1,
*it2;
if (JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl))
PG_RETURN_BOOL(false );
it1 = JsonbIteratorInit(&val->root);
it2 = JsonbIteratorInit(&tmpl->root);
PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
}
Datum
jsonb_contained(PG_FUNCTION_ARGS)
{
/* Commutator of "contains" */
Jsonb *tmpl = PG_GETARG_JSONB_P(0 );
Jsonb *val = PG_GETARG_JSONB_P(1 );
JsonbIterator *it1,
*it2;
if (JB_ROOT_IS_OBJECT(val) != JB_ROOT_IS_OBJECT(tmpl))
PG_RETURN_BOOL(false );
it1 = JsonbIteratorInit(&val->root);
it2 = JsonbIteratorInit(&tmpl->root);
PG_RETURN_BOOL(JsonbDeepContains(&it1, &it2));
}
Datum
jsonb_ne(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB_P(0 );
Jsonb *jbb = PG_GETARG_JSONB_P(1 );
bool res;
res = (compareJsonbContainers(&jba->root, &jbb->root) != 0 );
PG_FREE_IF_COPY(jba, 0 );
PG_FREE_IF_COPY(jbb, 1 );
PG_RETURN_BOOL(res);
}
/*
* B - Tree operator class operators , support function
*/
Datum
jsonb_lt(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB_P(0 );
Jsonb *jbb = PG_GETARG_JSONB_P(1 );
bool res;
res = (compareJsonbContainers(&jba->root, &jbb->root) < 0 );
PG_FREE_IF_COPY(jba, 0 );
PG_FREE_IF_COPY(jbb, 1 );
PG_RETURN_BOOL(res);
}
Datum
jsonb_gt(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB_P(0 );
Jsonb *jbb = PG_GETARG_JSONB_P(1 );
bool res;
res = (compareJsonbContainers(&jba->root, &jbb->root) > 0 );
PG_FREE_IF_COPY(jba, 0 );
PG_FREE_IF_COPY(jbb, 1 );
PG_RETURN_BOOL(res);
}
Datum
jsonb_le(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB_P(0 );
Jsonb *jbb = PG_GETARG_JSONB_P(1 );
bool res;
res = (compareJsonbContainers(&jba->root, &jbb->root) <= 0 );
PG_FREE_IF_COPY(jba, 0 );
PG_FREE_IF_COPY(jbb, 1 );
PG_RETURN_BOOL(res);
}
Datum
jsonb_ge(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB_P(0 );
Jsonb *jbb = PG_GETARG_JSONB_P(1 );
bool res;
res = (compareJsonbContainers(&jba->root, &jbb->root) >= 0 );
PG_FREE_IF_COPY(jba, 0 );
PG_FREE_IF_COPY(jbb, 1 );
PG_RETURN_BOOL(res);
}
Datum
jsonb_eq(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB_P(0 );
Jsonb *jbb = PG_GETARG_JSONB_P(1 );
bool res;
res = (compareJsonbContainers(&jba->root, &jbb->root) == 0 );
PG_FREE_IF_COPY(jba, 0 );
PG_FREE_IF_COPY(jbb, 1 );
PG_RETURN_BOOL(res);
}
Datum
jsonb_cmp(PG_FUNCTION_ARGS)
{
Jsonb *jba = PG_GETARG_JSONB_P(0 );
Jsonb *jbb = PG_GETARG_JSONB_P(1 );
int res;
res = compareJsonbContainers(&jba->root, &jbb->root);
PG_FREE_IF_COPY(jba, 0 );
PG_FREE_IF_COPY(jbb, 1 );
PG_RETURN_INT32(res);
}
/*
* Hash operator class jsonb hashing function
*/
Datum
jsonb_hash(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB_P(0 );
JsonbIterator *it;
JsonbValue v;
JsonbIteratorToken r;
uint32 hash = 0 ;
if (JB_ROOT_COUNT(jb) == 0 )
PG_RETURN_INT32(0 );
it = JsonbIteratorInit(&jb->root);
while ((r = JsonbIteratorNext(&it, &v, false )) != WJB_DONE)
{
switch (r)
{
/* Rotation is left to JsonbHashScalarValue() */
case WJB_BEGIN_ARRAY:
hash ^= JB_FARRAY;
break ;
case WJB_BEGIN_OBJECT:
hash ^= JB_FOBJECT;
break ;
case WJB_KEY:
case WJB_VALUE:
case WJB_ELEM:
JsonbHashScalarValue(&v, &hash);
break ;
case WJB_END_ARRAY:
case WJB_END_OBJECT:
break ;
default :
elog(ERROR, "invalid JsonbIteratorNext rc: %d" , (int ) r);
}
}
PG_FREE_IF_COPY(jb, 0 );
PG_RETURN_INT32(hash);
}
Datum
jsonb_hash_extended(PG_FUNCTION_ARGS)
{
Jsonb *jb = PG_GETARG_JSONB_P(0 );
uint64 seed = PG_GETARG_INT64(1 );
JsonbIterator *it;
JsonbValue v;
JsonbIteratorToken r;
uint64 hash = 0 ;
if (JB_ROOT_COUNT(jb) == 0 )
PG_RETURN_UINT64(seed);
it = JsonbIteratorInit(&jb->root);
while ((r = JsonbIteratorNext(&it, &v, false )) != WJB_DONE)
{
switch (r)
{
/* Rotation is left to JsonbHashScalarValueExtended() */
case WJB_BEGIN_ARRAY:
hash ^= ((uint64) JB_FARRAY) << 32 | JB_FARRAY;
break ;
case WJB_BEGIN_OBJECT:
hash ^= ((uint64) JB_FOBJECT) << 32 | JB_FOBJECT;
break ;
case WJB_KEY:
case WJB_VALUE:
case WJB_ELEM:
JsonbHashScalarValueExtended(&v, &hash, seed);
break ;
case WJB_END_ARRAY:
case WJB_END_OBJECT:
break ;
default :
elog(ERROR, "invalid JsonbIteratorNext rc: %d" , (int ) r);
}
}
PG_FREE_IF_COPY(jb, 0 );
PG_RETURN_UINT64(hash);
}
Messung V0.5 in Prozent C=94 H=94 G=93
[Verzeichnis aufwärts0.4unsichere VerbindungÜbersetzung europäischer Sprachen durch Browser2026-08-08]
2026-08-25