mirror of https://github.com/citusdata/citus.git
133 lines
3.2 KiB
C
133 lines
3.2 KiB
C
#include "postgres.h"
|
|
|
|
#include "fmgr.h"
|
|
|
|
#include "catalog/namespace.h"
|
|
#include "catalog/pg_class.h"
|
|
#include "catalog/pg_collation.h"
|
|
#include "catalog/pg_type.h"
|
|
#include "utils/array.h"
|
|
#include "utils/builtins.h"
|
|
#include "utils/json.h"
|
|
#include "utils/lsyscache.h"
|
|
|
|
#include "pg_version_compat.h"
|
|
|
|
#include "distributed/jsonbutils.h"
|
|
#include "distributed/metadata_cache.h"
|
|
|
|
|
|
/*
|
|
* ExtractFieldJsonb gets value of fieldName from jsonbDoc and puts it
|
|
* into result. If not found, returns false. Otherwise, returns true.
|
|
* The field is returned as a Text* Datum if as_text is true, or a Jsonb*
|
|
* Datum if as_text is false.
|
|
*/
|
|
static bool
|
|
ExtractFieldJsonb(Datum jsonbDoc, const char *fieldName, Datum *result, bool as_text)
|
|
{
|
|
Datum pathArray[1] = { CStringGetTextDatum(fieldName) };
|
|
bool pathNulls[1] = { false };
|
|
bool typeByValue = false;
|
|
char typeAlignment = 0;
|
|
int16 typeLength = 0;
|
|
int dimensions[1] = { 1 };
|
|
int lowerbounds[1] = { 1 };
|
|
|
|
get_typlenbyvalalign(TEXTOID, &typeLength, &typeByValue, &typeAlignment);
|
|
|
|
ArrayType *pathArrayObject = construct_md_array(pathArray, pathNulls, 1, dimensions,
|
|
lowerbounds, TEXTOID, typeLength,
|
|
typeByValue, typeAlignment);
|
|
Datum pathDatum = PointerGetDatum(pathArrayObject);
|
|
|
|
FmgrInfo fmgrInfo;
|
|
|
|
if (as_text)
|
|
{
|
|
fmgr_info(JsonbExtractPathTextFuncId(), &fmgrInfo);
|
|
}
|
|
else
|
|
{
|
|
fmgr_info(JsonbExtractPathFuncId(), &fmgrInfo);
|
|
}
|
|
|
|
LOCAL_FCINFO(functionCallInfo, 2);
|
|
InitFunctionCallInfoData(*functionCallInfo, &fmgrInfo, 2, DEFAULT_COLLATION_OID, NULL,
|
|
NULL);
|
|
|
|
fcSetArg(functionCallInfo, 0, jsonbDoc);
|
|
fcSetArg(functionCallInfo, 1, pathDatum);
|
|
|
|
*result = FunctionCallInvoke(functionCallInfo);
|
|
return !functionCallInfo->isnull;
|
|
}
|
|
|
|
|
|
/*
|
|
* ExtractFieldBoolean gets value of fieldName from jsonbDoc, or returns
|
|
* defaultValue if it doesn't exist.
|
|
*/
|
|
bool
|
|
ExtractFieldBoolean(Datum jsonbDoc, const char *fieldName, bool defaultValue)
|
|
{
|
|
Datum jsonbDatum = 0;
|
|
bool found = ExtractFieldJsonb(jsonbDoc, fieldName, &jsonbDatum, false);
|
|
if (!found)
|
|
{
|
|
return defaultValue;
|
|
}
|
|
|
|
Datum boolDatum = DirectFunctionCall1(jsonb_bool, jsonbDatum);
|
|
return DatumGetBool(boolDatum);
|
|
}
|
|
|
|
|
|
/*
|
|
* ExtractFieldInt32 gets value of fieldName from jsonbDoc, or returns
|
|
* defaultValue if it doesn't exist.
|
|
*/
|
|
int32
|
|
ExtractFieldInt32(Datum jsonbDoc, const char *fieldName, int32 defaultValue)
|
|
{
|
|
Datum jsonbDatum = 0;
|
|
bool found = ExtractFieldJsonb(jsonbDoc, fieldName, &jsonbDatum, false);
|
|
if (!found)
|
|
{
|
|
return defaultValue;
|
|
}
|
|
|
|
Datum int32Datum = DirectFunctionCall1(jsonb_int4, jsonbDatum);
|
|
return DatumGetInt32(int32Datum);
|
|
}
|
|
|
|
|
|
/*
|
|
* ExtractFieldTextP gets value of fieldName as text* from jsonbDoc, or
|
|
* returns NULL if it doesn't exist.
|
|
*/
|
|
text *
|
|
ExtractFieldTextP(Datum jsonbDoc, const char *fieldName)
|
|
{
|
|
Datum jsonbDatum = 0;
|
|
|
|
bool found = ExtractFieldJsonb(jsonbDoc, fieldName, &jsonbDatum, true);
|
|
if (!found)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return DatumGetTextP(jsonbDatum);
|
|
}
|
|
|
|
|
|
/*
|
|
* ExtractFieldJsonbDatum gets value of fieldName from jsonbDoc and puts it
|
|
* into result. If not found, returns false. Otherwise, returns true.
|
|
*/
|
|
bool
|
|
ExtractFieldJsonbDatum(Datum jsonbDoc, const char *fieldName, Datum *result)
|
|
{
|
|
return ExtractFieldJsonb(jsonbDoc, fieldName, result, false);
|
|
}
|