Skip to content

Commit 720e032

Browse files
committed
Convert contrib/isn's input functions to report errors softly
1 parent e37fe1d commit 720e032

File tree

3 files changed

+63
-44
lines changed

3 files changed

+63
-44
lines changed

contrib/isn/expected/isn.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,21 @@ SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
260260
t | t | t
261261
(1 row)
262262

263+
-- test non-error-throwing input API
264+
SELECT str as isn, typ as "type",
265+
pg_input_is_valid(str,typ) as ok,
266+
pg_input_error_message(str,typ) as errmsg
267+
FROM (VALUES ('9780123456786', 'UPC'),
268+
('postgresql...','EAN13'),
269+
('9771234567003','ISSN'))
270+
AS a(str,typ);
271+
isn | type | ok | errmsg
272+
---------------+-------+----+--------------------------------------------------------
273+
9780123456786 | UPC | f | cannot cast ISBN to UPC for number: "9780123456786"
274+
postgresql... | EAN13 | f | invalid input syntax for EAN13 number: "postgresql..."
275+
9771234567003 | ISSN | t |
276+
(3 rows)
277+
263278
--
264279
-- cleanup
265280
--

contrib/isn/isn.c

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -675,14 +675,14 @@ ean2string(ean13 ean, bool errorOK, char *result, bool shortType)
675675
/*
676676
* string2ean --- try to parse a string into an ean13.
677677
*
678-
* If errorOK is false, ereport a useful error message if the string is bad.
679-
* If errorOK is true, just return "false" for bad input.
678+
* ereturn false with a useful error message if the string is bad.
679+
* Otherwise return true.
680680
*
681681
* if the input string ends with '!' it will always be treated as invalid
682682
* (even if the check digit is valid)
683683
*/
684684
static bool
685-
string2ean(const char *str, bool errorOK, ean13 *result,
685+
string2ean(const char *str, struct Node *escontext, ean13 *result,
686686
enum isn_type accept)
687687
{
688688
bool digit,
@@ -876,48 +876,38 @@ string2ean(const char *str, bool errorOK, ean13 *result,
876876
return true;
877877
}
878878

879-
if (!errorOK)
879+
if (rcheck == (unsigned) -1)
880880
{
881-
if (rcheck == (unsigned) -1)
882-
{
883-
ereport(ERROR,
884-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
885-
errmsg("invalid %s number: \"%s\"",
886-
isn_names[accept], str)));
887-
}
888-
else
889-
{
890-
ereport(ERROR,
891-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
892-
errmsg("invalid check digit for %s number: \"%s\", should be %c",
893-
isn_names[accept], str, (rcheck == 10) ? ('X') : (rcheck + '0'))));
894-
}
881+
ereturn(escontext, false,
882+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
883+
errmsg("invalid %s number: \"%s\"",
884+
isn_names[accept], str)));
885+
}
886+
else
887+
{
888+
ereturn(escontext, false,
889+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
890+
errmsg("invalid check digit for %s number: \"%s\", should be %c",
891+
isn_names[accept], str, (rcheck == 10) ? ('X') : (rcheck + '0'))));
895892
}
896-
return false;
897893

898894
eaninvalid:
899-
if (!errorOK)
900-
ereport(ERROR,
901-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
902-
errmsg("invalid input syntax for %s number: \"%s\"",
903-
isn_names[accept], str)));
904-
return false;
895+
ereturn(escontext, false,
896+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
897+
errmsg("invalid input syntax for %s number: \"%s\"",
898+
isn_names[accept], str)));
905899

906900
eanwrongtype:
907-
if (!errorOK)
908-
ereport(ERROR,
909-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
910-
errmsg("cannot cast %s to %s for number: \"%s\"",
911-
isn_names[type], isn_names[accept], str)));
912-
return false;
901+
ereturn(escontext, false,
902+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
903+
errmsg("cannot cast %s to %s for number: \"%s\"",
904+
isn_names[type], isn_names[accept], str)));
913905

