diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c index 88fd18801..3d40578fc 100644 --- a/src/backend/utils/adt/agtype.c +++ b/src/backend/utils/adt/agtype.c @@ -6097,12 +6097,16 @@ Datum age_tointeger(PG_FUNCTION_ARGS) /* check number of args */ if (nargs > 1) + { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toInteger() only supports one argument"))); + } /* check for null */ if (nargs < 0 || nulls[0]) + { PG_RETURN_NULL(); + } /* * toInteger() supports integer, float, numeric, text, cstring, or the @@ -6114,30 +6118,40 @@ Datum age_tointeger(PG_FUNCTION_ARGS) if (type != AGTYPEOID) { if (type == INT2OID) + { result = (int64) DatumGetInt16(arg); + } else if (type == INT4OID) + { result = (int64) DatumGetInt32(arg); + } else if (type == INT8OID) + { result = (int64) DatumGetInt64(arg); + } else if (type == FLOAT4OID) { float4 f = DatumGetFloat4(arg); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float4)PG_INT64_MIN || f > (float4)PG_INT64_MAX) + { PG_RETURN_NULL(); + } - result = (int64) f; + result = (int64)f; } else if (type == FLOAT8OID) { float8 f = DatumGetFloat8(arg); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } - result = (int64) f; + result = (int64)f; } else if (type == NUMERICOID) { @@ -6147,27 +6161,34 @@ Datum age_tointeger(PG_FUNCTION_ARGS) numeric_float8_no_overflow, arg)); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } - result = (int64) f; + result = (int64)f; } else if (type == CSTRINGOID || type == TEXTOID) { if (type == CSTRINGOID) + { string = DatumGetCString(arg); + } else + { string = text_to_cstring(DatumGetTextPP(arg)); + } /* convert it if it is a regular integer string */ is_valid = scanint8(string, true, &result); + /* * If it isn't an integer string, try converting it as a float * string. */ if (!is_valid) { - float f; + float8 f; f = float8in_internal_null(string, NULL, "double precision", string, &is_valid); @@ -6176,16 +6197,20 @@ Datum age_tointeger(PG_FUNCTION_ARGS) * return null. */ if (!is_valid || isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } - result = (int64) f; + result = (int64)f; } } else + { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toInteger() unsupported argument type %d", type))); + } } else { @@ -6196,22 +6221,28 @@ Datum age_tointeger(PG_FUNCTION_ARGS) agt_arg = DATUM_GET_AGTYPE_P(arg); if (!AGT_ROOT_IS_SCALAR(agt_arg)) + { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toInteger() only supports scalar arguments"))); + } agtv_value = get_ith_agtype_value_from_container(&agt_arg->root, 0); if (agtv_value->type == AGTV_INTEGER) + { result = agtv_value->val.int_value; + } else if (agtv_value->type == AGTV_FLOAT) { - float f = agtv_value->val.float_value; + float8 f = agtv_value->val.float_value; if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } - result = (int64) f; + result = (int64)f; } else if (agtv_value->type == AGTV_NUMERIC) { @@ -6222,10 +6253,12 @@ Datum age_tointeger(PG_FUNCTION_ARGS) numeric_float8_no_overflow, num)); if (isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } - result = (int64) f; + result = (int64)f; } else if (agtv_value->type == AGTV_STRING) { @@ -6240,7 +6273,7 @@ Datum age_tointeger(PG_FUNCTION_ARGS) */ if (!is_valid) { - float f; + float8 f; f = float8in_internal_null(string, NULL, "double precision", string, &is_valid); @@ -6250,18 +6283,24 @@ Datum age_tointeger(PG_FUNCTION_ARGS) * return null. */ if (!is_valid || isnan(f) || isinf(f) || - f < PG_INT64_MIN || f > PG_INT64_MAX) + f < (float8)PG_INT64_MIN || f > (float8)PG_INT64_MAX) + { PG_RETURN_NULL(); + } - result = (int64) f; + result = (int64)f; } else + { free(string); + } } else + { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("toInteger() unsupported argument agtype %d", agtv_value->type))); + } } /* build the result */