我正在尝试创建一个聚合函数,该函数返回行中具有最小/最大时间戳的列的值。下面是为某些大输入引发分段错误的代码。
PG_FUNCTION_INFO_V1(minmax);
Datum minmax(PG_FUNCTION_ARGS) {
if(PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3)) {
if(PG_ARGISNULL(0)) {
PG_RETURN_NULL();
}
else {
PG_RETURN_HEAPTUPLEHEADER(PG_GETARG_HEAPTUPLEHEADER(0));
}
}
Timestamp epoch = PG_GETARG_TIMESTAMP(1);
Datum col = PG_GETARG_DATUM(2);
Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 2);
bool is_min = PG_GETARG_BOOL(3);
Timestamp minmax_epoch = is_min ? LONG_MAX : LONG_MIN;
Datum minmax_col;
if(PG_ARGISNULL(0)) {
// first call
minmax_epoch = epoch;
minmax_col = col;
}
else {
// state
HeapTupleHeader hth_state = PG_GETARG_HEAPTUPLEHEADER(0);
bool isnull_state_minmax_timestamp;
Datum d_state_minmax_timestamp = GetAttributeByNum(hth_state, (AttrNumber) 1, &isnull_state_minmax_timestamp);
minmax_epoch = DatumGetInt64(d_state_minmax_timestamp);
if((is_min && epoch < minmax_epoch) || (!is_min && epoch > minmax_epoch)) {
minmax_epoch = epoch;
minmax_col = col;
}
else {
PG_RETURN_HEAPTUPLEHEADER(hth_state);
}
}
// return state
TupleDesc tupdesc;
Datum values[2];
bool nulls[2];
MemSet(values, 0, sizeof(values));
MemSet(nulls, 0, sizeof(nulls));
tupdesc = CreateTemplateTupleDesc(2, false);
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "minmax_timestamp", INT8OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "minmax_col", element_type, -1, 0);
tupdesc = BlessTupleDesc(tupdesc);
values[0] = Int64GetDatum(minmax_epoch);
values[1] = minmax_col;
HeapTuple rettuple = heap_form_tuple(tupdesc, values, nulls);
PG_RETURN_DATUM(HeapTupleGetDatum(rettuple));
}
PG_FUNCTION_INFO_V1(get_minmax);
Datum get_minmax(PG_FUNCTION_ARGS) {
if(PG_ARGISNULL(0)) {
PG_RETURN_NULL();
}
else {
// state
//error here
HeapTupleHeader hth_state = PG_GETARG_HEAPTUPLEHEADER(0);
bool isnull_state_minmax_col;
Datum d_state_minmax_col = GetAttributeByNum(hth_state, (AttrNumber) 2, &isnull_state_minmax_col);
PG_RETURN_DATUM(d_state_minmax_col);
}
}
seg错误似乎在get_minmax函数中获取PG_GETARG_HEAPTUPLEHEADER参数。可能是我没有在minmax功能中正确构建它。
答案 0 :(得分:0)
上述代码似乎没有任何问题。我在greenplum中使用聚合函数而不是postgresql。对于那些在greenplum中编写聚合函数并实现PREFUNC的人,请确保检查两个参数是否都为NULL并相应处理。
专家确实建议在内存使用等方面是否可以对上述功能进行任何改进