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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy