]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Make many cast functions error safe
authorPeter Eisentraut <peter@eisentraut.org>
Tue, 24 Mar 2026 11:01:05 +0000 (12:01 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Tue, 24 Mar 2026 11:08:22 +0000 (12:08 +0100)
This adjusts many C functions underlying casts to support soft errors.
This is in preparation for a future feature where conversion errors in
casts can be caught.

This patch covers cast functions that can be adjusted easily by
changing ereport to ereturn or making other light changes.  The
underlying helper functions were already changed to support soft
errors some time ago as part of soft error support in type input
functions.

Other casts and types will require some more work and are being kept
as separate patches.

Author: jian he <jian.universality@gmail.com>
Reviewed-by: Amul Sul <sulamul@gmail.com>
Reviewed-by: Corey Huinker <corey.huinker@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CADkLM%3Dfv1JfY4Ufa-jcwwNbjQixNViskQ8jZu3Tz_p656i_4hQ%40mail.gmail.com

15 files changed:
src/backend/executor/execExprInterp.c
src/backend/utils/adt/bytea.c
src/backend/utils/adt/char.c
src/backend/utils/adt/date.c
src/backend/utils/adt/float.c
src/backend/utils/adt/int.c
src/backend/utils/adt/int8.c
src/backend/utils/adt/mac8.c
src/backend/utils/adt/network.c
src/backend/utils/adt/numeric.c
src/backend/utils/adt/timestamp.c
src/backend/utils/adt/varbit.c
src/backend/utils/adt/varchar.c
src/backend/utils/adt/xml.c
src/include/utils/xml.h

index 53ae0205702bac8301171e7c5110f4f874bc8c73..43116431edfc14cbe052c2f19b200cf3b7cf790d 100644 (file)
@@ -4548,7 +4548,7 @@ ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op)
 
                                *op->resvalue = PointerGetDatum(xmlparse(data,
                                                                                                                 xexpr->xmloption,
-                                                                                                                preserve_whitespace));
+                                                                                                                preserve_whitespace, NULL));
                                *op->resnull = false;
                        }
                        break;
index 39ed04ddae828b8f8d01fe2b436fa08fb04ffc1a..f6e3266ac3247cf585cb1d910cbe68bcb3b423fb 100644 (file)
@@ -1256,7 +1256,7 @@ bytea_int2(PG_FUNCTION_ARGS)
 
        /* Check that the byte array is not too long */
        if (len > sizeof(result))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                errmsg("smallint out of range"));
 
@@ -1281,7 +1281,7 @@ bytea_int4(PG_FUNCTION_ARGS)
 
        /* Check that the byte array is not too long */
        if (len > sizeof(result))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                errmsg("integer out of range"));
 
@@ -1306,7 +1306,7 @@ bytea_int8(PG_FUNCTION_ARGS)
 
        /* Check that the byte array is not too long */
        if (len > sizeof(result))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                errmsg("bigint out of range"));
 
@@ -1351,7 +1351,7 @@ bytea_uuid(PG_FUNCTION_ARGS)
        pg_uuid_t  *uuid;
 
        if (len != UUID_LEN)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                                 errmsg("invalid input length for type %s", "uuid"),
                                 errdetail("Expected %d bytes, got %d.", UUID_LEN, len)));
index 3e4def68fe4073a05ea424b342db5b520d3f362e..698863924ee23d7f3d8a3f2cae7f94861052fb16 100644 (file)
@@ -192,7 +192,7 @@ i4tochar(PG_FUNCTION_ARGS)
        int32           arg1 = PG_GETARG_INT32(0);
 
        if (arg1 < SCHAR_MIN || arg1 > SCHAR_MAX)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("\"char\" out of range")));
 
index 87c063fa0cd0e5111181b69a7b92b4fcb0f3348f..71ea048d25125256cde92bbba23646f52b51a045 100644 (file)
@@ -722,15 +722,6 @@ date2timestamptz_safe(DateADT dateVal, Node *escontext)
        return result;
 }
 
