Thread: Problem with Numerics multiplication in C-function
Hi, I have a strange problem with Numeric multiplication in C-function.
There are 2 functions getRate and getVAT which return Numeric. In 3rd function calculateService I try to multiply the results of getRate and getVAT. After execution I have two types of error, some time without messages and with message "Invalid memory alloc ... ".
If I initialize the Numeric variables inside calculateService and multiply, function numeric_mul works fine.
PostgreSQL 8.3.7
Datum getRate(PG_FUNCTION_ARGS) {
int32 accountId = PG_GETARG_INT32(0);
int16 serviceId = PG_GETARG_INT16(1);
DateADT date = PG_GETARG_DATEADT(2);
bool isNull;
char command[QUERY_MAX_SIZE];
char message[MESSAGE_MAX_SIZE];
Numeric rate = DatumGetNumeric(DirectFunctionCall3(numeric_in,
CStringGetDatum(RATE_ERROR_CSTRING_VALUE), 0, -1));
//Build SQL query
snprintf(command, sizeof (command), "...");
SPI_connect();
SPI_execute(command, true, 0);
rate = DatumGetNumeric(SPI_getbinval(SPI_tuptable->vals[0],
SPI_tuptable->tupdesc,
1,
&isNull));
#ifdef PR_DEBUG
snprintf(message, sizeof (message), "<DEBUG> getRate: Returns rate = %s.",
DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(rate))));
elog(INFO, message);
#endif
SPI_finish();
PG_RETURN_NUMERIC(rate);
}
Datum calculateService(PG_FUNCTION_ARGS) {
// Like the getRate
}
Datum calculateService(PG_FUNCTION_ARGS) {
int32 accountId = PG_GETARG_INT32(0);
int16 serviceId = PG_GETARG_INT16(1);
DateADT date = PG_GETARG_DATEADT(2);
int32 transactionRegisterId = PG_GETARG_INT32(3);
Numeric rate;
Numeric vat;
Numeric amount;
rate = DatumGetNumeric(DirectFunctionCall3(getRate,
Int32GetDatum(accountId),
Int16GetDatum(serviceId),
DateADTGetDatum(date)));
vat = DatumGetNumeric(DirectFunctionCall1(getVAT, DateADTGetDatum(date)));
#ifdef PR_DEBUG
snprintf(message, sizeof (message), "<DEBUG> calculateService: rate = %s, vat",
DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(rate))));
elog(INFO, message);
#endif
amount = DatumGetNumeric(DirectFunctionCall2(numeric_mul,
NumericGetDatum(rate),
NumericGetDatum(vat)));
// ERROR
...
}
Best regards,
Ilya Urikh.
There are 2 functions getRate and getVAT which return Numeric. In 3rd function calculateService I try to multiply the results of getRate and getVAT. After execution I have two types of error, some time without messages and with message "Invalid memory alloc ... ".
If I initialize the Numeric variables inside calculateService and multiply, function numeric_mul works fine.
PostgreSQL 8.3.7
Datum getRate(PG_FUNCTION_ARGS) {
int32 accountId = PG_GETARG_INT32(0);
int16 serviceId = PG_GETARG_INT16(1);
DateADT date = PG_GETARG_DATEADT(2);
bool isNull;
char command[QUERY_MAX_SIZE];
char message[MESSAGE_MAX_SIZE];
Numeric rate = DatumGetNumeric(DirectFunctionCall3(numeric_in,
CStringGetDatum(RATE_ERROR_CSTRING_VALUE), 0, -1));
//Build SQL query
snprintf(command, sizeof (command), "...");
SPI_connect();
SPI_execute(command, true, 0);
rate = DatumGetNumeric(SPI_getbinval(SPI_tuptable->vals[0],
SPI_tuptable->tupdesc,
1,
&isNull));
#ifdef PR_DEBUG
snprintf(message, sizeof (message), "<DEBUG> getRate: Returns rate = %s.",
DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(rate))));
elog(INFO, message);
#endif
SPI_finish();
PG_RETURN_NUMERIC(rate);
}
Datum calculateService(PG_FUNCTION_ARGS) {
// Like the getRate
}
Datum calculateService(PG_FUNCTION_ARGS) {
int32 accountId = PG_GETARG_INT32(0);
int16 serviceId = PG_GETARG_INT16(1);
DateADT date = PG_GETARG_DATEADT(2);
int32 transactionRegisterId = PG_GETARG_INT32(3);
Numeric rate;
Numeric vat;
Numeric amount;
rate = DatumGetNumeric(DirectFunctionCall3(getRate,
Int32GetDatum(accountId),
Int16GetDatum(serviceId),
DateADTGetDatum(date)));
vat = DatumGetNumeric(DirectFunctionCall1(getVAT, DateADTGetDatum(date)));
#ifdef PR_DEBUG
snprintf(message, sizeof (message), "<DEBUG> calculateService: rate = %s, vat",
DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(rate))));
elog(INFO, message);
#endif
amount = DatumGetNumeric(DirectFunctionCall2(numeric_mul,
NumericGetDatum(rate),
NumericGetDatum(vat)));
// ERROR
...
}
Best regards,
Ilya Urikh.