914906
eantoobig:
915-
if (!errorOK)
916-
ereport(ERROR,
917-
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
918-
errmsg("value \"%s\" is out of range for %s type",
919-
str, isn_names[accept])));
920-
return false;
907+
ereturn(escontext, false,
908+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
909+
errmsg("value \"%s\" is out of range for %s type",
910+
str, isn_names[accept])));
921911
}
922912

923913
/*----------------------------------------------------------
@@ -952,7 +942,7 @@ isn_out(PG_FUNCTION_ARGS)
952942
char *result;
953943
char buf[MAXEAN13LEN + 1];
954944

955-
(void) ean2string(val, false, buf, true);
945+
(void) ean2string(val, fcinfo->context, buf, true);
956946

957947
result = pstrdup(buf);
958948
PG_RETURN_CSTRING(result);
@@ -968,7 +958,7 @@ ean13_out(PG_FUNCTION_ARGS)
968958
char *result;
969959
char buf[MAXEAN13LEN + 1];
970960

971-
(void) ean2string(val, false, buf, false);
961+
(void) ean2string(val, fcinfo->context, buf, false);
972962

973963
result = pstrdup(buf);
974964
PG_RETURN_CSTRING(result);
@@ -983,7 +973,8 @@ ean13_in(PG_FUNCTION_ARGS)
983973
const char *str = PG_GETARG_CSTRING(0);
984974
ean13 result;
985975

986-
(void) string2ean(str, false, &result, EAN13);
976+
if (!string2ean(str, fcinfo->context, &result, EAN13))
977+
PG_RETURN_NULL();
987978
PG_RETURN_EAN13(result);
988979
}
989980

@@ -996,7 +987,8 @@ isbn_in(PG_FUNCTION_ARGS)
996987
const char *str = PG_GETARG_CSTRING(0);
997988
ean13 result;
998989

999-
(void) string2ean(str, false, &result, ISBN);
990+
if (!string2ean(str, fcinfo->context, &result, ISBN))
991+
PG_RETURN_NULL();
1000992
PG_RETURN_EAN13(result);
1001993
}
1002994

@@ -1009,7 +1001,8 @@ ismn_in(PG_FUNCTION_ARGS)
10091001
const char *str = PG_GETARG_CSTRING(0);
10101002
ean13 result;
10111003

1012-
(void) string2ean(str, false, &result, ISMN);
1004+
if (!string2ean(str, fcinfo->context, &result, ISMN))
1005+
PG_RETURN_NULL();
10131006
PG_RETURN_EAN13(result);
10141007
}
10151008

@@ -1022,7 +1015,8 @@ issn_in(PG_FUNCTION_ARGS)
10221015
const char *str = PG_GETARG_CSTRING(0);
10231016
ean13 result;
10241017

1025-
(void) string2ean(str, false, &result, ISSN);
1018+
if (!string2ean(str, fcinfo->context, &result, ISSN))
1019+
PG_RETURN_NULL();
10261020
PG_RETURN_EAN13(result);
10271021
}
10281022

@@ -1035,7 +1029,8 @@ upc_in(PG_FUNCTION_ARGS)
10351029
const char *str = PG_GETARG_CSTRING(0);
10361030
ean13 result;
10371031

1038-
(void) string2ean(str, false, &result, UPC);
1032+
if (!string2ean(str, fcinfo->context, &result, UPC))
1033+
PG_RETURN_NULL();
10391034
PG_RETURN_EAN13(result);
10401035
}
10411036

contrib/isn/sql/isn.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
107107
'M-1234-5678-5'::ISMN = '9790123456785'::EAN13 AS "ok",
108108
'9791234567896'::EAN13 != '123456789X'::ISBN AS "nope";
109109

110+
-- test non-error-throwing input API
111+
SELECT str as isn, typ as "type",
112+
pg_input_is_valid(str,typ) as ok,
113+
pg_input_error_message(str,typ) as errmsg
114+
FROM (VALUES ('9780123456786', 'UPC'),
115+
('postgresql...','EAN13'),
116+
('9771234567003','ISSN'))
117+
AS a(str,typ);
118+
110119
--
111120
-- cleanup
112121
--

0 commit comments

Comments
 (0)