-/*
- * Promote date to timestamptz, throwing error for overflow.
- */
-static TimestampTz
-date2timestamptz(DateADT dateVal)
-{
-       return date2timestamptz_safe(dateVal, NULL);
-}
-
 /*
  * date2timestamp_no_overflow
  *
@@ -1315,7 +1306,9 @@ date_timestamp(PG_FUNCTION_ARGS)
        DateADT         dateVal = PG_GETARG_DATEADT(0);
        Timestamp       result;
 
-       result = date2timestamp(dateVal);
+       result = date2timestamp_safe(dateVal, fcinfo->context);
+       if (SOFT_ERROR_OCCURRED(fcinfo->context))
+               PG_RETURN_NULL();
 
        PG_RETURN_TIMESTAMP(result);
 }
@@ -1329,7 +1322,10 @@ timestamp_date(PG_FUNCTION_ARGS)
        Timestamp       timestamp = PG_GETARG_TIMESTAMP(0);
        DateADT         result;
 
-       result = timestamp2date_safe(timestamp, NULL);
+       result = timestamp2date_safe(timestamp, fcinfo->context);
+       if (SOFT_ERROR_OCCURRED(fcinfo->context))
+               PG_RETURN_NULL();
+
        PG_RETURN_DATEADT(result);
 }
 
@@ -1388,7 +1384,9 @@ date_timestamptz(PG_FUNCTION_ARGS)
        DateADT         dateVal = PG_GETARG_DATEADT(0);
        TimestampTz result;
 
-       result = date2timestamptz(dateVal);
+       result = date2timestamptz_safe(dateVal, fcinfo->context);
+       if (SOFT_ERROR_OCCURRED(fcinfo->context))
+               PG_RETURN_NULL();
 
        PG_RETURN_TIMESTAMP(result);
 }
@@ -1403,7 +1401,10 @@ timestamptz_date(PG_FUNCTION_ARGS)
        TimestampTz timestamp = PG_GETARG_TIMESTAMP(0);
        DateADT         result;
 
-       result = timestamptz2date_safe(timestamp, NULL);
+       result = timestamptz2date_safe(timestamp, fcinfo->context);
+       if (SOFT_ERROR_OCCURRED(fcinfo->args))
+               PG_RETURN_NULL();
+
        PG_RETURN_DATEADT(result);
 }
 
@@ -2002,7 +2003,7 @@ timestamp_time(PG_FUNCTION_ARGS)
                PG_RETURN_NULL();
 
        if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
                                 errmsg("timestamp out of range")));
 
@@ -2033,7 +2034,7 @@ timestamptz_time(PG_FUNCTION_ARGS)
                PG_RETURN_NULL();
 
        if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
                                 errmsg("timestamp out of range")));
 
@@ -2103,7 +2104,7 @@ interval_time(PG_FUNCTION_ARGS)
        TimeADT         result;
 
        if (INTERVAL_NOT_FINITE(span))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
                                 errmsg("cannot convert infinite interval to time")));
 
@@ -2952,7 +2953,7 @@ timestamptz_timetz(PG_FUNCTION_ARGS)
                PG_RETURN_NULL();
 
        if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
                                 errmsg("timestamp out of range")));
 
index f77f73820d77fa6283bd942703bec0261d64df32..a06fef4290122c71232edbe1bfc8e1452355e48c 100644 (file)
@@ -1241,7 +1241,7 @@ dtoi4(PG_FUNCTION_ARGS)
 
        /* Range check */
        if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT32(num)))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("integer out of range")));
 
@@ -1266,7 +1266,7 @@ dtoi2(PG_FUNCTION_ARGS)
 
        /* Range check */
        if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT16(num)))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("smallint out of range")));
 
@@ -1315,7 +1315,7 @@ ftoi4(PG_FUNCTION_ARGS)
 
        /* Range check */
        if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT32(num)))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("integer out of range")));
 
@@ -1340,7 +1340,7 @@ ftoi2(PG_FUNCTION_ARGS)
 
        /* Range check */
        if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT16(num)))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("smallint out of range")));
 
index ff54d50ea9ddfb84097a33a435b9c792f0c19c97..4c894a49d5d80c1997a7976f72eaa025a332ec74 100644 (file)
@@ -379,7 +379,7 @@ i4toi2(PG_FUNCTION_ARGS)
        int32           arg1 = PG_GETARG_INT32(0);
 
        if (unlikely(arg1 < SHRT_MIN) || unlikely(arg1 > SHRT_MAX))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("smallint out of range")));
 
index 6c8fb7b7275bead16d3efce52c251eedfc11901a..19bb30f2d0f53a78a59b7def3d884cbe1068a383 100644 (file)
@@ -1251,7 +1251,7 @@ int84(PG_FUNCTION_ARGS)
        int64           arg = PG_GETARG_INT64(0);
 
        if (unlikely(arg < PG_INT32_MIN) || unlikely(arg > PG_INT32_MAX))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("integer out of range")));
 
