aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2022-12-24 15:28:13 -0500
committerAndrew Dunstan <andrew@dunslane.net>2022-12-24 15:28:13 -0500
commit720e0327bc98464b889801a65ae2358f86a0265a (patch)
treebdb325ae536b3ce761ba34cc6dce0fd18ad3807f
parente37fe1db6ef930f657be28fe764f7e642b93464a (diff)
downloadpostgresql-720e0327bc98464b889801a65ae2358f86a0265a.tar.gz
postgresql-720e0327bc98464b889801a65ae2358f86a0265a.zip
Convert contrib/isn's input functions to report errors softly
-rw-r--r--contrib/isn/expected/isn.out15
-rw-r--r--contrib/isn/isn.c83
-rw-r--r--contrib/isn/sql/isn.sql9
3 files changed, 63 insertions, 44 deletions
diff --git a/contrib/isn/expected/isn.out b/contrib/isn/expected/isn.out
index 18fe37a82c3..72171b2790e 100644
--- a/contrib/isn/expected/isn.out
+++ b/contrib/isn/expected/isn.out
@@ -260,6 +260,21 @@ SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
t | t | t
(1 row)
+-- test non-error-throwing input API
+SELECT str as isn, typ as "type",
+ pg_input_is_valid(str,typ) as ok,
+ pg_input_error_message(str,typ) as errmsg
+FROM (VALUES ('9780123456786', 'UPC'),
+ ('postgresql...','EAN13'),
+ ('9771234567003','ISSN'))
+ AS a(str,typ);
+ isn | type | ok | errmsg
+---------------+-------+----+--------------------------------------------------------
+ 9780123456786 | UPC | f | cannot cast ISBN to UPC for number: "9780123456786"
+ postgresql... | EAN13 | f | invalid input syntax for EAN13 number: "postgresql..."
+ 9771234567003 | ISSN | t |
+(3 rows)
+
--
-- cleanup
--
diff --git a/contrib/isn/isn.c b/contrib/isn/isn.c
index a53d99722ad..a86db045dec 100644
--- a/contrib/isn/isn.c
+++ b/contrib/isn/isn.c
@@ -675,14 +675,14 @@ eantoobig:
/*
* string2ean --- try to parse a string into an ean13.
*
- * If errorOK is false, ereport a useful error message if the string is bad.
- * If errorOK is true, just return "false" for bad input.
+ * ereturn false with a useful error message if the string is bad.
+ * Otherwise return true.
*
* if the input string ends with '!' it will always be treated as invalid
* (even if the check digit is valid)
*/
static bool
-string2ean(const char *str, bool errorOK, ean13 *result,
+string2ean(const char *str, struct Node *escontext, ean13 *result,
enum isn_type accept)
{
bool digit,
@@ -876,48 +876,38 @@ eanbadcheck:
return true;
}
- if (!errorOK)
+ if (rcheck == (unsigned) -1)
{
- if (rcheck == (unsigned) -1)
- {
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid %s number: \"%s\"",
- isn_names[accept], str)));
- }
- else
- {
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid check digit for %s number: \"%s\", should be %c",
- isn_names[accept], str, (rcheck == 10) ? ('X') : (rcheck + '0'))));
- }
+ ereturn(escontext, false,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid %s number: \"%s\"",
+ isn_names[accept], str)));
+ }
+ else
+ {
+ ereturn(escontext, false,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid check digit for %s number: \"%s\", should be %c",
+ isn_names[accept], str, (rcheck == 10) ? ('X') : (rcheck + '0'))));
}
- return false;
eaninvalid:
- if (!errorOK)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("invalid input syntax for %s number: \"%s\"",
- isn_names[accept], str)));
- return false;
+ ereturn(escontext, false,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for %s number: \"%s\"",
+ isn_names[accept], str)));
eanwrongtype:
- if (!errorOK)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
- errmsg("cannot cast %s to %s for number: \"%s\"",
- isn_names[type], isn_names[accept], str)));
- return false;
+ ereturn(escontext, false,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("cannot cast %s to %s for number: \"%s\"",
+ isn_names[type], isn_names[accept], str)));
eantoobig:
- if (!errorOK)
- ereport(ERROR,
- (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
- errmsg("value \"%s\" is out of range for %s type",
- str, isn_names[accept])));
- return false;
+ ereturn(escontext, false,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("value \"%s\" is out of range for %s type",
+ str, isn_names[accept])));
}
/*----------------------------------------------------------
@@ -952,7 +942,7 @@ isn_out(PG_FUNCTION_ARGS)
char *result;
char buf[MAXEAN13LEN + 1];
- (void) ean2string(val, false, buf, true);
+ (void) ean2string(val, fcinfo->context, buf, true);
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
@@ -968,7 +958,7 @@ ean13_out(PG_FUNCTION_ARGS)
char *result;
char buf[MAXEAN13LEN + 1];
- (void) ean2string(val, false, buf, false);
+ (void) ean2string(val, fcinfo->context, buf, false);
result = pstrdup(buf);
PG_RETURN_CSTRING(result);
@@ -983,7 +973,8 @@ ean13_in(PG_FUNCTION_ARGS)
const char *str = PG_GETARG_CSTRING(0);
ean13 result;
- (void) string2ean(str, false, &result, EAN13);
+ if (!string2ean(str, fcinfo->context, &result, EAN13))
+ PG_RETURN_NULL();
PG_RETURN_EAN13(result);
}
@@ -996,7 +987,8 @@ isbn_in(PG_FUNCTION_ARGS)
const char *str = PG_GETARG_CSTRING(0);
ean13 result;
- (void) string2ean(str, false, &result, ISBN);
+ if (!string2ean(str, fcinfo->context, &result, ISBN))
+ PG_RETURN_NULL();
PG_RETURN_EAN13(result);
}
@@ -1009,7 +1001,8 @@ ismn_in(PG_FUNCTION_ARGS)
const char *str = PG_GETARG_CSTRING(0);
ean13 result;
- (void) string2ean(str, false, &result, ISMN);
+ if (!string2ean(str, fcinfo->context, &result, ISMN))
+ PG_RETURN_NULL();
PG_RETURN_EAN13(result);
}
@@ -1022,7 +1015,8 @@ issn_in(PG_FUNCTION_ARGS)
const char *str = PG_GETARG_CSTRING(0);
ean13 result;
- (void) string2ean(str, false, &result, ISSN);
+ if (!string2ean(str, fcinfo->context, &result, ISSN))
+ PG_RETURN_NULL();
PG_RETURN_EAN13(result);
}
@@ -1035,7 +1029,8 @@ upc_in(PG_FUNCTION_ARGS)
const char *str = PG_GETARG_CSTRING(0);
ean13 result;
- (void) string2ean(str, false, &result, UPC);
+ if (!string2ean(str, fcinfo->context, &result, UPC))
+ PG_RETURN_NULL();
PG_RETURN_EAN13(result);
}
diff --git a/contrib/isn/sql/isn.sql b/contrib/isn/sql/isn.sql
index 71577d5590f..6426cb42a0f 100644
--- a/contrib/isn/sql/isn.sql
+++ b/contrib/isn/sql/isn.sql
@@ -107,6 +107,15 @@ SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
'M-1234-5678-5'::ISMN = '9790123456785'::EAN13 AS "ok",
'9791234567896'::EAN13 != '123456789X'::ISBN AS "nope";
+-- test non-error-throwing input API
+SELECT str as isn, typ as "type",
+ pg_input_is_valid(str,typ) as ok,
+ pg_input_error_message(str,typ) as errmsg
+FROM (VALUES ('9780123456786', 'UPC'),
+ ('postgresql...','EAN13'),
+ ('9771234567003','ISSN'))
+ AS a(str,typ);
+
--
-- cleanup
--