diff --git a/src/common/backend/parser/parse_coerce.cpp b/src/common/backend/parser/parse_coerce.cpp index c5bf52937..5ed095a89 100644 --- a/src/common/backend/parser/parse_coerce.cpp +++ b/src/common/backend/parser/parse_coerce.cpp @@ -394,9 +394,11 @@ Node* coerce_type(ParseState* pstate, Node* node, Oid inputTypeId, Oid targetTyp * as CSTRING. */ if (!con->constisnull) { - newcon->constvalue = stringTypeDatum(targetType, DatumGetCString(con->constvalue), inputTypeMod); + newcon->constvalue = stringTypeDatum(targetType, DatumGetCString(con->constvalue), inputTypeMod, + pstate != NULL && pstate->p_has_ignore); } else { - newcon->constvalue = stringTypeDatum(targetType, NULL, inputTypeMod); + newcon->constvalue = + stringTypeDatum(targetType, NULL, inputTypeMod, pstate != NULL && pstate->p_has_ignore); } cancel_parser_errposition_callback(&pcbstate); diff --git a/src/common/backend/parser/parse_type.cpp b/src/common/backend/parser/parse_type.cpp index 7ba70cbd0..a6b1c7444 100644 --- a/src/common/backend/parser/parse_type.cpp +++ b/src/common/backend/parser/parse_type.cpp @@ -761,15 +761,18 @@ Oid typeTypeCollation(Type typ) * Given a type structure and a string, returns the internal representation * of that string. The "string" can be NULL to perform conversion of a NULL * (which might result in failure, if the input function rejects NULLs). + * + * With param can_ignore == true, truncation or transformation may be cast + * for input string if string is invalid for target type. */ -Datum stringTypeDatum(Type tp, char* string, int32 atttypmod) +Datum stringTypeDatum(Type tp, char* string, int32 atttypmod, bool can_ignore) { Form_pg_type typform = (Form_pg_type)GETSTRUCT(tp); Oid typinput = typform->typinput; Oid typioparam = getTypeIOParam(tp); Datum result; - result = OidInputFunctionCall(typinput, string, typioparam, atttypmod); + result = OidInputFunctionCall(typinput, string, typioparam, atttypmod, can_ignore); #ifdef RANDOMIZE_ALLOCATED_MEMORY diff --git a/src/common/backend/utils/adt/date.cpp b/src/common/backend/utils/adt/date.cpp index a1c96e8e0..207e607f1 100644 --- a/src/common/backend/utils/adt/date.cpp +++ b/src/common/backend/utils/adt/date.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "access/hash.h" #include "commands/copy.h" @@ -50,6 +51,7 @@ static int timetz2tm(TimeTzADT* time, struct pg_tm* tm, fsec_t* fsec, int* tzp); static int tm2time(struct pg_tm* tm, fsec_t fsec, TimeADT* result); static int tm2timetz(struct pg_tm* tm, fsec_t fsec, int tz, TimeTzADT* result); static void AdjustTimeForTypmod(TimeADT* time, int32 typmod); +static int getStartingDigits(char* str); /* common code for timetypmodin and timetztypmodin */ static int32 anytime_typmodin(bool istz, ArrayType* ta) @@ -102,6 +104,26 @@ static char* anytime_typmodout(bool istz, int32 typmod) return res; } +/* + * Get starting digits of input string and return as int + * + * If the first character is not digit, return -1. NOTICE that if the first character is '+' or '-', + * it will consider it as invalid digit. So handle starting '+' nad '-' before using this function. + */ +static int getStartingDigits(char* str) +{ + int digitnum = 0; + long trunc_val = 0; + while (isdigit((unsigned char)*str)) { + trunc_val = trunc_val * 10 + (*str++ - '0'); + digitnum++; + if (trunc_val > PG_INT32_MAX) { + return PG_INT32_MAX; + } + } + return digitnum == 0 ? -1 : trunc_val; +} + /***************************************************************************** * Date ADT *****************************************************************************/ @@ -142,8 +164,13 @@ Datum date_in(PG_FUNCTION_ARGS) dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp); - if (dterr != 0) - DateTimeParseError(dterr, str, "date"); + if (dterr != 0) { + DateTimeParseError(dterr, str, "date", fcinfo->can_ignore); + /* + * if reporting warning in DateTimeParseError, return 1970-01-01 + */ + PG_RETURN_DATEADT(UNIX_EPOCH_JDATE - POSTGRES_EPOCH_JDATE); + } switch (dtype) { case DTK_DATE: @@ -176,7 +203,7 @@ Datum date_in(PG_FUNCTION_ARGS) } /* - * the following logic is unified for date parsing. + * the following logic is unified for date parsing.` */ if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday)) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("date out of range: \"%s\"", str))); @@ -1101,8 +1128,22 @@ Datum time_in(PG_FUNCTION_ARGS) dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz); - if (dterr != 0) - DateTimeParseError(dterr, str, "time"); + if (dterr != 0) { + DateTimeParseError(dterr, str, "time", fcinfo->can_ignore); + /* + * can_ignore == true means hint string "ignore_error" used. warning report instead of error. + * then we will return 00:00:xx if the first 1 or 2 character is lower than 60, otherwise return 00:00:00 + */ + char* field_str = field[0]; + if (*field_str == '+') { + field_str++; + } + int trunc_val = getStartingDigits(field_str); + if (trunc_val < 0 || trunc_val >= 60) { + PG_RETURN_TIMEADT(0); + } + PG_RETURN_TIMEADT(trunc_val * 1000 * 1000); + } } /* @@ -1836,8 +1877,22 @@ Datum timetz_in(PG_FUNCTION_ARGS) dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz); - if (dterr != 0) - DateTimeParseError(dterr, str, "time with time zone"); + if (dterr != 0) { + DateTimeParseError(dterr, str, "time with time zone", fcinfo->can_ignore); + /* + * can_ignore == true means hint string "ignore_error" used. warning report instead of error. + * then we will return 00:00:xx if the first 1 or 2 character is lower than 60, otherwise return 00:00:00 + */ + char* field_str = field[0]; + if (*field_str == '+') { + field_str++; + } + tm->tm_hour = 0; + tm->tm_min = 0; + int trunc_val = getStartingDigits(field_str); + tm->tm_sec = (trunc_val < 0 || trunc_val >= 60) ? 0 : trunc_val; + fsec = 0; + } result = (TimeTzADT*)palloc(sizeof(TimeTzADT)); tm2timetz(tm, fsec, tz, result); diff --git a/src/common/backend/utils/adt/datetime.cpp b/src/common/backend/utils/adt/datetime.cpp index 39bfbced5..26b02cc20 100644 --- a/src/common/backend/utils/adt/datetime.cpp +++ b/src/common/backend/utils/adt/datetime.cpp @@ -3240,32 +3240,33 @@ int DecodeUnits(int field, const char* lowtoken, int* val) * DTERR_TZDISP_OVERFLOW from DTERR_FIELD_OVERFLOW, but SQL99 mandates three * separate SQLSTATE codes, so ... */ -void DateTimeParseError(int dterr, const char* str, const char* datatype) +void DateTimeParseError(int dterr, const char* str, const char* datatype, bool can_ignore) { + int level = can_ignore ? WARNING : ERROR; switch (dterr) { case DTERR_FIELD_OVERFLOW: - ereport(ERROR, + ereport(level, (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW), errmsg("date/time field value out of range: \"%s\"", str))); break; case DTERR_MD_FIELD_OVERFLOW: /* same as above, but add hint about u_sess->time_cxt.DateStyle */ - ereport(ERROR, + ereport(level, (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW), errmsg("date/time field value out of range: \"%s\"", str), errhint("Perhaps you need a different \"datestyle\" setting."))); break; case DTERR_INTERVAL_OVERFLOW: - ereport(ERROR, + ereport(level, (errcode(ERRCODE_INTERVAL_FIELD_OVERFLOW), errmsg("interval field value out of range: \"%s\"", str))); break; case DTERR_TZDISP_OVERFLOW: - ereport(ERROR, + ereport(level, (errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE), errmsg("time zone displacement out of range: \"%s\"", str))); break; case DTERR_BAD_FORMAT: default: - ereport(ERROR, + ereport(level, (errcode(ERRCODE_INVALID_DATETIME_FORMAT), errmsg("invalid input syntax for type %s: \"%s\"", datatype, str))); break; @@ -4300,7 +4301,7 @@ static void check_dtype (int dtype, struct pg_tm *tm, fsec_t fsec, Interval *res } } -Interval *char_to_interval(char *str, int32 typmod) { +Interval *char_to_interval(char *str, int32 typmod, bool can_ignore) { Interval *result = NULL; fsec_t fsec = 0; struct pg_tm tt, *tm = &tt; @@ -4343,7 +4344,14 @@ Interval *char_to_interval(char *str, int32 typmod) { if (dterr != 0) { if (dterr == DTERR_FIELD_OVERFLOW) dterr = DTERR_INTERVAL_OVERFLOW; - DateTimeParseError(dterr, str, "interval"); + DateTimeParseError(dterr, str, "interval", can_ignore); + /* if invalid input error is ignorable, set the result to 0 */ + tm->tm_year = 0; + tm->tm_mon = 0; + tm->tm_mday = 0; + tm->tm_hour = 0; + tm->tm_min = 0; + tm->tm_sec = 0; } // process negative ISO8601 interval if (true == isnegative) { diff --git a/src/common/backend/utils/adt/float.cpp b/src/common/backend/utils/adt/float.cpp index d93e79c83..f76a2c971 100644 --- a/src/common/backend/utils/adt/float.cpp +++ b/src/common/backend/utils/adt/float.cpp @@ -300,11 +300,13 @@ Datum float4in(PG_FUNCTION_ARGS) * detect whether it's a "real" out-of-range condition by checking * to see if the result is zero or huge. */ - if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type real", orig_num))); - } else + if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL) { + ereport((fcinfo->can_ignore ? WARNING : ERROR), + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type real", orig_num))); + val = (val == 0.0 ? 0 : (val >= HUGE_VAL ? FLT_MAX : FLT_MIN)); + } + } else if (!fcinfo->can_ignore) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type real: \"%s\"", orig_num))); @@ -346,8 +348,8 @@ Datum float4in(PG_FUNCTION_ARGS) while (*endptr != '\0' && isspace((unsigned char)*endptr)) endptr++; - /* if there is any junk left at the end of the string, bail out */ - if (*endptr != '\0') + /* if there is any junk left at the end of the string, bail out. if can_ignore == true, discard junk and continue */ + if (*endptr != '\0' && !fcinfo->can_ignore) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type real: \"%s\"", orig_num))); @@ -365,6 +367,11 @@ Datum float4in(PG_FUNCTION_ARGS) ereport(WARNING, (errmsg("value out of range: underflow"))); PG_RETURN_FLOAT4(0); } + if (*endptr != '\0') { + ereport(WARNING, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type real: \"%s\". truncated automatically", orig_num))); + } PG_RETURN_FLOAT4((float4)val); } CHECKFLOATVAL((float4)val, isinf(val), val == 0); @@ -529,11 +536,13 @@ Datum float8in(PG_FUNCTION_ARGS) * detect whether it's a "real" out-of-range condition by checking * to see if the result is zero or huge. */ - if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type double precision", orig_num))); - } else + if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL) { + ereport(fcinfo->can_ignore ? WARNING : ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type double precision", orig_num))); + val = (val == 0.0 ? 0 : (val >= HUGE_VAL ? DBL_MAX : DBL_MIN)); + } + } else if (!fcinfo->can_ignore) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type double precision: \"%s\"", orig_num))); @@ -575,11 +584,18 @@ Datum float8in(PG_FUNCTION_ARGS) while (*endptr != '\0' && isspace((unsigned char)*endptr)) endptr++; - /* if there is any junk left at the end of the string, bail out */ - if (*endptr != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type double precision: \"%s\"", orig_num))); + /* if there is any junk left at the end of the string, bail out. if can_ignore == true, discard junk and continue. */ + if (*endptr != '\0') { + if (fcinfo->can_ignore) { + ereport(WARNING, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type double precision: \"%s\". truncated automatically", orig_num))); + } else { + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type double precision: \"%s\"", orig_num))); + } + } CHECKFLOATVAL(val, true, true); diff --git a/src/common/backend/utils/adt/geo_ops.cpp b/src/common/backend/utils/adt/geo_ops.cpp index 79e11394c..f1c3f2d19 100644 --- a/src/common/backend/utils/adt/geo_ops.cpp +++ b/src/common/backend/utils/adt/geo_ops.cpp @@ -379,9 +379,16 @@ Datum box_in(PG_FUNCTION_ARGS) char* s = NULL; double x, y; - if ((!path_decode(FALSE, 2, str, &isopen, &s, &(box->high))) || (*s != '\0')) - ereport(ERROR, + if ((!path_decode(FALSE, 2, str, &isopen, &s, &(box->high))) || (*s != '\0')) { + ereport(fcinfo->can_ignore ? WARNING : ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type box: \"%s\"", str))); + /* if syntax error is ignorable, report warning and return box (0,0),(0,0) */ + box->low.x = 0; + box->low.y = 0; + box->high.x = 0; + box->high.y = 0; + PG_RETURN_BOX_P(box); + } /* reorder corners if necessary... */ if (box->high.x < box->low.x) { @@ -1291,9 +1298,13 @@ Datum path_in(PG_FUNCTION_ARGS) int base_size; int depth = 0; - if ((npts = pair_count(str, ',')) <= 0) - ereport(ERROR, + int level = fcinfo->can_ignore ? WARNING : ERROR; + if ((npts = pair_count(str, ',')) <= 0) { + ereport(level, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type path: \"%s\"", str))); + /* if invalid syntax is ignorable, report warning and return path ((0,0)) */ + PG_RETURN_DATUM((Datum)DirectFunctionCall1(path_in, CStringGetDatum("0,0"))); + } s = str; while (isspace((unsigned char)*s)) { @@ -1319,9 +1330,12 @@ Datum path_in(PG_FUNCTION_ARGS) path->npts = npts; if ((!path_decode(TRUE, npts, s, &isopen, &s, &(path->p[0]))) && (!((depth == 0) && (*s == '\0'))) && - !((depth >= 1) && (*s == RDELIM))) - ereport(ERROR, + !((depth >= 1) && (*s == RDELIM))) { + ereport(level, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type path: \"%s\"", str))); + /* if invalid syntax is ignorable, report warning and return path ((0,0)) */ + PG_RETURN_DATUM((Datum)DirectFunctionCall1(path_in, CStringGetDatum("0,0"))); + } path->closed = (!isopen); /* prevent instability in unused pad bytes */ @@ -1659,9 +1673,13 @@ Datum point_in(PG_FUNCTION_ARGS) double x, y; char* s = NULL; - if (!pair_decode(str, &x, &y, &s) || (*s != '\0')) - ereport(ERROR, + if (!pair_decode(str, &x, &y, &s) || (*s != '\0')) { + ereport(fcinfo->can_ignore ? WARNING : ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type point: \"%s\"", str))); + /* if syntax error is ignorable, return point as (0,0) */ + x = 0; + y = 0; + } point = (Point*)palloc(sizeof(Point)); @@ -1864,9 +1882,12 @@ Datum lseg_in(PG_FUNCTION_ARGS) lseg = (LSEG*)palloc(sizeof(LSEG)); - if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0]))) || (*s != '\0')) - ereport(ERROR, + if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg->p[0]))) || (*s != '\0')) { + ereport(fcinfo->can_ignore ? WARNING : ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type lseg: \"%s\"", str))); + /* if syntax error is ignorable, reporting warning and return lseg [(0,0),(0,0)] */ + PG_RETURN_DATUM((Datum)DirectFunctionCall1(box_in, CStringGetDatum("0,0,0,0"))); + } #ifdef NOT_USED lseg->m = point_sl(&lseg->p[0], &lseg->p[1]); @@ -3149,10 +3170,14 @@ Datum poly_in(PG_FUNCTION_ARGS) int isopen; char* s = NULL; - if ((npts = pair_count(str, ',')) <= 0) - ereport(ERROR, + int level = fcinfo->can_ignore ? WARNING : ERROR; + if ((npts = pair_count(str, ',')) <= 0) { + ereport(level, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type polygon: \"%s\"", str))); + /* if invalid syntax error is ignorable, report warning and return '((0,0))' */ + PG_RETURN_DATUM((Datum)DirectFunctionCall1(poly_in, CStringGetDatum("(0,0)"))); + } base_size = sizeof(poly->p[0]) * npts; size = offsetof(POLYGON, p) + base_size; @@ -3166,10 +3191,13 @@ Datum poly_in(PG_FUNCTION_ARGS) SET_VARSIZE(poly, size); poly->npts = npts; - if ((!path_decode(FALSE, npts, str, &isopen, &s, &(poly->p[0]))) || (*s != '\0')) - ereport(ERROR, + if ((!path_decode(FALSE, npts, str, &isopen, &s, &(poly->p[0]))) || (*s != '\0')) { + ereport(level, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type polygon: \"%s\"", str))); + /* if invalid syntax error is ignorable, report warning and return '((0,0))' */ + PG_RETURN_DATUM((Datum)DirectFunctionCall1(poly_in, CStringGetDatum("(0,0)"))); + } make_bound_box(poly); @@ -4115,9 +4143,7 @@ Datum circle_in(PG_FUNCTION_ARGS) } if (!pair_decode(s, &circle->center.x, &circle->center.y, &s)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type circle: \"%s\"", str))); + goto syntax_error_handle; if (*s == DELIM) s++; @@ -4126,9 +4152,7 @@ Datum circle_in(PG_FUNCTION_ARGS) } if ((!single_decode(s, &circle->radius, &s)) || (circle->radius < 0)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type circle: \"%s\"", str))); + goto syntax_error_handle; while (depth > 0) { if ((*s == RDELIM) || ((*s == RDELIM_C) && (depth == 1))) { @@ -4138,17 +4162,21 @@ Datum circle_in(PG_FUNCTION_ARGS) s++; } } else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type circle: \"%s\"", str))); + goto syntax_error_handle; } if (*s != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type circle: \"%s\"", str))); + goto syntax_error_handle; PG_RETURN_CIRCLE_P(circle); + +syntax_error_handle: + int level = fcinfo->can_ignore ? WARNING : ERROR; + ereport(level, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type circle: \"%s\"", str))); + /* if syntax error is ignorable, report warning and return circle '<(0,0),0>' */ + PG_RETURN_DATUM((Datum)DirectFunctionCall1(circle_in, CStringGetDatum("0,0,0"))); } /* circle_out - convert a circle to external form. diff --git a/src/common/backend/utils/adt/int.cpp b/src/common/backend/utils/adt/int.cpp index 031d39c19..ac2059bbd 100644 --- a/src/common/backend/utils/adt/int.cpp +++ b/src/common/backend/utils/adt/int.cpp @@ -61,7 +61,7 @@ Datum int2in(PG_FUNCTION_ARGS) { char* num = PG_GETARG_CSTRING(0); - PG_RETURN_INT16(pg_strtoint16(num)); + PG_RETURN_INT16(pg_strtoint16(num, fcinfo->can_ignore)); } /* @@ -296,7 +296,7 @@ Datum int4in(PG_FUNCTION_ARGS) { char* num = PG_GETARG_CSTRING(0); - PG_RETURN_INT32(pg_strtoint32(num)); + PG_RETURN_INT32(pg_strtoint32(num, fcinfo->can_ignore)); } /* @@ -1224,7 +1224,7 @@ Datum int1in(PG_FUNCTION_ARGS) { char* num = PG_GETARG_CSTRING(0); - PG_RETURN_UINT8((uint8)pg_atoi(num, sizeof(uint8), '\0')); + PG_RETURN_UINT8((uint8)pg_atoi(num, sizeof(uint8), '\0', fcinfo->can_ignore)); } // int1out - converts uint8 to "num" diff --git a/src/common/backend/utils/adt/int8.cpp b/src/common/backend/utils/adt/int8.cpp index d904a33dc..d187f5e1d 100644 --- a/src/common/backend/utils/adt/int8.cpp +++ b/src/common/backend/utils/adt/int8.cpp @@ -48,8 +48,11 @@ typedef struct { * * If errorOK is false, ereport a useful error message if the string is bad. * If errorOK is true, just return "false" for bad input. + * + * Param can_ignore is true when using ignore hint, which will ignore errors of + * overflowing or invalid input. */ -bool scanint8(const char* str, bool errorOK, int64* result) +bool scanint8(const char* str, bool errorOK, int64* result, bool can_ignore) { const char* ptr = str; int64 tmp = 0; @@ -95,6 +98,13 @@ bool scanint8(const char* str, bool errorOK, int64* result) int8 digit = (*ptr++ - '0'); if (unlikely(pg_mul_s64_overflow(tmp, 10, &tmp)) || unlikely(pg_sub_s64_overflow(tmp, digit, &tmp))) { + if (can_ignore) { + ereport(WARNING, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type %s. truncated automatically", str, "bigint"))); + *result = neg ? PG_INT64_MIN : PG_INT64_MAX; + return true; + } if (errorOK) return false; else @@ -110,14 +120,15 @@ bool scanint8(const char* str, bool errorOK, int64* result) } if (unlikely(*ptr != '\0')) { - if (errorOK) - return false; - else - /* Empty string will be treated as NULL if sql_compatibility == A_FORMAT, - Other wise whitespace will be convert to 0 */ - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type %s: \"%s\"", "bigint", str))); + if (!can_ignore) { + if (errorOK) + return false; + else + /* Empty string will be treated as NULL if sql_compatibility == A_FORMAT, + Other wise whitespace will be convert to 0 */ + ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s: \"%s\"", "bigint", str))); + } } if (!neg) { @@ -144,7 +155,7 @@ Datum int8in(PG_FUNCTION_ARGS) char* str = PG_GETARG_CSTRING(0); int64 result; - (void)scanint8(str, false, &result); + (void)scanint8(str, false, &result, fcinfo->can_ignore); PG_RETURN_INT64(result); } diff --git a/src/common/backend/utils/adt/json.cpp b/src/common/backend/utils/adt/json.cpp index b533ef10a..b6fc8ce1b 100644 --- a/src/common/backend/utils/adt/json.cpp +++ b/src/common/backend/utils/adt/json.cpp @@ -162,7 +162,22 @@ Datum json_in(PG_FUNCTION_ARGS) /* validate it */ lex = makeJsonLexContext(result, false); - pg_parse_json(lex, &nullSemAction); + PG_TRY(); + { + pg_parse_json(lex, &nullSemAction); + } + PG_CATCH(); + { + if (fcinfo->can_ignore) { + ereport(WARNING, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type json"))); + PG_RETURN_DATUM((Datum)DirectFunctionCall1(json_in, CStringGetDatum("null"))); + } else { + PG_RE_THROW(); + } + } + PG_END_TRY(); /* Internal representation is the same as text, for now */ PG_RETURN_TEXT_P(result); diff --git a/src/common/backend/utils/adt/jsonb.cpp b/src/common/backend/utils/adt/jsonb.cpp index 983c47aac..12d021ccf 100644 --- a/src/common/backend/utils/adt/jsonb.cpp +++ b/src/common/backend/utils/adt/jsonb.cpp @@ -18,6 +18,7 @@ #include "utils/json.h" #include "utils/jsonapi.h" #include "utils/jsonb.h" +#include "knl/knl_thread.h" typedef struct JsonbInState { JsonbParseState *parseState; @@ -43,7 +44,24 @@ Datum jsonb_in(PG_FUNCTION_ARGS) char *json = PG_GETARG_CSTRING(0); json = json == NULL ? pstrdup("") : json; - return jsonb_from_cstring(json, strlen(json)); + Datum result; + PG_TRY(); + { + result = jsonb_from_cstring(json, strlen(json)); + } + PG_CATCH(); + { + if (fcinfo->can_ignore) { + ereport(WARNING, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type json"))); + PG_RETURN_DATUM((Datum)DirectFunctionCall1(jsonb_in, CStringGetDatum("null"))); + } else { + PG_RE_THROW(); + } + } + PG_END_TRY(); + return result; } /* diff --git a/src/common/backend/utils/adt/nabstime.cpp b/src/common/backend/utils/adt/nabstime.cpp index 800feaf0c..874dca267 100644 --- a/src/common/backend/utils/adt/nabstime.cpp +++ b/src/common/backend/utils/adt/nabstime.cpp @@ -68,7 +68,7 @@ static AbsoluteTime tm2abstime(struct pg_tm* tm, int tz); static void reltime2tm(RelativeTime time, struct pg_tm* tm); -static void parsetinterval(char* i_string, AbsoluteTime* i_start, AbsoluteTime* i_end); +static void parsetinterval(char* i_string, AbsoluteTime* i_start, AbsoluteTime* i_end, bool can_ignore = false); extern TimestampTz GetCurrentStmtsysTimestamp(void); @@ -659,7 +659,7 @@ Datum tintervalin(PG_FUNCTION_ARGS) TimeInterval tinterval; AbsoluteTime i_start, i_end, t1, t2; - parsetinterval(tintervalstr, &t1, &t2); + parsetinterval(tintervalstr, &t1, &t2, fcinfo->can_ignore); tinterval = (TimeInterval)palloc(sizeof(TimeIntervalData)); @@ -1325,7 +1325,7 @@ Datum tintervalend(PG_FUNCTION_ARGS) * * e.g. [ ' Jan 18 1902' 'Jan 1 00:00:00 1970'] */ -static void parsetinterval(char* i_string, AbsoluteTime* i_start, AbsoluteTime* i_end) +static void parsetinterval(char* i_string, AbsoluteTime* i_start, AbsoluteTime* i_end, bool can_ignore) { char *p = NULL, *p1 = NULL; char c; @@ -1419,10 +1419,18 @@ static void parsetinterval(char* i_string, AbsoluteTime* i_start, AbsoluteTime* return; bogus: - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("invalid input syntax for type tinterval: \"%s\"", i_string))); - *i_start = *i_end = INVALID_ABSTIME; /* keep compiler quiet */ + if (can_ignore) { + ereport(WARNING, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid input syntax for type tinterval: \"%s\"", i_string))); + /* ignorable syntax error. returning epoch time '1970-01-01 00:00:00' */ + *i_start = *i_end = 0; + return; + } else { + ereport(ERROR, (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid input syntax for type tinterval: \"%s\"", i_string))); + *i_start = *i_end = INVALID_ABSTIME; /* keep compiler quiet */ + } } /***************************************************************************** diff --git a/src/common/backend/utils/adt/numeric.cpp b/src/common/backend/utils/adt/numeric.cpp index 4def37f6e..ea905e8f0 100644 --- a/src/common/backend/utils/adt/numeric.cpp +++ b/src/common/backend/utils/adt/numeric.cpp @@ -272,16 +272,20 @@ Datum numeric_in(PG_FUNCTION_ARGS) /* * Check for NaN */ + int level = fcinfo->can_ignore ? WARNING : ERROR; if (pg_strncasecmp(cp, "NaN", 3) == 0) { res = make_result(&const_nan); /* Should be nothing left but spaces */ cp += 3; while (*cp) { - if (!isspace((unsigned char)*cp)) - ereport(ERROR, + if (!isspace((unsigned char)*cp)) { + ereport(level, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type numeric: \"%s\"", str))); + /* for this invalid input, if fcinfo->can_ignore == true, directly return 0 */ + PG_RETURN_NUMERIC(0); + } cp++; } } else { @@ -301,10 +305,15 @@ Datum numeric_in(PG_FUNCTION_ARGS) * together because we mustn't apply apply_typmod to a NaN. */ while (*cp) { - if (!isspace((unsigned char)*cp)) - ereport(ERROR, + if (!isspace((unsigned char)*cp)) { + ereport(level, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type numeric: \"%s\"", str))); + /* for this invalid input, if fcinfo->can_ignore == true, handle value only and + * discard rest of invalid characters + */ + break; + } cp++; } @@ -3165,7 +3174,7 @@ Datum numeric_float8(PG_FUNCTION_ARGS) tmp = DatumGetCString(DirectFunctionCall1(numeric_out_with_zero, NumericGetDatum(num))); - result = DirectFunctionCall1(float8in, CStringGetDatum(tmp)); + result = DirectFunctionCall1Coll(float8in, InvalidOid, CStringGetDatum(tmp), fcinfo->can_ignore); pfree_ext(tmp); diff --git a/src/common/backend/utils/adt/numutils.cpp b/src/common/backend/utils/adt/numutils.cpp index ea594a275..562adab71 100644 --- a/src/common/backend/utils/adt/numutils.cpp +++ b/src/common/backend/utils/adt/numutils.cpp @@ -68,10 +68,13 @@ decimalLength32(const uint32 v) * c, if not 0, is a terminator character that may appear after the * integer (plus whitespace). If 0, the string must end after the integer. * + * can_ignore, if is true, means the input s will be truncated when its value + * is invalid for integer. + * * Unlike plain atoi(), this will throw ereport() upon bad input format or * overflow. */ -int32 pg_atoi(char* s, int size, int c) +int32 pg_atoi(char* s, int size, int c, bool can_ignore) { long l; char* badp = NULL; @@ -119,22 +122,39 @@ int32 pg_atoi(char* s, int size, int c) /* won't get ERANGE on these with 64-bit longs... */ || l < INT_MIN || l > INT_MAX #endif - ) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value \"%s\" is out of range for type integer", s))); + ) { + if (!can_ignore) { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type integer", s))); + } + ereport(WARNING, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type integer. truncated automatically", s))); + l = l < INT_MIN ? INT_MIN : INT_MAX; + } break; case sizeof(int16): - if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value \"%s\" is out of range for type smallint", s))); + if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX) { + if (!can_ignore) { + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type smallint", s))); + } + ereport(WARNING, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type smallint. truncated automatically", s))); + l = l < SHRT_MIN ? SHRT_MIN : SHRT_MAX; + } break; case sizeof(uint8): - if (errno == ERANGE || l < 0 || l > UCHAR_MAX) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value \"%s\" is out of range for 8-bit integer", s))); + if (errno == ERANGE || l < 0 || l > UCHAR_MAX) { + if (!can_ignore) { + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for 8-bit integer", s))); + } + ereport(WARNING, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for 8-bit integer. truncated automatically", s))); + l = l < 0 ? 0 : UCHAR_MAX; + } break; default: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("unsupported result size: %d", size))); @@ -165,7 +185,7 @@ int32 pg_atoi(char* s, int size, int c) * representation of the most negative number, which can't be represented as a * positive number. */ -int16 pg_strtoint16(const char* s) +int16 pg_strtoint16(const char* s, bool can_ignore) { const char* ptr = s; int16 tmp = 0; @@ -217,9 +237,13 @@ int16 pg_strtoint16(const char* s) return tmp; out_of_range: - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value \"%s\" is out of range for type %s", s, "smallint"))); + if (!can_ignore) { + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type %s", s, "smallint"))); + } + ereport(WARNING, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type %s. truncated automatically", s, "smallint"))); + return neg ? PG_INT16_MIN : PG_INT16_MAX; invalid_syntax: ereport(ERROR, @@ -237,7 +261,7 @@ invalid_syntax: * representation of the most negative number, which can't be represented as a * positive number. */ -int32 pg_strtoint32(const char* s) +int32 pg_strtoint32(const char* s, bool can_ignore) { const char* ptr = s; int32 tmp = 0; @@ -289,9 +313,14 @@ int32 pg_strtoint32(const char* s) return tmp; out_of_range: - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value \"%s\" is out of range for type %s", s, "integer"))); + if (!can_ignore) { + ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type %s", s, "integer"))); + } + ereport(WARNING, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type %s. truncated automatically", s, "integer"))); + return neg ? PG_INT32_MIN : PG_INT32_MAX; + invalid_syntax: ereport(ERROR, diff --git a/src/common/backend/utils/adt/timestamp.cpp b/src/common/backend/utils/adt/timestamp.cpp index 5a65cad13..40c895064 100644 --- a/src/common/backend/utils/adt/timestamp.cpp +++ b/src/common/backend/utils/adt/timestamp.cpp @@ -252,8 +252,13 @@ Datum timestamp_in(PG_FUNCTION_ARGS) dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz); - if (dterr != 0) - DateTimeParseError(dterr, str, "timestamp"); + if (dterr != 0) { + DateTimeParseError(dterr, str, "timestamp", fcinfo->can_ignore); + /* + * if error ignorable, function DateTimeParseError reports warning instead, then return current timestamp. + */ + PG_RETURN_TIMESTAMP(GetCurrentTimestamp()); + } switch (dtype) { case DTK_DATE: @@ -456,8 +461,11 @@ Datum smalldatetime_in(PG_FUNCTION_ARGS) dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz); fsec = 0; } - if (dterr != 0) - DateTimeParseError(dterr, str, "smalldatetime"); + if (dterr != 0) { + DateTimeParseError(dterr, str, "smalldatetime", fcinfo->can_ignore); + /* if error ignorable, return epoch time as result */ + GetEpochTime(tm); + } if (tm->tm_sec >= 30) { sign = 1; } @@ -768,8 +776,13 @@ Datum timestamptz_in(PG_FUNCTION_ARGS) dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz); - if (dterr != 0) - DateTimeParseError(dterr, str, "timestamp with time zone"); + if (dterr != 0) { + DateTimeParseError(dterr, str, "timestamp with time zone", fcinfo->can_ignore); + /* + * if error ignorable, function DateTimeParseError reports warning instead, then return current timestamp. + */ + PG_RETURN_TIMESTAMP(GetCurrentTimestamp()); + } switch (dtype) { case DTK_DATE: @@ -930,7 +943,7 @@ Datum interval_in(PG_FUNCTION_ARGS) #endif int32 typmod = PG_GETARG_INT32(2); Interval *result = NULL; - result = char_to_interval(str, typmod); + result = char_to_interval(str, typmod, fcinfo->can_ignore); AdjustIntervalForTypmod(result, typmod); diff --git a/src/common/backend/utils/adt/uuid.cpp b/src/common/backend/utils/adt/uuid.cpp index e605d175a..17f6863f8 100644 --- a/src/common/backend/utils/adt/uuid.cpp +++ b/src/common/backend/utils/adt/uuid.cpp @@ -19,7 +19,7 @@ #include "utils/builtins.h" #include "utils/uuid.h" -static void string_to_uuid(const char* source, pg_uuid_t* uuid); +static void string_to_uuid(const char* source, pg_uuid_t* uuid, bool can_ignore = false); static int uuid_internal_cmp(const pg_uuid_t* arg1, const pg_uuid_t* arg2); Datum uuid_in(PG_FUNCTION_ARGS) @@ -28,7 +28,7 @@ Datum uuid_in(PG_FUNCTION_ARGS) pg_uuid_t* uuid = NULL; uuid = (pg_uuid_t*)palloc(sizeof(*uuid)); - string_to_uuid(uuid_str, uuid); + string_to_uuid(uuid_str, uuid, fcinfo->can_ignore); PG_RETURN_UUID_P(uuid); } @@ -68,7 +68,7 @@ Datum uuid_out(PG_FUNCTION_ARGS) * (The canonical format 8x-4x-4x-4x-12x, where "nx" means n hexadecimal * digits, is the only one used for output.) */ -static void string_to_uuid(const char* source, pg_uuid_t* uuid) +static void string_to_uuid(const char* source, pg_uuid_t* uuid, bool can_ignore) { const char* src = source; bool braces = false; @@ -111,6 +111,14 @@ static void string_to_uuid(const char* source, pg_uuid_t* uuid) return; syntax_error: + if (can_ignore) { + /* if invalid syntax error is ignorable, report warning and return '00000000-0000-0000-0000-000000000000' */ + ereport( + WARNING, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for uuid: \"%s\"", source))); + rc = memset_s(uuid->data, UUID_LEN, 0, UUID_LEN); + securec_check(rc, "\0", "\0"); + return; + } ereport( ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for uuid: \"%s\"", source))); } diff --git a/src/common/backend/utils/adt/varbit.cpp b/src/common/backend/utils/adt/varbit.cpp index 61ff5f412..b2f1ca17e 100644 --- a/src/common/backend/utils/adt/varbit.cpp +++ b/src/common/backend/utils/adt/varbit.cpp @@ -178,9 +178,12 @@ Datum bit_in(PG_FUNCTION_ARGS) for (; *sp; sp++) { if (*sp == '1') *r |= x; - else if (*sp != '0') - ereport(ERROR, + else if (*sp != '0') { + ereport(fcinfo->can_ignore ? WARNING : ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("\"%c\" is not a valid binary digit", *sp))); + /* if invalid input erro is ignorable, report warning and return a empty varbit */ + PG_RETURN_DATUM((Datum)DirectFunctionCall3(bit_in, CStringGetDatum(""), ObjectIdGetDatum(0), Int32GetDatum(-1))); + } x >>= 1; if (x == 0) { @@ -197,10 +200,13 @@ Datum bit_in(PG_FUNCTION_ARGS) x = (bits8)(*sp - 'A') + 10; else if (*sp >= 'a' && *sp <= 'f') x = (bits8)(*sp - 'a') + 10; - else - ereport(ERROR, + else { + ereport(fcinfo->can_ignore ? WARNING :ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("\"%c\" is not a valid hexadecimal digit", *sp))); + /* if invalid input erro is ignorable, report warning and return a empty varbit */ + PG_RETURN_DATUM((Datum)DirectFunctionCall3(bit_in, CStringGetDatum(""), ObjectIdGetDatum(0), Int32GetDatum(-1))); + } if (bc) { *r++ |= x; @@ -334,7 +340,7 @@ Datum bit(PG_FUNCTION_ARGS) if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN(arg)) PG_RETURN_VARBIT_P(arg); - if (!isExplicit) + if (!isExplicit && !fcinfo->can_ignore) ereport(ERROR, (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH), errmsg("bit string length %d does not match type bit(%d)", VARBITLEN(arg), len))); diff --git a/src/common/backend/utils/adt/xml.cpp b/src/common/backend/utils/adt/xml.cpp index 3fbfb3ab9..9d3890757 100644 --- a/src/common/backend/utils/adt/xml.cpp +++ b/src/common/backend/utils/adt/xml.cpp @@ -131,7 +131,7 @@ static char* xml_pstrdup(const char* string); static xmlChar* xml_text2xmlChar(text* in); static int parse_xml_decl(const xmlChar* str, size_t* lenp, xmlChar** version, xmlChar** encoding, int* standalone); static bool print_xml_decl(StringInfo buf, const xmlChar* version, pg_enc encoding, int standalone); -static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserve_whitespace, int encoding); +static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserve_whitespace, int encoding, bool can_ignore = false); static text* xml_xmlnodetoxmltype(xmlNodePtr cur); static int xml_xpathobjtoxmlarray(xmlXPathObjectPtr xpathobj, ArrayBuildState** astate); #endif /* USE_LIBXML */ @@ -200,7 +200,7 @@ Datum xml_in(PG_FUNCTION_ARGS) * Parse the data to check if it is well-formed XML data. Assume that * ERROR occurred if parsing failed. */ - doc = xml_parse(vardata, (XmlOptionType)xmloption, true, GetDatabaseEncoding()); + doc = xml_parse(vardata, (XmlOptionType)xmloption, true, GetDatabaseEncoding(), fcinfo->can_ignore); xmlFreeDoc(doc); PG_RETURN_XML_P(vardata); @@ -825,12 +825,9 @@ void pg_xml_init_library(void) * we can work. */ if (sizeof(char) != sizeof(xmlChar)) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("could not initialize XML library"), - errdetail("libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u.", - (int)sizeof(char), - (int)sizeof(xmlChar)))); + ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("could not initialize XML library"), + errdetail("libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u.", + (int)sizeof(char), (int)sizeof(xmlChar)))); #ifdef USE_LIBXMLCONTEXT /* Set up libxml's memory allocation our way */ @@ -1214,7 +1211,8 @@ static bool print_xml_decl(StringInfo buf, const xmlChar* version, pg_enc encodi * Maybe libxml2's xmlreader is better? (do not construct DOM, * yet do not use SAX - see xmlreader.c) */ -static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserve_whitespace, int encoding) +static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserve_whitespace, int encoding, + bool can_ignore) { int32 len; xmlChar* string = NULL; @@ -1248,13 +1246,14 @@ static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserv * external DTDs, we try to support them too, (see SQL/XML:2008 GR * 10.16.7.e) */ - doc = xmlCtxtReadDoc(ctxt, - utf8string, - NULL, - "UTF-8", - XML_PARSE_NOENT | XML_PARSE_DTDATTR | (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS)); - if (doc == NULL || xmlerrcxt->err_occurred) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT, "invalid XML document"); + doc = xmlCtxtReadDoc(ctxt, utf8string, NULL, "UTF-8", + XML_PARSE_NOENT | XML_PARSE_DTDATTR | (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS)); + if (doc == NULL || xmlerrcxt->err_occurred) { + xml_ereport(xmlerrcxt, can_ignore ? WARNING : ERROR, ERRCODE_INVALID_XML_DOCUMENT, + "invalid XML document"); + /* if invalid content value error is ignorable, report warning and return 'null' */ + goto ignorable_error_handle; + } } else { int res_code; size_t count; @@ -1262,9 +1261,16 @@ static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserv int standalone; res_code = parse_xml_decl(utf8string, &count, &version, NULL, &standalone); - if (res_code != 0) - xml_ereport_by_code( - ERROR, ERRCODE_INVALID_XML_CONTENT, "invalid XML content: invalid XML declaration", res_code); + if (res_code != 0) { + if (can_ignore) { + xml_ereport(xmlerrcxt, WARNING, ERRCODE_INVALID_XML_DOCUMENT, "invalid XML document"); + /* if invalid content value error is ignorable, report warning and return 'null' */ + goto ignorable_error_handle; + } else { + xml_ereport_by_code(ERROR, ERRCODE_INVALID_XML_CONTENT, + "invalid XML content: invalid XML declaration", res_code); + } + } doc = xmlNewDoc(version); Assert(doc->encoding == NULL); @@ -1272,8 +1278,12 @@ static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserv doc->standalone = standalone; res_code = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, utf8string + count, NULL); - if (res_code != 0 || xmlerrcxt->err_occurred) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_CONTENT, "invalid XML content"); + if (res_code != 0 || xmlerrcxt->err_occurred) { + xml_ereport(xmlerrcxt, can_ignore ? WARNING : ERROR, ERRCODE_INVALID_XML_CONTENT, + "invalid XML content"); + /* if invalid content value error is ignorable, report warning and return 'null' */ + goto ignorable_error_handle; + } } } PG_CATCH(); @@ -1294,6 +1304,17 @@ static xmlDocPtr xml_parse(text* data, XmlOptionType xmloption_arg, bool preserv pg_xml_done(xmlerrcxt, false); return doc; + +ignorable_error_handle: + text *new_data = cstring_to_text("null"); + xmlChar *new_utf8string = pg_do_encoding_conversion(xml_text2xmlChar(new_data), + VARSIZE(new_data) - VARHDRSZ, encoding, PG_UTF8); + volatile xmlDocPtr new_doc = xmlCtxtReadDoc( + ctxt, new_utf8string, NULL, "UTF-8", + XML_PARSE_NOENT | XML_PARSE_DTDATTR | (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS)); + xmlFreeParserCtxt(ctxt); + pg_xml_done(xmlerrcxt, false); + return new_doc; } /* diff --git a/src/common/backend/utils/fmgr/fmgr.cpp b/src/common/backend/utils/fmgr/fmgr.cpp index fc4e28270..902481271 100755 --- a/src/common/backend/utils/fmgr/fmgr.cpp +++ b/src/common/backend/utils/fmgr/fmgr.cpp @@ -2132,8 +2132,11 @@ void CheckNullResult(Oid oid, bool isnull, char* str) * called from other SPI functions without extra notation. This is a hack, * but the alternative of expecting all SPI functions to do SPI_push/SPI_pop * around I/O calls seems worse. + * + * With param can_ignore == true, truncation or transformation may be cast + * if function failed for ignorable errors like overflowing or out of range. */ -Datum InputFunctionCall(FmgrInfo* flinfo, char* str, Oid typioparam, int32 typmod) +Datum InputFunctionCall(FmgrInfo* flinfo, char* str, Oid typioparam, int32 typmod, bool can_ignore) { FunctionCallInfoData fcinfo; Datum result; @@ -2154,6 +2157,7 @@ Datum InputFunctionCall(FmgrInfo* flinfo, char* str, Oid typioparam, int32 typmo fcinfo.argnull[0] = (str == NULL); fcinfo.argnull[1] = false; fcinfo.argnull[2] = false; + fcinfo.can_ignore = can_ignore; result = FunctionCallInvoke(&fcinfo); @@ -2316,13 +2320,16 @@ bytea* SendFunctionCall(FmgrInfo* flinfo, Datum val) /* * As above, for I/O functions identified by OID. These are only to be used * in seldom-executed code paths. They are not only slow but leak memory. + * + * With param can_ignore == true, str may be truncated or transformed if function + * failed for ignorable errors like overflowing or out of range. */ -Datum OidInputFunctionCall(Oid functionId, char* str, Oid typioparam, int32 typmod) +Datum OidInputFunctionCall(Oid functionId, char* str, Oid typioparam, int32 typmod, bool can_ignore) { FmgrInfo flinfo; fmgr_info(functionId, &flinfo); - return InputFunctionCall(&flinfo, str, typioparam, typmod); + return InputFunctionCall(&flinfo, str, typioparam, typmod, can_ignore); } char* OidOutputFunctionCall(Oid functionId, Datum val) diff --git a/src/gausskernel/runtime/executor/execUtils.cpp b/src/gausskernel/runtime/executor/execUtils.cpp index 82c2dfd24..5d9f950ac 100644 --- a/src/gausskernel/runtime/executor/execUtils.cpp +++ b/src/gausskernel/runtime/executor/execUtils.cpp @@ -2577,7 +2577,7 @@ Datum GetTypeZeroValue(Form_pg_attribute att_tup) } case SMALLDATETIMEOID: { result = (Datum)DirectFunctionCall3( - smalldatetime_in, CStringGetDatum("1970-01-01 08:00:00"), ObjectIdGetDatum(0), Int32GetDatum(-1)); + smalldatetime_in, CStringGetDatum("1970-01-01 00:00:00"), ObjectIdGetDatum(0), Int32GetDatum(-1)); break; } case DATEOID: { @@ -2623,8 +2623,7 @@ Datum GetTypeZeroValue(Form_pg_attribute att_tup) break; } case XMLOID: { - result = (Datum)DirectFunctionCall1(xml_in, CStringGetDatum("")); - (Datum)DirectFunctionCall1(numeric_in, CStringGetDatum("0")); + result = (Datum)DirectFunctionCall1(xml_in, CStringGetDatum("null")); break; } case BITOID: { diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 0204976cb..0cb497254 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -564,10 +564,10 @@ typedef struct { } CFunInfo; /* Special cases for convenient invocation of datatype I/O functions. */ -extern Datum InputFunctionCall(FmgrInfo* flinfo, char* str, Oid typioparam, int32 typmod); +extern Datum InputFunctionCall(FmgrInfo* flinfo, char* str, Oid typioparam, int32 typmod, bool can_ignore = false); extern Datum InputFunctionCallForDateType( FmgrInfo* flinfo, char* str, Oid typioparam, int32 typmod, char* date_time_fmt); -extern Datum OidInputFunctionCall(Oid functionId, char* str, Oid typioparam, int32 typmod); +extern Datum OidInputFunctionCall(Oid functionId, char* str, Oid typioparam, int32 typmod, bool can_ignore = false); extern char* OutputFunctionCall(FmgrInfo* flinfo, Datum val); extern char* OidOutputFunctionCall(Oid functionId, Datum val); extern Datum ReceiveFunctionCall(FmgrInfo* flinfo, fmStringInfo buf, Oid typioparam, int32 typmod); diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h index 44667e845..8314c156b 100644 --- a/src/include/parser/parse_type.h +++ b/src/include/parser/parse_type.h @@ -42,7 +42,7 @@ extern bool typeByVal(Type t); extern char* typeTypeName(Type t); extern Oid typeTypeRelid(Type typ); extern Oid typeTypeCollation(Type typ); -extern Datum stringTypeDatum(Type tp, char* string, int32 atttypmod); +extern Datum stringTypeDatum(Type tp, char* string, int32 atttypmod, bool can_ignore = false); extern Oid typeidTypeRelid(Oid type_id); extern bool IsTypeSupportedByCStore(_in_ Oid typeOid); diff --git a/src/include/replication/archive_walreceiver.h b/src/include/replication/archive_walreceiver.h index 39cc8bde9..3de066f76 100644 --- a/src/include/replication/archive_walreceiver.h +++ b/src/include/replication/archive_walreceiver.h @@ -32,8 +32,8 @@ #include "replication/slot.h" -extern int32 pg_atoi(char* s, int size, int c); -extern int32 pg_strtoint32(const char* s); +extern int32 pg_atoi(char* s, int size, int c, bool can_ignore); +extern int32 pg_strtoint32(const char* s, bool can_ignore); /* Prototypes for interface functions */ extern bool archive_connect(char* conninfo, XLogRecPtr* startpoint, char* slotname, int channel_identifier); diff --git a/src/include/replication/libpqwalreceiver.h b/src/include/replication/libpqwalreceiver.h index ebe25688b..df30bd6f1 100755 --- a/src/include/replication/libpqwalreceiver.h +++ b/src/include/replication/libpqwalreceiver.h @@ -67,8 +67,8 @@ typedef struct WalRcvExecResult { TupleDesc tupledesc; } WalRcvExecResult; -extern int32 pg_atoi(char* s, int size, int c); -extern int32 pg_strtoint32(const char* s); +extern int32 pg_atoi(char* s, int size, int c, bool can_ignore = false); +extern int32 pg_strtoint32(const char* s, bool can_ignore = false); /* Prototypes for interface functions */ extern bool libpqrcv_connect_for_TLI(TimeLineID* timeLineID, char* conninfo); extern bool libpqrcv_connect(char* conninfo, XLogRecPtr* startpoint, char* slotname, int channel_identifier); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 528f4fa69..add1a6f3e 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -482,9 +482,9 @@ extern Datum pseudo_current_user(PG_FUNCTION_ARGS); extern uint64 pg_strtouint64(const char* str, char** endptr, int base); /* numutils.c */ -extern int32 pg_atoi(char* s, int size, int c); -extern int16 pg_strtoint16(const char* s); -extern int32 pg_strtoint32(const char* s); +extern int32 pg_atoi(char* s, int size, int c, bool can_ignore); +extern int16 pg_strtoint16(const char* s, bool can_ignore = false); +extern int32 pg_strtoint32(const char* s, bool can_ignore); extern void pg_itoa(int16 i, char* a); extern void pg_ltoa(int32 l, char* a); extern void pg_ctoa(uint8 i, char* a); diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h index 5b6936f20..642c3be76 100644 --- a/src/include/utils/datetime.h +++ b/src/include/utils/datetime.h @@ -278,7 +278,7 @@ extern int DecodeInterval( char** field, const int* ftype, int nf, int range, int* dtype, struct pg_tm* tm, fsec_t* fsec); extern int DecodeISO8601Interval(char* str, int* dtype, struct pg_tm* tm, fsec_t* fsec); -extern void DateTimeParseError(int dterr, const char* str, const char* datatype); +extern void DateTimeParseError(int dterr, const char* str, const char* datatype, bool can_ignore = false); extern int DetermineTimeZoneOffset(struct pg_tm* tm, pg_tz* tzp); @@ -302,7 +302,7 @@ extern void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable* tbl); extern Datum pg_timezone_abbrevs(PG_FUNCTION_ARGS); extern Datum pg_timezone_names(PG_FUNCTION_ARGS); -extern Interval *char_to_interval(char *str, int32 typmod); +extern Interval *char_to_interval(char *str, int32 typmod, bool can_ignore = false); #endif // !FRONTEND_PARSER #endif /* DATETIME_H */ diff --git a/src/include/utils/int8.h b/src/include/utils/int8.h index 1efcb9966..18435d61b 100644 --- a/src/include/utils/int8.h +++ b/src/include/utils/int8.h @@ -22,7 +22,7 @@ #include "fmgr.h" -extern bool scanint8(const char* str, bool errorOK, int64* result); +extern bool scanint8(const char* str, bool errorOK, int64* result, bool can_ignore = false); extern Datum int8in(PG_FUNCTION_ARGS); extern Datum int8out(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/ignore/ignore_invalid_input.out b/src/test/regress/expected/ignore/ignore_invalid_input.out new file mode 100644 index 000000000..80807ccf4 --- /dev/null +++ b/src/test/regress/expected/ignore/ignore_invalid_input.out @@ -0,0 +1,790 @@ +-- test for insert/update ignore. +create database sql_ignore_invalid_input_test dbcompatibility 'B'; +\c sql_ignore_invalid_input_test; +set timezone to 'PRC'; +-- type: tinyint +create table t_tinyint(c tinyint); +insert /*+ ignore_error */ into t_tinyint values('12a34'); +insert /*+ ignore_error */ into t_tinyint values('12555a34'); +WARNING: value "12555a34" is out of range for 8-bit integer. truncated automatically +LINE 1: insert /*+ ignore_error */ into t_tinyint values('12555a34')... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_tinyint values('-12555a34'); +WARNING: value "-12555a34" is out of range for 8-bit integer. truncated automatically +LINE 1: insert /*+ ignore_error */ into t_tinyint values('-12555a34'... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_tinyint values('aaa123a34'); +insert /*+ ignore_error */ into t_tinyint values('abcde'); +select * from t_tinyint; + c +----- + 12 + 255 + 0 + 0 + 0 +(5 rows) + +update /*+ ignore_error */ t_tinyint set c = '12a34'; +-- type: smallint +create table t_smallint(c smallint); +insert /*+ ignore_error */ into t_smallint values ('12a34'); +insert /*+ ignore_error */ into t_smallint values ('123333333333333a34'); +WARNING: value "123333333333333a34" is out of range for type smallint. truncated automatically +LINE 1: ...nsert /*+ ignore_error */ into t_smallint values ('123333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_smallint values ('-123333333333333a34'); +WARNING: value "-123333333333333a34" is out of range for type smallint. truncated automatically +LINE 1: ...nsert /*+ ignore_error */ into t_smallint values ('-12333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_smallint values ('aaa1234a5'); +insert /*+ ignore_error */ into t_smallint values ('abcde'); +select * from t_smallint; + c +-------- + 12 + 32767 + -32768 + 0 + 0 +(5 rows) + +update /*+ ignore_error */ t_smallint set c = '12a34'; +-- type: int4 +create table t_int(c int); +insert /*+ ignore_error */ into t_int values ('12a34'); +insert /*+ ignore_error */ into t_int values ('123333333333333333333333333a34'); +WARNING: value "123333333333333333333333333a34" is out of range for type integer. truncated automatically +LINE 1: insert /*+ ignore_error */ into t_int values ('1233333333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_int values ('-123333333333333333333333333a34'); +WARNING: value "-123333333333333333333333333a34" is out of range for type integer. truncated automatically +LINE 1: insert /*+ ignore_error */ into t_int values ('-123333333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_int values ('aaa123a45'); +insert /*+ ignore_error */ into t_int values ('abcde'); +select * from t_int; + c +------------- + 12 + 2147483647 + -2147483648 + 0 + 0 +(5 rows) + +update /*+ ignore_error */ t_int set c = '12a34'; +-- type: bigint +create table t_bigint(c bigint); +insert /*+ ignore_error */ into t_bigint values ('12a34'); +insert /*+ ignore_error */ into t_bigint values ('123333333333333333333333333333333333333333333333333333333333333333333333333333333333333a34'); +WARNING: value "123333333333333333333333333333333333333333333333333333333333333333333333333333333333333a34" is out of range for type bigint. truncated automatically +LINE 1: insert /*+ ignore_error */ into t_bigint values ('1233333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_bigint values ('-123333333333333333333333333333333333333333333333333333333333333333333333333333333333333a34'); +WARNING: value "-123333333333333333333333333333333333333333333333333333333333333333333333333333333333333a34" is out of range for type bigint. truncated automatically +LINE 1: insert /*+ ignore_error */ into t_bigint values ('-123333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_bigint values ('aaa123a45'); +insert /*+ ignore_error */ into t_bigint values ('abcde'); +select * from t_bigint; + c +---------------------- + 12 + 9223372036854775807 + -9223372036854775808 + 0 + 0 +(5 rows) + +update /*+ ignore_error */ t_bigint set c = '12a34'; +-- type: float4 +create table t_float4(c float4); +insert /*+ ignore_error */ into t_float4 values ('12.123a34'); +WARNING: invalid input syntax for type real: "12.123a34". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float4 values ('12.123a34'... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float4 values ('123333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.123a34'); +WARNING: value out of range: overflow +LINE 1: insert /*+ ignore_error */ into t_float4 values ('1233333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float4 values ('-123333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.123a34'); +WARNING: value out of range: overflow +LINE 1: insert /*+ ignore_error */ into t_float4 values ('-123333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float4 values ('aaa123.12a45'); +WARNING: invalid input syntax for type real: "aaa123.12a45". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float4 values ('aaa123.12a... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float4 values ('abcde'); +WARNING: invalid input syntax for type real: "abcde". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float4 values ('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_float4; + c +-------------- + 12.123 + 3.40282e+38 + -3.40282e+38 + 0 + 0 +(5 rows) + +update /*+ ignore_error */ t_float4 set c = '12a34'; +WARNING: invalid input syntax for type real: "12a34". truncated automatically +LINE 1: update /*+ ignore_error */ t_float4 set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: float8 +create table t_float8(c float8); +insert /*+ ignore_error */ into t_float8 values ('12.123a34'); +WARNING: invalid input syntax for type double precision: "12.123a34". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float8 values ('12.123a34'... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float8 values ('3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +WARNING: "3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34" is out of range for type double precision +LINE 1: insert /*+ ignore_error */ into t_float8 values ('3333333331... + ^ +CONTEXT: referenced column: c +WARNING: invalid input syntax for type double precision: "3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float8 values ('3333333331... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float8 values ('-3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +WARNING: "-3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34" is out of range for type double precision +LINE 1: insert /*+ ignore_error */ into t_float8 values ('-333333333... + ^ +CONTEXT: referenced column: c +WARNING: invalid input syntax for type double precision: "-3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float8 values ('-333333333... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float8 values ('aaa123.12a45'); +WARNING: invalid input syntax for type double precision: "aaa123.12a45". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float8 values ('aaa123.12a... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_float8 values ('abcde'); +WARNING: invalid input syntax for type double precision: "abcde". truncated automatically +LINE 1: insert /*+ ignore_error */ into t_float8 values ('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_float8; + c +----------------------- + 12.123 + 1.79769313486232e+308 + 2.2250738585072e-308 + 0 + 0 +(5 rows) + +update /*+ ignore_error */ t_float8 set c = '12a34'; +WARNING: invalid input syntax for type double precision: "12a34". truncated automatically +LINE 1: update /*+ ignore_error */ t_float8 set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: numeric +create table t_numeric(c numeric); +insert /*+ ignore_error */ into t_numeric values ('12.123a34'); +WARNING: invalid input syntax for type numeric: "12.123a34" +LINE 1: insert /*+ ignore_error */ into t_numeric values ('12.123a34... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_numeric values ('333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +WARNING: invalid input syntax for type numeric: "333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34" +LINE 1: insert /*+ ignore_error */ into t_numeric values ('333331892... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_numeric values ('-333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +WARNING: invalid input syntax for type numeric: "-333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34" +LINE 1: insert /*+ ignore_error */ into t_numeric values ('-33333189... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_numeric values ('aaa123.12a45'); +insert /*+ ignore_error */ into t_numeric values ('abcde'); +select * from t_numeric; + c +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + 12.123 + 333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984 + -333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984 + 0 + 0 +(5 rows) + +update /*+ ignore_error */ t_numeric set c = '12a34'; +WARNING: invalid input syntax for type numeric: "12a34" +LINE 1: update /*+ ignore_error */ t_numeric set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: date +create table t_date(c date); +insert /*+ ignore_error */ into t_date values('12a34'); +WARNING: invalid input syntax for type date: "12a34" +LINE 1: insert /*+ ignore_error */ into t_date values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_date values('123a34'); +WARNING: invalid input syntax for type date: "123a34" +LINE 1: insert /*+ ignore_error */ into t_date values('123a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_date values('12aaaaaaa34'); +WARNING: invalid input syntax for type date: "12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_date values('12aaaaaaa34')... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_date values('aaaaaaa12aaaaaaa34'); +WARNING: invalid input syntax for type date: "aaaaaaa12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_date values('aaaaaaa12aaaa... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_date values('abcde'); +WARNING: invalid input syntax for type date: "abcde" +LINE 1: insert /*+ ignore_error */ into t_date values('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_date; + c +------------ + 01-01-1970 + 01-01-1970 + 01-01-1970 + 01-01-1970 + 01-01-1970 +(5 rows) + +update /*+ ignore_error */ t_date set c = '12a34'; +WARNING: invalid input syntax for type date: "12a34" +LINE 1: update /*+ ignore_error */ t_date set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: time +create table t_time(c time); +insert /*+ ignore_error */ into t_time values('12a34'); +WARNING: invalid input syntax for type time: "12a34" +LINE 1: insert /*+ ignore_error */ into t_time values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_time values('123a34'); +WARNING: invalid input syntax for type time: "123a34" +LINE 1: insert /*+ ignore_error */ into t_time values('123a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_time values('12aaaaaaa34'); +WARNING: invalid input syntax for type time: "12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_time values('12aaaaaaa34')... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_time values('aaaaaaa12aaaaaaa34'); +WARNING: invalid input syntax for type time: "aaaaaaa12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_time values('aaaaaaa12aaaa... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_time values('abcde'); +WARNING: invalid input syntax for type time: "abcde" +LINE 1: insert /*+ ignore_error */ into t_time values('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_time; + c +---------- + 00:00:12 + 00:00:00 + 00:00:12 + 00:00:00 + 00:00:00 +(5 rows) + +update /*+ ignore_error */ t_time set c = '12a34'; +WARNING: invalid input syntax for type time: "12a34" +LINE 1: update /*+ ignore_error */ t_time set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: timestamp +create table t_timestamp(c timestamp); +insert /*+ ignore_error */ into t_timestamp values('12a34'); +WARNING: invalid input syntax for type timestamp: "12a34" +LINE 1: ...nsert /*+ ignore_error */ into t_timestamp values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timestamp values('abcde'); +WARNING: invalid input syntax for type timestamp: "abcde" +LINE 1: ...nsert /*+ ignore_error */ into t_timestamp values('abcde'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timestamp values('aaaaaa12a34'); +WARNING: invalid input syntax for type timestamp: "aaaaaa12a34" +LINE 1: ...sert /*+ ignore_error */ into t_timestamp values('aaaaaa12a... + ^ +CONTEXT: referenced column: c +select * from t_timestamp; + c +--------------------------------- +--?.* +--?.* +--?.* +(3 rows) + +update /*+ ignore_error */ t_timestamp set c = '12a34'; +WARNING: invalid input syntax for type timestamp: "12a34" +LINE 1: update /*+ ignore_error */ t_timestamp set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: timestamptz +create table t_timestamptz(c timestamptz); +insert /*+ ignore_error */ into t_timestamptz values('12a34'); +WARNING: invalid input syntax for type timestamp with time zone: "12a34" +LINE 1: ...ert /*+ ignore_error */ into t_timestamptz values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timestamptz values('abcde'); +WARNING: invalid input syntax for type timestamp with time zone: "abcde" +LINE 1: ...ert /*+ ignore_error */ into t_timestamptz values('abcde'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timestamptz values('aaaaaa12a34'); +WARNING: invalid input syntax for type timestamp with time zone: "aaaaaa12a34" +LINE 1: ...rt /*+ ignore_error */ into t_timestamptz values('aaaaaa12a... + ^ +CONTEXT: referenced column: c +select * from t_timestamptz; + c +------------------------------------- +--?.* +--?.* +--?.* +(3 rows) + +update /*+ ignore_error */ t_timestamptz set c = '12a34'; +WARNING: invalid input syntax for type timestamp with time zone: "12a34" +LINE 1: update /*+ ignore_error */ t_timestamptz set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: timetz +create table t_timetz(c timetz); +insert /*+ ignore_error */ into t_timetz values('12a34'); +WARNING: invalid input syntax for type time with time zone: "12a34" +LINE 1: insert /*+ ignore_error */ into t_timetz values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timetz values('123a34'); +WARNING: invalid input syntax for type time with time zone: "123a34" +LINE 1: insert /*+ ignore_error */ into t_timetz values('123a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timetz values('12aaaaaaa34'); +WARNING: invalid input syntax for type time with time zone: "12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_timetz values('12aaaaaaa34... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timetz values('aaaaaaa12aaaaaaa34'); +WARNING: invalid input syntax for type time with time zone: "aaaaaaa12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_timetz values('aaaaaaa12aa... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_timetz values('abcde'); +WARNING: invalid input syntax for type time with time zone: "abcde" +LINE 1: insert /*+ ignore_error */ into t_timetz values('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_timetz; + c +------------- + 00:00:12+00 + 00:00:00+00 + 00:00:12+00 + 00:00:00+00 + 00:00:00+00 +(5 rows) + +update /*+ ignore_error */ t_timetz set c = '12a34'; +WARNING: invalid input syntax for type time with time zone: "12a34" +LINE 1: update /*+ ignore_error */ t_timetz set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: interval +create table t_interval(c interval); +insert /*+ ignore_error */ into t_interval values('12a34'); +WARNING: invalid input syntax for type interval: "12a34" +LINE 1: insert /*+ ignore_error */ into t_interval values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_interval values('123a34'); +WARNING: invalid input syntax for type interval: "123a34" +LINE 1: insert /*+ ignore_error */ into t_interval values('123a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_interval values('12aaaaaaa34'); +WARNING: invalid input syntax for type interval: "12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_interval values('12aaaaaaa... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_interval values('aaaaaaa12aaaaaaa34'); +WARNING: invalid input syntax for type interval: "aaaaaaa12aaaaaaa34" +LINE 1: insert /*+ ignore_error */ into t_interval values('aaaaaaa12... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_interval values('abcde'); +WARNING: invalid input syntax for type interval: "abcde" +LINE 1: insert /*+ ignore_error */ into t_interval values('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_interval; + c +----- + @ 0 + @ 0 + @ 0 + @ 0 + @ 0 +(5 rows) + +update /*+ ignore_error */ t_interval set c = '12a34'; +WARNING: invalid input syntax for type interval: "12a34" +LINE 1: update /*+ ignore_error */ t_interval set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: tinterval +create table t_tinterval(c tinterval); +insert /*+ ignore_error */ into t_tinterval values('12a34'); +WARNING: invalid input syntax for type tinterval: "12a34" +LINE 1: insert /*+ ignore_error */ into t_tinterval values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_tinterval values('123a34'); +WARNING: invalid input syntax for type tinterval: "123a34" +LINE 1: ...nsert /*+ ignore_error */ into t_tinterval values('123a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_tinterval values('12aaaaaaa34'); +WARNING: invalid input syntax for type tinterval: "12aaaaaaa34" +LINE 1: ...nsert /*+ ignore_error */ into t_tinterval values('12aaaaaaa... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_tinterval values('aaaaaaa12aaaaaaa34'); +WARNING: invalid input syntax for type tinterval: "aaaaaaa12aaaaaaa34" +LINE 1: ...nsert /*+ ignore_error */ into t_tinterval values('aaaaaaa12... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_tinterval values('abcde'); +WARNING: invalid input syntax for type tinterval: "abcde" +LINE 1: insert /*+ ignore_error */ into t_tinterval values('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_tinterval; + c +----------------------------------------------------------------- + ["Thu Jan 01 08:00:00 1970 CST" "Thu Jan 01 08:00:00 1970 CST"] + ["Thu Jan 01 08:00:00 1970 CST" "Thu Jan 01 08:00:00 1970 CST"] + ["Thu Jan 01 08:00:00 1970 CST" "Thu Jan 01 08:00:00 1970 CST"] + ["Thu Jan 01 08:00:00 1970 CST" "Thu Jan 01 08:00:00 1970 CST"] + ["Thu Jan 01 08:00:00 1970 CST" "Thu Jan 01 08:00:00 1970 CST"] +(5 rows) + +update /*+ ignore_error */ t_tinterval set c = '12a34'; +WARNING: invalid input syntax for type tinterval: "12a34" +LINE 1: update /*+ ignore_error */ t_tinterval set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: smalldatetime +create table t_smalldatetime(c smalldatetime); +insert /*+ ignore_error */ into t_smalldatetime values('12a34'); +WARNING: invalid input syntax for type smalldatetime: "12a34" +LINE 1: ...rt /*+ ignore_error */ into t_smalldatetime values('12a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_smalldatetime values('123a34'); +WARNING: invalid input syntax for type smalldatetime: "123a34" +LINE 1: ...t /*+ ignore_error */ into t_smalldatetime values('123a34'); + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_smalldatetime values('12aaaaaaa34'); +WARNING: invalid input syntax for type smalldatetime: "12aaaaaaa34" +LINE 1: ...t /*+ ignore_error */ into t_smalldatetime values('12aaaaaaa... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_smalldatetime values('aaaaaaa12aaaaaaa34'); +WARNING: invalid input syntax for type smalldatetime: "aaaaaaa12aaaaaaa34" +LINE 1: ...t /*+ ignore_error */ into t_smalldatetime values('aaaaaaa12... + ^ +CONTEXT: referenced column: c +insert /*+ ignore_error */ into t_smalldatetime values('abcde'); +WARNING: invalid input syntax for type smalldatetime: "abcde" +LINE 1: ...rt /*+ ignore_error */ into t_smalldatetime values('abcde'); + ^ +CONTEXT: referenced column: c +select * from t_smalldatetime; + c +-------------------------- + Thu Jan 01 00:00:00 1970 + Thu Jan 01 00:00:00 1970 + Thu Jan 01 00:00:00 1970 + Thu Jan 01 00:00:00 1970 + Thu Jan 01 00:00:00 1970 +(5 rows) + +update /*+ ignore_error */ t_smalldatetime set c = '12a34'; +WARNING: invalid input syntax for type smalldatetime: "12a34" +LINE 1: update /*+ ignore_error */ t_smalldatetime set c = '12a34'; + ^ +CONTEXT: referenced column: c +-- type: uuid +create table t_uuid(c uuid); +insert /*+ ignore_error */ into t_uuid values('12a34'); +WARNING: invalid input syntax for uuid: "12a34" +LINE 1: insert /*+ ignore_error */ into t_uuid values('12a34'); + ^ +CONTEXT: referenced column: c +update /*+ ignore_error */ t_uuid set c = '12a34'; +WARNING: invalid input syntax for uuid: "12a34" +LINE 1: update /*+ ignore_error */ t_uuid set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_uuid; + c +-------------------------------------- + 00000000-0000-0000-0000-000000000000 +(1 row) + +-- type: point +create table t_point(c point); +insert /*+ ignore_error */ into t_point values('12a34'); +WARNING: invalid input syntax for type point: "12a34" +LINE 1: insert /*+ ignore_error */ into t_point values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_point; + c +------- + (0,0) +(1 row) + +update /*+ ignore_error */ t_point set c = '12a34'; +WARNING: invalid input syntax for type point: "12a34" +LINE 1: update /*+ ignore_error */ t_point set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_point; + c +------- + (0,0) +(1 row) + +-- type: path +create table t_path(c path); +insert /*+ ignore_error */ into t_path values('12a34'); +WARNING: invalid input syntax for type path: "12a34" +LINE 1: insert /*+ ignore_error */ into t_path values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_path; + c +--------- + ((0,0)) +(1 row) + +update /*+ ignore_error */ t_path set c = '12a34'; +WARNING: invalid input syntax for type path: "12a34" +LINE 1: update /*+ ignore_error */ t_path set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_path; + c +--------- + ((0,0)) +(1 row) + +-- type: polygon +create table t_polygon(c polygon); +insert /*+ ignore_error */ into t_polygon values('12a34'); +WARNING: invalid input syntax for type polygon: "12a34" +LINE 1: insert /*+ ignore_error */ into t_polygon values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_polygon; + c +--------- + ((0,0)) +(1 row) + +update /*+ ignore_error */ t_polygon set c = '12a34'; +WARNING: invalid input syntax for type polygon: "12a34" +LINE 1: update /*+ ignore_error */ t_polygon set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_polygon; + c +--------- + ((0,0)) +(1 row) + +-- type: circle +create table t_circle(c circle); +insert /*+ ignore_error */ into t_circle values('12a34'); +WARNING: invalid input syntax for type circle: "12a34" +LINE 1: insert /*+ ignore_error */ into t_circle values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_circle; + c +----------- + <(0,0),0> +(1 row) + +update /*+ ignore_error */ t_circle set c = '12a34'; +WARNING: invalid input syntax for type circle: "12a34" +LINE 1: update /*+ ignore_error */ t_circle set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_circle; + c +----------- + <(0,0),0> +(1 row) + +-- type: lseg +create table t_lseg(c lseg); +insert /*+ ignore_error */ into t_lseg values('12a34'); +WARNING: invalid input syntax for type lseg: "12a34" +LINE 1: insert /*+ ignore_error */ into t_lseg values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_lseg; + c +--------------- + [(0,0),(0,0)] +(1 row) + +update /*+ ignore_error */ t_lseg set c = '12a34'; +WARNING: invalid input syntax for type lseg: "12a34" +LINE 1: update /*+ ignore_error */ t_lseg set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_lseg; + c +--------------- + [(0,0),(0,0)] +(1 row) + +-- type: box +create table t_box(c box); +insert /*+ ignore_error */ into t_box values('12a34'); +WARNING: invalid input syntax for type box: "12a34" +LINE 1: insert /*+ ignore_error */ into t_box values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_box; + c +------------- + (0,0),(0,0) +(1 row) + +update /*+ ignore_error */ t_box set c = '12a34'; +WARNING: invalid input syntax for type box: "12a34" +LINE 1: update /*+ ignore_error */ t_box set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_box; + c +------------- + (0,0),(0,0) +(1 row) + +-- type: json +create table t_json(c json); +insert /*+ ignore_error */ into t_json values('12a34'); +WARNING: invalid input syntax for type json +LINE 1: insert /*+ ignore_error */ into t_json values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_json; + c +------ + null +(1 row) + +update /*+ ignore_error */ t_json set c = '12a34'; +WARNING: invalid input syntax for type json +LINE 1: update /*+ ignore_error */ t_json set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_json; + c +------ + null +(1 row) + +-- type: jsonb +create table t_jsonb(c jsonb); +insert /*+ ignore_error */ into t_jsonb values('12a34'); +WARNING: invalid input syntax for type json +LINE 1: insert /*+ ignore_error */ into t_jsonb values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_jsonb; + c +------ + null +(1 row) + +update /*+ ignore_error */ t_jsonb set c = '12a34'; +WARNING: invalid input syntax for type json +LINE 1: update /*+ ignore_error */ t_jsonb set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_jsonb; + c +------ + null +(1 row) + +-- type: bit +create table t_bit(c bit); +insert /*+ ignore_error */ into t_bit values('12a34'); +WARNING: "2" is not a valid binary digit +LINE 1: insert /*+ ignore_error */ into t_bit values('12a34'); + ^ +CONTEXT: referenced column: c +select * from t_bit; + c +--- + 0 +(1 row) + +update /*+ ignore_error */ t_bit set c = '12a34'; +WARNING: "2" is not a valid binary digit +LINE 1: update /*+ ignore_error */ t_bit set c = '12a34'; + ^ +CONTEXT: referenced column: c +select * from t_bit; + c +--- + 0 +(1 row) + +-- restore context +reset timezone; +show timezone; + TimeZone +---------- + PST8PDT +(1 row) + +\c postgres +drop database if exists sql_ignore_invalid_input_test; diff --git a/src/test/regress/expected/ignore/ignore_not_null_constraints.out b/src/test/regress/expected/ignore/ignore_not_null_constraints.out index dffc57c3f..5888ac8ed 100644 --- a/src/test/regress/expected/ignore/ignore_not_null_constraints.out +++ b/src/test/regress/expected/ignore/ignore_not_null_constraints.out @@ -377,7 +377,7 @@ DETAIL: Failing row contains (null). select * from t_smalldatetime; c -------------------------- - Thu Jan 01 08:00:00 1970 + Thu Jan 01 00:00:00 1970 (1 row) insert into t_smalldatetime values('1991-01-01 08:00:00'); @@ -389,8 +389,8 @@ DETAIL: Failing row contains (null). select * from t_smalldatetime; c -------------------------- - Thu Jan 01 08:00:00 1970 - Thu Jan 01 08:00:00 1970 + Thu Jan 01 00:00:00 1970 + Thu Jan 01 00:00:00 1970 (2 rows) -- date diff --git a/src/test/regress/parallel_schedule0 b/src/test/regress/parallel_schedule0 index 268c853ba..2b348de77 100644 --- a/src/test/regress/parallel_schedule0 +++ b/src/test/regress/parallel_schedule0 @@ -989,7 +989,7 @@ test: gs_dump_encrypt substr test: composite_datum_record mysql_function b_comments mysql_syntax mysql_delimiter test: join_test_alias alter_ctable_compress -test: ignore/ignore_type_transform ignore/ignore_not_null_constraints ignore/ignore_unique_constraints ignore/ignore_no_matched_partition +test: ignore/ignore_type_transform ignore/ignore_not_null_constraints ignore/ignore_unique_constraints ignore/ignore_no_matched_partition ignore/ignore_invalid_input test: pg_ls_dir test: cost_model diff --git a/src/test/regress/sql/ignore/ignore_invalid_input.sql b/src/test/regress/sql/ignore/ignore_invalid_input.sql new file mode 100644 index 000000000..4abfa7660 --- /dev/null +++ b/src/test/regress/sql/ignore/ignore_invalid_input.sql @@ -0,0 +1,225 @@ +-- test for insert/update ignore. +create database sql_ignore_invalid_input_test dbcompatibility 'B'; +\c sql_ignore_invalid_input_test; +set timezone to 'PRC'; + +-- type: tinyint +create table t_tinyint(c tinyint); +insert /*+ ignore_error */ into t_tinyint values('12a34'); +insert /*+ ignore_error */ into t_tinyint values('12555a34'); +insert /*+ ignore_error */ into t_tinyint values('-12555a34'); +insert /*+ ignore_error */ into t_tinyint values('aaa123a34'); +insert /*+ ignore_error */ into t_tinyint values('abcde'); +select * from t_tinyint; +update /*+ ignore_error */ t_tinyint set c = '12a34'; + +-- type: smallint +create table t_smallint(c smallint); +insert /*+ ignore_error */ into t_smallint values ('12a34'); +insert /*+ ignore_error */ into t_smallint values ('123333333333333a34'); +insert /*+ ignore_error */ into t_smallint values ('-123333333333333a34'); +insert /*+ ignore_error */ into t_smallint values ('aaa1234a5'); +insert /*+ ignore_error */ into t_smallint values ('abcde'); +select * from t_smallint; +update /*+ ignore_error */ t_smallint set c = '12a34'; + +-- type: int4 +create table t_int(c int); +insert /*+ ignore_error */ into t_int values ('12a34'); +insert /*+ ignore_error */ into t_int values ('123333333333333333333333333a34'); +insert /*+ ignore_error */ into t_int values ('-123333333333333333333333333a34'); +insert /*+ ignore_error */ into t_int values ('aaa123a45'); +insert /*+ ignore_error */ into t_int values ('abcde'); +select * from t_int; +update /*+ ignore_error */ t_int set c = '12a34'; + +-- type: bigint +create table t_bigint(c bigint); +insert /*+ ignore_error */ into t_bigint values ('12a34'); +insert /*+ ignore_error */ into t_bigint values ('123333333333333333333333333333333333333333333333333333333333333333333333333333333333333a34'); +insert /*+ ignore_error */ into t_bigint values ('-123333333333333333333333333333333333333333333333333333333333333333333333333333333333333a34'); +insert /*+ ignore_error */ into t_bigint values ('aaa123a45'); +insert /*+ ignore_error */ into t_bigint values ('abcde'); +select * from t_bigint; +update /*+ ignore_error */ t_bigint set c = '12a34'; + +-- type: float4 +create table t_float4(c float4); +insert /*+ ignore_error */ into t_float4 values ('12.123a34'); +insert /*+ ignore_error */ into t_float4 values ('123333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.123a34'); +insert /*+ ignore_error */ into t_float4 values ('-123333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333.123a34'); +insert /*+ ignore_error */ into t_float4 values ('aaa123.12a45'); +insert /*+ ignore_error */ into t_float4 values ('abcde'); +select * from t_float4; +update /*+ ignore_error */ t_float4 set c = '12a34'; + +-- type: float8 +create table t_float8(c float8); +insert /*+ ignore_error */ into t_float8 values ('12.123a34'); +insert /*+ ignore_error */ into t_float8 values ('3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +insert /*+ ignore_error */ into t_float8 values ('-3333333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +insert /*+ ignore_error */ into t_float8 values ('aaa123.12a45'); +insert /*+ ignore_error */ into t_float8 values ('abcde'); +select * from t_float8; +update /*+ ignore_error */ t_float8 set c = '12a34'; + +-- type: numeric +create table t_numeric(c numeric); +insert /*+ ignore_error */ into t_numeric values ('12.123a34'); +insert /*+ ignore_error */ into t_numeric values ('333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +insert /*+ ignore_error */ into t_numeric values ('-333331892038097432987589432759843769348605436304758493758943758943758943759843756983760945860948605948765487689547893475893475918920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759627346378267863475863875648365843734895749837589437589473988.18920380974329875894327598437693486054363047584937589437589437589437598437569837609458609486059487654876895478934758934759189203809743298758943275984376934860543630475849375894375894375894375984375698376094586094860594876548768954789347589347593874894375984aaa34'); +insert /*+ ignore_error */ into t_numeric values ('aaa123.12a45'); +insert /*+ ignore_error */ into t_numeric values ('abcde'); +select * from t_numeric; +update /*+ ignore_error */ t_numeric set c = '12a34'; + +-- type: date +create table t_date(c date); +insert /*+ ignore_error */ into t_date values('12a34'); +insert /*+ ignore_error */ into t_date values('123a34'); +insert /*+ ignore_error */ into t_date values('12aaaaaaa34'); +insert /*+ ignore_error */ into t_date values('aaaaaaa12aaaaaaa34'); +insert /*+ ignore_error */ into t_date values('abcde'); +select * from t_date; +update /*+ ignore_error */ t_date set c = '12a34'; + +-- type: time +create table t_time(c time); +insert /*+ ignore_error */ into t_time values('12a34'); +insert /*+ ignore_error */ into t_time values('123a34'); +insert /*+ ignore_error */ into t_time values('12aaaaaaa34'); +insert /*+ ignore_error */ into t_time values('aaaaaaa12aaaaaaa34'); +insert /*+ ignore_error */ into t_time values('abcde'); +select * from t_time; +update /*+ ignore_error */ t_time set c = '12a34'; + +-- type: timestamp +create table t_timestamp(c timestamp); +insert /*+ ignore_error */ into t_timestamp values('12a34'); +insert /*+ ignore_error */ into t_timestamp values('abcde'); +insert /*+ ignore_error */ into t_timestamp values('aaaaaa12a34'); +select * from t_timestamp; +update /*+ ignore_error */ t_timestamp set c = '12a34'; + +-- type: timestamptz +create table t_timestamptz(c timestamptz); +insert /*+ ignore_error */ into t_timestamptz values('12a34'); +insert /*+ ignore_error */ into t_timestamptz values('abcde'); +insert /*+ ignore_error */ into t_timestamptz values('aaaaaa12a34'); +select * from t_timestamptz; +update /*+ ignore_error */ t_timestamptz set c = '12a34'; + +-- type: timetz +create table t_timetz(c timetz); +insert /*+ ignore_error */ into t_timetz values('12a34'); +insert /*+ ignore_error */ into t_timetz values('123a34'); +insert /*+ ignore_error */ into t_timetz values('12aaaaaaa34'); +insert /*+ ignore_error */ into t_timetz values('aaaaaaa12aaaaaaa34'); +insert /*+ ignore_error */ into t_timetz values('abcde'); +select * from t_timetz; +update /*+ ignore_error */ t_timetz set c = '12a34'; + +-- type: interval +create table t_interval(c interval); +insert /*+ ignore_error */ into t_interval values('12a34'); +insert /*+ ignore_error */ into t_interval values('123a34'); +insert /*+ ignore_error */ into t_interval values('12aaaaaaa34'); +insert /*+ ignore_error */ into t_interval values('aaaaaaa12aaaaaaa34'); +insert /*+ ignore_error */ into t_interval values('abcde'); +select * from t_interval; +update /*+ ignore_error */ t_interval set c = '12a34'; + +-- type: tinterval +create table t_tinterval(c tinterval); +insert /*+ ignore_error */ into t_tinterval values('12a34'); +insert /*+ ignore_error */ into t_tinterval values('123a34'); +insert /*+ ignore_error */ into t_tinterval values('12aaaaaaa34'); +insert /*+ ignore_error */ into t_tinterval values('aaaaaaa12aaaaaaa34'); +insert /*+ ignore_error */ into t_tinterval values('abcde'); +select * from t_tinterval; +update /*+ ignore_error */ t_tinterval set c = '12a34'; + +-- type: smalldatetime +create table t_smalldatetime(c smalldatetime); +insert /*+ ignore_error */ into t_smalldatetime values('12a34'); +insert /*+ ignore_error */ into t_smalldatetime values('123a34'); +insert /*+ ignore_error */ into t_smalldatetime values('12aaaaaaa34'); +insert /*+ ignore_error */ into t_smalldatetime values('aaaaaaa12aaaaaaa34'); +insert /*+ ignore_error */ into t_smalldatetime values('abcde'); +select * from t_smalldatetime; +update /*+ ignore_error */ t_smalldatetime set c = '12a34'; + +-- type: uuid +create table t_uuid(c uuid); +insert /*+ ignore_error */ into t_uuid values('12a34'); +update /*+ ignore_error */ t_uuid set c = '12a34'; +select * from t_uuid; + +-- type: point +create table t_point(c point); +insert /*+ ignore_error */ into t_point values('12a34'); +select * from t_point; +update /*+ ignore_error */ t_point set c = '12a34'; +select * from t_point; + +-- type: path +create table t_path(c path); +insert /*+ ignore_error */ into t_path values('12a34'); +select * from t_path; +update /*+ ignore_error */ t_path set c = '12a34'; +select * from t_path; + +-- type: polygon +create table t_polygon(c polygon); +insert /*+ ignore_error */ into t_polygon values('12a34'); +select * from t_polygon; +update /*+ ignore_error */ t_polygon set c = '12a34'; +select * from t_polygon; + +-- type: circle +create table t_circle(c circle); +insert /*+ ignore_error */ into t_circle values('12a34'); +select * from t_circle; +update /*+ ignore_error */ t_circle set c = '12a34'; +select * from t_circle; + +-- type: lseg +create table t_lseg(c lseg); +insert /*+ ignore_error */ into t_lseg values('12a34'); +select * from t_lseg; +update /*+ ignore_error */ t_lseg set c = '12a34'; +select * from t_lseg; + +-- type: box +create table t_box(c box); +insert /*+ ignore_error */ into t_box values('12a34'); +select * from t_box; +update /*+ ignore_error */ t_box set c = '12a34'; +select * from t_box; + +-- type: json +create table t_json(c json); +insert /*+ ignore_error */ into t_json values('12a34'); +select * from t_json; +update /*+ ignore_error */ t_json set c = '12a34'; +select * from t_json; + +-- type: jsonb +create table t_jsonb(c jsonb); +insert /*+ ignore_error */ into t_jsonb values('12a34'); +select * from t_jsonb; +update /*+ ignore_error */ t_jsonb set c = '12a34'; +select * from t_jsonb; + +-- type: bit +create table t_bit(c bit); +insert /*+ ignore_error */ into t_bit values('12a34'); +select * from t_bit; +update /*+ ignore_error */ t_bit set c = '12a34'; +select * from t_bit; + +-- restore context +reset timezone; +show timezone; +\c postgres +drop database if exists sql_ignore_invalid_input_test; \ No newline at end of file