@@ -1272,7 +1272,7 @@ int82(PG_FUNCTION_ARGS)
        int64           arg = PG_GETARG_INT64(0);
 
        if (unlikely(arg < PG_INT16_MIN) || unlikely(arg > PG_INT16_MAX))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("smallint out of range")));
 
@@ -1307,7 +1307,7 @@ dtoi8(PG_FUNCTION_ARGS)
 
        /* Range check */
        if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT64(num)))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("bigint out of range")));
 
@@ -1342,7 +1342,7 @@ ftoi8(PG_FUNCTION_ARGS)
 
        /* Range check */
        if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT64(num)))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("bigint out of range")));
 
@@ -1355,7 +1355,7 @@ i8tooid(PG_FUNCTION_ARGS)
        int64           arg = PG_GETARG_INT64(0);
 
        if (unlikely(arg < 0) || unlikely(arg > PG_UINT32_MAX))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("OID out of range")));
 
index c1bf9fd5783b9ef422a5f08749820e74e33ab60f..0425ea473a529fe035c41aaab70d431dcdac9f64 100644 (file)
@@ -550,7 +550,7 @@ macaddr8tomacaddr(PG_FUNCTION_ARGS)
        result = palloc0_object(macaddr);
 
        if ((addr->d != 0xFF) || (addr->e != 0xFE))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("macaddr8 data out of range to convert to macaddr"),
                                 errhint("Only addresses that have FF and FE as values in the "
index 3a2002097ddcebf420cd4030c88303109347f778..c7e0828764e7b1a6b595af9b4355e6f4222da581 100644 (file)
@@ -1137,7 +1137,7 @@ network_show(PG_FUNCTION_ARGS)
 
        if (pg_inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
                                                 tmp, sizeof(tmp)) == NULL)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                                 errmsg("could not format inet value: %m")));
 
index d25b8ad505dc7b8eab18fd205db8e45c7d8c3123..cb23dfe9b9506821e519c344ee4d955154584b4b 100644 (file)
@@ -1244,7 +1244,8 @@ numeric           (PG_FUNCTION_ARGS)
         */
        if (NUMERIC_IS_SPECIAL(num))
        {
-               (void) apply_typmod_special(num, typmod, NULL);
+               if (!apply_typmod_special(num, typmod, fcinfo->context))
+                       PG_RETURN_NULL();
                PG_RETURN_NUMERIC(duplicate_numeric(num));
        }
 
@@ -1295,8 +1296,9 @@ numeric           (PG_FUNCTION_ARGS)
        init_var(&var);
 
        set_var_from_num(num, &var);
-       (void) apply_typmod(&var, typmod, NULL);
-       new = make_result(&var);
+       if (!apply_typmod(&var, typmod, fcinfo->context))
+               PG_RETURN_NULL();
+       new = make_result_safe(&var, fcinfo->context);
 
        free_var(&var);
 
@@ -3018,7 +3020,10 @@ numeric_mul(PG_FUNCTION_ARGS)
        Numeric         num2 = PG_GETARG_NUMERIC(1);
        Numeric         res;
 
-       res = numeric_mul_safe(num1, num2, NULL);
+       res = numeric_mul_safe(num1, num2, fcinfo->context);
+
+       if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
+               PG_RETURN_NULL();
 
        PG_RETURN_NUMERIC(res);
 }
@@ -4393,8 +4398,14 @@ Datum
 numeric_int4(PG_FUNCTION_ARGS)
 {
        Numeric         num = PG_GETARG_NUMERIC(0);
+       int32           result;
+
+       result = numeric_int4_safe(num, fcinfo->context);
+
+       if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
+               PG_RETURN_NULL();
 
-       PG_RETURN_INT32(numeric_int4_safe(num, NULL));
+       PG_RETURN_INT32(result);
 }
 
 /*
@@ -4463,8 +4474,14 @@ Datum
 numeric_int8(PG_FUNCTION_ARGS)
 {
        Numeric         num = PG_GETARG_NUMERIC(0);
+       int64           result;
+
+       result = numeric_int8_safe(num, fcinfo->context);
 
-       PG_RETURN_INT64(numeric_int8_safe(num, NULL));
+       if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
+               PG_RETURN_NULL();
+
+       PG_RETURN_INT64(result);
 }
 
 
@@ -4488,11 +4505,11 @@ numeric_int2(PG_FUNCTION_ARGS)
        if (NUMERIC_IS_SPECIAL(num))
        {
                if (NUMERIC_IS_NAN(num))
-                       ereport(ERROR,
+                       ereturn(fcinfo->context, (Datum) 0,
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                         errmsg("cannot convert NaN to %s", "smallint")));
                else
-                       ereport(ERROR,
+                       ereturn(fcinfo->context, (Datum) 0,
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                         errmsg("cannot convert infinity to %s", "smallint")));
        }
@@ -4501,12 +4518,12 @@ numeric_int2(PG_FUNCTION_ARGS)
        init_var_from_num(num, &x);
 
        if (!numericvar_to_int64(&x, &val))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("smallint out of range")));
 
        if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("smallint out of range")));
 
@@ -4542,7 +4559,8 @@ float8_numeric(PG_FUNCTION_ARGS)
        init_var(&result);
 
        /* Assume we need not worry about leading/trailing spaces */
