diff --git a/contrib/isn/Makefile b/contrib/isn/Makefile index 1037506c705..bfe8977bb64 100644 --- a/contrib/isn/Makefile +++ b/contrib/isn/Makefile @@ -3,8 +3,8 @@ MODULES = isn EXTENSION = isn -DATA = isn--1.1.sql isn--1.1--1.2.sql \ - isn--1.0--1.1.sql +DATA = isn--1.0--1.1.sql isn--1.1.sql \ + isn--1.1--1.2.sql isn--1.2--1.3.sql PGFILEDESC = "isn - data types for international product numbering standards" # the other .h files are data tables, we don't install those diff --git a/contrib/isn/expected/isn.out b/contrib/isn/expected/isn.out index 2f05b7eb861..c533768d926 100644 --- a/contrib/isn/expected/isn.out +++ b/contrib/isn/expected/isn.out @@ -279,6 +279,50 @@ FROM (VALUES ('9780123456786', 'UPC'), 9771234567003 | ISSN | t | | | | (3 rows) +-- +-- test weak mode +-- +SELECT '2222222222221'::ean13; -- fail +ERROR: invalid check digit for EAN13 number: "2222222222221", should be 2 +LINE 1: SELECT '2222222222221'::ean13; + ^ +SET isn.weak TO TRUE; +SELECT '2222222222221'::ean13; + ean13 +------------------ + 222-222222222-2! +(1 row) + +SELECT is_valid('2222222222221'::ean13); + is_valid +---------- + f +(1 row) + +SELECT make_valid('2222222222221'::ean13); + make_valid +----------------- + 222-222222222-2 +(1 row) + +SELECT isn_weak(); -- backwards-compatibility wrappers for accessing the GUC + isn_weak +---------- + t +(1 row) + +SELECT isn_weak(false); + isn_weak +---------- + f +(1 row) + +SHOW isn.weak; + isn.weak +---------- + off +(1 row) + -- -- cleanup -- diff --git a/contrib/isn/isn--1.2--1.3.sql b/contrib/isn/isn--1.2--1.3.sql new file mode 100644 index 00000000000..a8e30ff44fb --- /dev/null +++ b/contrib/isn/isn--1.2--1.3.sql @@ -0,0 +1,7 @@ +/* contrib/isn/isn--1.2--1.3.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION isn UPDATE TO '1.3'" to load this file. \quit + +ALTER FUNCTION isn_weak(boolean) VOLATILE PARALLEL UNSAFE; +ALTER FUNCTION isn_weak() STABLE PARALLEL SAFE; diff --git a/contrib/isn/isn.c b/contrib/isn/isn.c index db765ee490d..5783c188737 100644 --- a/contrib/isn/isn.c +++ b/contrib/isn/isn.c @@ -21,6 +21,7 @@ #include "UPC.h" #include "fmgr.h" #include "isn.h" +#include "utils/guc.h" PG_MODULE_MAGIC; @@ -39,6 +40,7 @@ enum isn_type static const char *const isn_names[] = {"EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC"}; +/* GUC value */ static bool g_weak = false; @@ -929,6 +931,20 @@ _PG_init(void) if (!check_table(UPC_range, UPC_index)) elog(ERROR, "UPC failed check"); } + + /* Define a GUC variable for weak mode. */ + DefineCustomBoolVariable("isn.weak", + "Accept input with invalid ISN check digits.", + NULL, + &g_weak, + false, + PGC_USERSET, + 0, + NULL, + NULL, + NULL); + + MarkGUCPrefixReserved("isn"); } /* isn_out @@ -1109,17 +1125,16 @@ make_valid(PG_FUNCTION_ARGS) /* this function temporarily sets weak input flag * (to lose the strictness of check digit acceptance) - * It's a helper function, not intended to be used!! */ PG_FUNCTION_INFO_V1(accept_weak_input); Datum accept_weak_input(PG_FUNCTION_ARGS) { -#ifdef ISN_WEAK_MODE - g_weak = PG_GETARG_BOOL(0); -#else - /* function has no effect */ -#endif /* ISN_WEAK_MODE */ + bool newvalue = PG_GETARG_BOOL(0); + + (void) set_config_option("isn.weak", newvalue ? "on" : "off", + PGC_USERSET, PGC_S_SESSION, + GUC_ACTION_SET, true, 0, false); PG_RETURN_BOOL(g_weak); } diff --git a/contrib/isn/isn.control b/contrib/isn/isn.control index 1cb5e2b2340..e7daea52b84 100644 --- a/contrib/isn/isn.control +++ b/contrib/isn/isn.control @@ -1,6 +1,6 @@ # isn extension comment = 'data types for international product numbering standards' -default_version = '1.2' +default_version = '1.3' module_pathname = '$libdir/isn' relocatable = true trusted = true diff --git a/contrib/isn/isn.h b/contrib/isn/isn.h index 038eb362c39..399896ad417 100644 --- a/contrib/isn/isn.h +++ b/contrib/isn/isn.h @@ -18,7 +18,6 @@ #include "fmgr.h" #undef ISN_DEBUG -#define ISN_WEAK_MODE /* * uint64 is the internal storage format for ISNs. diff --git a/contrib/isn/meson.build b/contrib/isn/meson.build index fbbeeff01bb..39cf781684e 100644 --- a/contrib/isn/meson.build +++ b/contrib/isn/meson.build @@ -19,8 +19,9 @@ contrib_targets += isn install_data( 'isn.control', 'isn--1.0--1.1.sql', - 'isn--1.1--1.2.sql', 'isn--1.1.sql', + 'isn--1.1--1.2.sql', + 'isn--1.2--1.3.sql', kwargs: contrib_data_args, ) diff --git a/contrib/isn/sql/isn.sql b/contrib/isn/sql/isn.sql index 2c2ea077d1e..043e5580b0d 100644 --- a/contrib/isn/sql/isn.sql +++ b/contrib/isn/sql/isn.sql @@ -120,6 +120,19 @@ FROM (VALUES ('9780123456786', 'UPC'), AS a(str,typ), LATERAL pg_input_error_info(a.str, a.typ) as errinfo; +-- +-- test weak mode +-- +SELECT '2222222222221'::ean13; -- fail +SET isn.weak TO TRUE; +SELECT '2222222222221'::ean13; +SELECT is_valid('2222222222221'::ean13); +SELECT make_valid('2222222222221'::ean13); + +SELECT isn_weak(); -- backwards-compatibility wrappers for accessing the GUC +SELECT isn_weak(false); +SHOW isn.weak; + -- -- cleanup -- diff --git a/doc/src/sgml/isn.sgml b/doc/src/sgml/isn.sgml index 45a867d98c2..1f08ada6218 100644 --- a/doc/src/sgml/isn.sgml +++ b/doc/src/sgml/isn.sgml @@ -230,7 +230,7 @@ The isn module provides the standard comparison operators, plus B-tree and hash indexing support for all these data types. In - addition there are several specialized functions; shown in . + addition, there are several specialized functions, shown in . In this table, isn means any one of the module's data types. @@ -250,27 +250,6 @@ - - - isn_weak - isn_weak ( boolean ) - boolean - - - Sets the weak input mode, and returns new setting. - - - - - - isn_weak () - boolean - - - Returns the current status of the weak mode. - - - make_valid @@ -278,7 +257,7 @@ isn - Validates an invalid number (clears the invalid flag). + Clears the invalid-check-digit flag of the value. @@ -289,18 +268,62 @@ boolean - Checks for the presence of the invalid flag. + Checks for the presence of the invalid-check-digit flag. + + + + + + isn_weak + isn_weak ( boolean ) + boolean + + + Sets the weak input mode, and returns the new setting. + This function is retained for backward compatibility. + The recommended way to set weak mode is via + the isn.weak configuration parameter. + + + + + + isn_weak () + boolean + + + Returns the current status of the weak mode. + This function is retained for backward compatibility. + The recommended way to check weak mode is via + the isn.weak configuration parameter. + - - Weak mode is used to be able to insert invalid data - into a table. Invalid means the check digit is wrong, not that there are - missing numbers. - + + Configuration Parameters + + + + + isn.weak (boolean) + + isn.weak configuration parameter + + + + + isn.weak enables the weak input mode, which allows + ISN input values to be accepted even when their check digit is wrong. + The default is false, which rejects invalid check + digits. + + + + Why would you want to use the weak mode? Well, it could be that @@ -325,9 +348,9 @@ - You can also force the insertion of invalid numbers even when not in the - weak mode, by appending the ! character at the end of the - number. + You can also force the insertion of marked-as-invalid numbers even when not + in the weak mode, by appending the ! character at the + end of the number. @@ -366,11 +389,11 @@ SELECT issn('3251231?'); SELECT ismn('979047213542?'); --Using the weak mode: -SELECT isn_weak(true); +SET isn.weak TO true; INSERT INTO test VALUES('978-0-11-000533-4'); INSERT INTO test VALUES('9780141219307'); INSERT INTO test VALUES('2-205-00876-X'); -SELECT isn_weak(false); +SET isn.weak TO false; SELECT id FROM test WHERE NOT is_valid(id); UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!';