如何 return 来自 PostgreSQL c 扩展函数的 jsonb 对象?
How to return a jsonb object from a PostgreSQL c extension function?
如何在用 C 语言编写的 PostgreSQL 函数中 return 一个简单的 jsonb 对象?
我对 postgres 服务器端编程了解不够。下面是我尝试 return 基于 the C source code for hstore_to_jsonb_loose
的简单 json/jsonb 对象,这是我能找到的最接近的示例。我正在尝试从 C 函数 return {"hi": -101}
,但出现错误:
=> ERROR: unexpected jsonb type as object key
任何人都可以帮助解释如何做对吗?
我的 C 代码是:
PG_FUNCTION_INFO_V1(test_return_jsonb);
Datum
test_return_jsonb( PG_FUNCTION_ARGS) {
JsonbParseState *state = NULL;
JsonbValue *res;
StringInfoData tmp;
initStringInfo(&tmp);
(void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
JsonbValue key, val;
//key
key.type = jbvString;
key.val.string.len = 2;
key.val.string.val = "hi";
Datum numd;
//value
val.type = jbvNumeric;
numd = DirectFunctionCall3(numeric_in, CStringGetDatum("-101"), //!tmp.data),
ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1));
val.val.numeric = DatumGetNumeric(numd);
(void) pushJsonbValue(&state, WJB_VALUE, &val);
res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
PG_RETURN_POINTER(JsonbValueToJsonb(res));
}
而SQL接口代码为:
CREATE OR REPLACE FUNCTION test_return_jsonb()
RETURNS jsonb
AS '$libdir/pgtest', 'test_return_jsonb'
LANGUAGE 'c' IMMUTABLE STRICT COST 100; -- Guessed cost
这是 PostgreSQL 12 和 Ubuntu 18.04 LTS。
我最近也在学习,遇到了同样的问题。我按照以下方式解决了它(不确定这是否正确,但目前有效):
// Defined in "/src/backend/utils/adt/numeric.c"
extern Datum int8_numeric(PG_FUNCTION_ARGS);
extern Datum float8_numeric(PG_FUNCTION_ARGS);
extern Datum numeric_int8(PG_FUNCTION_ARGS);
extern Datum numeric_float8(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(test_return_jsonb);
Datum test_return_jsonb(PG_FUNCTION_ARGS) {
JsonbPair *pair = palloc(sizeof(JsonbPair));
pair->key.type = jbvString;
pair->key.val.string.len = 3;
pair->key.val.string.val = "foo";
pair->value.type = jbvNumeric;
pair->value.val.numeric = DatumGetNumeric(DirectFunctionCall1(int8_numeric, (int64_t)100));
JsonbValue *object = palloc(sizeof(JsonbValue));
object->type = jbvObject;
object->val.object.nPairs = 1;
object->val.object.pairs = pair;
PG_RETURN_POINTER(JsonbValueToJsonb(object));
}
如何在用 C 语言编写的 PostgreSQL 函数中 return 一个简单的 jsonb 对象?
我对 postgres 服务器端编程了解不够。下面是我尝试 return 基于 the C source code for hstore_to_jsonb_loose
的简单 json/jsonb 对象,这是我能找到的最接近的示例。我正在尝试从 C 函数 return {"hi": -101}
,但出现错误:
=> ERROR: unexpected jsonb type as object key
任何人都可以帮助解释如何做对吗?
我的 C 代码是:
PG_FUNCTION_INFO_V1(test_return_jsonb);
Datum
test_return_jsonb( PG_FUNCTION_ARGS) {
JsonbParseState *state = NULL;
JsonbValue *res;
StringInfoData tmp;
initStringInfo(&tmp);
(void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
JsonbValue key, val;
//key
key.type = jbvString;
key.val.string.len = 2;
key.val.string.val = "hi";
Datum numd;
//value
val.type = jbvNumeric;
numd = DirectFunctionCall3(numeric_in, CStringGetDatum("-101"), //!tmp.data),
ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1));
val.val.numeric = DatumGetNumeric(numd);
(void) pushJsonbValue(&state, WJB_VALUE, &val);
res = pushJsonbValue(&state, WJB_END_OBJECT, NULL);
PG_RETURN_POINTER(JsonbValueToJsonb(res));
}
而SQL接口代码为:
CREATE OR REPLACE FUNCTION test_return_jsonb()
RETURNS jsonb
AS '$libdir/pgtest', 'test_return_jsonb'
LANGUAGE 'c' IMMUTABLE STRICT COST 100; -- Guessed cost
这是 PostgreSQL 12 和 Ubuntu 18.04 LTS。
我最近也在学习,遇到了同样的问题。我按照以下方式解决了它(不确定这是否正确,但目前有效):
// Defined in "/src/backend/utils/adt/numeric.c"
extern Datum int8_numeric(PG_FUNCTION_ARGS);
extern Datum float8_numeric(PG_FUNCTION_ARGS);
extern Datum numeric_int8(PG_FUNCTION_ARGS);
extern Datum numeric_float8(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(test_return_jsonb);
Datum test_return_jsonb(PG_FUNCTION_ARGS) {
JsonbPair *pair = palloc(sizeof(JsonbPair));
pair->key.type = jbvString;
pair->key.val.string.len = 3;
pair->key.val.string.val = "foo";
pair->value.type = jbvNumeric;
pair->value.val.numeric = DatumGetNumeric(DirectFunctionCall1(int8_numeric, (int64_t)100));
JsonbValue *object = palloc(sizeof(JsonbValue));
object->type = jbvObject;
object->val.object.nPairs = 1;
object->val.object.pairs = pair;
PG_RETURN_POINTER(JsonbValueToJsonb(object));
}