-       (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
+       if (!set_var_from_str(buf, buf, &result, &endptr, fcinfo->context))
+               PG_RETURN_NULL();
 
        res = make_result(&result);
 
@@ -4571,10 +4589,14 @@ numeric_float8(PG_FUNCTION_ARGS)
 
        tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
                                                                                          NumericGetDatum(num)));
-
-       result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
-
-       pfree(tmp);
+       if (!DirectInputFunctionCallSafe(float8in, tmp,
+                                                                        InvalidOid, -1,
+                                                                        (Node *) fcinfo->context,
+                                                                        &result))
+       {
+               pfree(tmp);
+               PG_RETURN_NULL();
+       }
 
        PG_RETURN_DATUM(result);
 }
@@ -4636,7 +4658,8 @@ float4_numeric(PG_FUNCTION_ARGS)
        init_var(&result);
 
        /* Assume we need not worry about leading/trailing spaces */
-       (void) set_var_from_str(buf, buf, &result, &endptr, NULL);
+       if (!set_var_from_str(buf, buf, &result, &endptr, fcinfo->context))
+               PG_RETURN_NULL();
 
        res = make_result(&result);
 
@@ -4666,7 +4689,14 @@ numeric_float4(PG_FUNCTION_ARGS)
        tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
                                                                                          NumericGetDatum(num)));
 
-       result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
+       if (!DirectInputFunctionCallSafe(float4in, tmp,
+                                                                        InvalidOid, -1,
+                                                                        (Node *) fcinfo->context,
+                                                                        &result))
+       {
+               pfree(tmp);
+               PG_RETURN_NULL();
+       }
 
        pfree(tmp);
 
index 50a73fd24ec88a55367dd97978d3b1a341466ff2..288d696be77506f31d4120c2950510756e766ff0 100644 (file)
@@ -343,7 +343,8 @@ timestamp_scale(PG_FUNCTION_ARGS)
 
        result = timestamp;
 
-       AdjustTimestampForTypmod(&result, typmod, NULL);
+       if (!AdjustTimestampForTypmod(&result, typmod, fcinfo->context))
+               PG_RETURN_NULL();
 
        PG_RETURN_TIMESTAMP(result);
 }
@@ -866,7 +867,8 @@ timestamptz_scale(PG_FUNCTION_ARGS)
 
        result = timestamp;
 
-       AdjustTimestampForTypmod(&result, typmod, NULL);
+       if (!AdjustTimestampForTypmod(&result, typmod, fcinfo->context))
+               PG_RETURN_NULL();
 
        PG_RETURN_TIMESTAMPTZ(result);
 }
@@ -1325,7 +1327,8 @@ interval_scale(PG_FUNCTION_ARGS)
        result = palloc_object(Interval);
        *result = *interval;
 
-       AdjustIntervalForTypmod(result, typmod, NULL);
+       if (!AdjustIntervalForTypmod(result, typmod, fcinfo->context))
+               PG_RETURN_NULL();
 
        PG_RETURN_INTERVAL_P(result);
 }
@@ -6421,8 +6424,13 @@ Datum
 timestamp_timestamptz(PG_FUNCTION_ARGS)
 {
        Timestamp       timestamp = PG_GETARG_TIMESTAMP(0);
+       TimestampTz result;
+
+       result = timestamp2timestamptz_safe(timestamp, fcinfo->context);
+       if (SOFT_ERROR_OCCURRED(fcinfo->context))
+               PG_RETURN_NULL();
 
-       PG_RETURN_TIMESTAMPTZ(timestamp2timestamptz(timestamp));
+       PG_RETURN_TIMESTAMPTZ(result);
 }
 
 /*
@@ -6484,8 +6492,13 @@ Datum
 timestamptz_timestamp(PG_FUNCTION_ARGS)
 {
        TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
+       Timestamp       result;
 
-       PG_RETURN_TIMESTAMP(timestamptz2timestamp(timestamp));
+       result = timestamptz2timestamp_safe(timestamp, fcinfo->context);
+       if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
+               PG_RETURN_NULL();
+
+       PG_RETURN_TIMESTAMP(result);
 }
 
 /*
index 65ad1bfe18f660a2c6d7eb013a5f440dcd46bc2a..c46b5bae70d6149093a7d225360d8ddfa2c8553b 100644 (file)
@@ -401,7 +401,7 @@ bit(PG_FUNCTION_ARGS)
                PG_RETURN_VARBIT_P(arg);
 
        if (!isExplicit)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
                                 errmsg("bit string length %d does not match type bit(%d)",
                                                VARBITLEN(arg), len)));
@@ -752,7 +752,7 @@ varbit(PG_FUNCTION_ARGS)
                PG_RETURN_VARBIT_P(arg);
 
        if (!isExplicit)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
                                 errmsg("bit string too long for type bit varying(%d)",
                                                len)));
@@ -1591,7 +1591,7 @@ bittoint4(PG_FUNCTION_ARGS)
 
        /* Check that the bit string is not too long */
        if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("integer out of range")));
 
@@ -1671,7 +1671,7 @@ bittoint8(PG_FUNCTION_ARGS)
 
        /* Check that the bit string is not too long */
        if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
-               ereport(ERROR,
+               ereturn(fcinfo->context, (Datum) 0,
                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                 errmsg("bigint out of range")));
 
index df305098130e626c344619c1d756cf2a18f15465..a62e55eec196bf2ed1198cb754b6f8388b9c6b40 100644 (file)
@@ -307,7 +307,7 @@ bpchar(PG_FUNCTION_ARGS)
                {
                        for (i = maxmblen; i < len; i++)
                                if (s[i] != ' ')
-                                       ereport(ERROR,
+                                       ereturn(fcinfo->context, (Datum) 0,
                                                        (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
                                                         errmsg("value too long for type character(%d)",
                                                                        maxlen)));
@@ -634,7 +634,7 @@ varchar(PG_FUNCTION_ARGS)
        {
                for (i = maxmblen; i < len; i++)
                        if (s_data[i] != ' ')
-                               ereport(ERROR,
+                               ereturn(fcinfo->context, (Datum) 0,
                                                (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
                                                 errmsg("value too long for type character varying(%d)",
                                                                maxlen)));
index 79f6cf7b4fa76619c97fd7e55880f338d6087c1b..2c7f778cfdb7a416da533e6cb570dc0c4398946d 100644 (file)
@@ -660,7 +660,7 @@ texttoxml(PG_FUNCTION_ARGS)
 {
        text       *data = PG_GETARG_TEXT_PP(0);
 
-       PG_RETURN_XML_P(xmlparse(data, xmloption, true));
+       PG_RETURN_XML_P(xmlparse(data, xmloption, true, fcinfo->context));
 }
 
 
@@ -1029,14 +1029,18 @@ xmlelement(XmlExpr *xexpr,
 
 
 xmltype *
-xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace)
+xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, Node *escontext)
 {
 #ifdef USE_LIBXML
        xmlDocPtr       doc;
 
        doc = xml_parse(data, xmloption_arg, preserve_whitespace,
-                                       GetDatabaseEncoding(), NULL, NULL, NULL);
-       xmlFreeDoc(doc);
+                                       GetDatabaseEncoding(), NULL, NULL, escontext);
+       if (doc)
+               xmlFreeDoc(doc);
+
+       if (SOFT_ERROR_OCCURRED(escontext))
+               return NULL;
 
        return (xmltype *) data;
 #else
index 023fdeb453135fe8f6ad7b73e45b71f70e61a28b..ca266f448d689b650d5ffaeee880ad417c2b462a 100644 (file)
@@ -73,7 +73,7 @@ extern xmltype *xmlconcat(List *args);
 extern xmltype *xmlelement(XmlExpr *xexpr,
                                                   const Datum *named_argvalue, const bool *named_argnull,
                                                   const Datum *argvalue, const bool *argnull);
-extern xmltype *xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace);
+extern xmltype *xmlparse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, Node *escontext);
 extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *result_is_null);
 extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
 extern bool xml_is_document(xmltype *arg);