2 F.20. isn — data types for international standard numbers (ISBN, EAN, UPC,
7 F.20.3. Functions and Operators
8 F.20.4. Configuration Parameters
13 The isn module provides data types for the following international
14 product numbering standards: EAN13, UPC, ISBN (books), ISMN (music),
15 and ISSN (serials). Numbers are validated on input according to a
16 hard-coded list of prefixes; this list of prefixes is also used to
17 hyphenate numbers on output. Since new prefixes are assigned from time
18 to time, the list of prefixes may be out of date. It is hoped that a
19 future version of this module will obtain the prefix list from one or
20 more tables that can be easily updated by users as needed; however, at
21 present, the list can only be updated by modifying the source code and
22 recompiling. Alternatively, prefix validation and hyphenation support
23 may be dropped from a future version of this module.
25 This module is considered “trusted”, that is, it can be installed by
26 non-superusers who have CREATE privilege on the current database.
30 Table F.10 shows the data types provided by the isn module.
32 Table F.10. isn Data Types
34 EAN13 European Article Numbers, always displayed in the EAN13 display
36 ISBN13 International Standard Book Numbers to be displayed in the new
38 ISMN13 International Standard Music Numbers to be displayed in the new
40 ISSN13 International Standard Serial Numbers to be displayed in the new
42 ISBN International Standard Book Numbers to be displayed in the old
44 ISMN International Standard Music Numbers to be displayed in the old
46 ISSN International Standard Serial Numbers to be displayed in the old
48 UPC Universal Product Codes
51 1. ISBN13, ISMN13, ISSN13 numbers are all EAN13 numbers.
52 2. EAN13 numbers aren't always ISBN13, ISMN13 or ISSN13 (some are).
53 3. Some ISBN13 numbers can be displayed as ISBN.
54 4. Some ISMN13 numbers can be displayed as ISMN.
55 5. Some ISSN13 numbers can be displayed as ISSN.
56 6. UPC numbers are a subset of the EAN13 numbers (they are basically
57 EAN13 without the first 0 digit).
58 7. All UPC, ISBN, ISMN and ISSN numbers can be represented as EAN13
61 Internally, all these types use the same representation (a 64-bit
62 integer), and all are interchangeable. Multiple types are provided to
63 control display formatting and to permit tighter validity checking of
64 input that is supposed to denote one particular type of number.
66 The ISBN, ISMN, and ISSN types will display the short version of the
67 number (ISxN 10) whenever it's possible, and will show ISxN 13 format
68 for numbers that do not fit in the short version. The EAN13, ISBN13,
69 ISMN13 and ISSN13 types will always display the long version of the
74 The isn module provides the following pairs of type casts:
86 When casting from EAN13 to another type, there is a run-time check that
87 the value is within the domain of the other type, and an error is
88 thrown if not. The other casts are simply relabelings that will always
91 F.20.3. Functions and Operators #
93 The isn module provides the standard comparison operators, plus B-tree
94 and hash indexing support for all these data types. In addition, there
95 are several specialized functions, shown in Table F.11. In this table,
96 isn means any one of the module's data types.
98 Table F.11. isn Functions
104 make_valid ( isn ) → isn
106 Clears the invalid-check-digit flag of the value.
108 is_valid ( isn ) → boolean
110 Checks for the presence of the invalid-check-digit flag.
112 isn_weak ( boolean ) → boolean
114 Sets the weak input mode, and returns the new setting. This function is
115 retained for backward compatibility. The recommended way to set weak
116 mode is via the isn.weak configuration parameter.
118 isn_weak () → boolean
120 Returns the current status of the weak mode. This function is retained
121 for backward compatibility. The recommended way to check weak mode is
122 via the isn.weak configuration parameter.
124 F.20.4. Configuration Parameters #
127 isn.weak enables the weak input mode, which allows ISN input
128 values to be accepted even when their check digit is wrong. The
129 default is false, which rejects invalid check digits.
131 Why would you want to use the weak mode? Well, it could be that you
132 have a huge collection of ISBN numbers, and that there are so many of
133 them that for weird reasons some have the wrong check digit (perhaps
134 the numbers were scanned from a printed list and the OCR got the
135 numbers wrong, perhaps the numbers were manually captured... who
136 knows). Anyway, the point is you might want to clean the mess up, but
137 you still want to be able to have all the numbers in your database and
138 maybe use an external tool to locate the invalid numbers in the
139 database so you can verify the information and validate it more easily;
140 so for example you'd want to select all the invalid numbers in the
143 When you insert invalid numbers in a table using the weak mode, the
144 number will be inserted with the corrected check digit, but it will be
145 displayed with an exclamation mark (!) at the end, for example
146 0-11-000322-5!. This invalid marker can be checked with the is_valid
147 function and cleared with the make_valid function.
149 You can also force the insertion of marked-as-invalid numbers even when
150 not in the weak mode, by appending the ! character at the end of the
153 Another special feature is that during input, you can write ? in place
154 of the check digit, and the correct check digit will be inserted
159 --Using the types directly:
160 SELECT isbn('978-0-393-04002-9');
161 SELECT isbn13('0901690546');
162 SELECT issn('1436-4522');
165 -- note that you can only cast from ean13 to another type when the
166 -- number would be valid in the realm of the target type;
167 -- thus, the following will NOT work: select isbn(ean13('0220356483481'));
169 SELECT upc(ean13('0220356483481'));
170 SELECT ean13(upc('220356483481'));
172 --Create a table with a single column to hold ISBN numbers:
173 CREATE TABLE test (id isbn);
174 INSERT INTO test VALUES('9780393040029');
176 --Automatically calculate check digits (observe the '?'):
177 INSERT INTO test VALUES('220500896?');
178 INSERT INTO test VALUES('978055215372?');
180 SELECT issn('3251231?');
181 SELECT ismn('979047213542?');
183 --Using the weak mode:
184 SET isn.weak TO true;
185 INSERT INTO test VALUES('978-0-11-000533-4');
186 INSERT INTO test VALUES('9780141219307');
187 INSERT INTO test VALUES('2-205-00876-X');
188 SET isn.weak TO false;
190 SELECT id FROM test WHERE NOT is_valid(id);
191 UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!';
195 SELECT isbn13(id) FROM test;
197 F.20.6. Bibliography #
199 The information to implement this module was collected from several
201 * https://www.isbn-international.org/
202 * https://www.issn.org/
203 * https://www.ismn-international.org/
204 * https://www.wikipedia.org/
206 The prefixes used for hyphenation were also compiled from:
207 * https://www.gs1.org/standards/id-keys
208 * https://en.wikipedia.org/wiki/List_of_ISBN_registration_groups
209 * https://www.isbn-international.org/content/isbn-users-manual/29
210 * https://en.wikipedia.org/wiki/International_Standard_Music_Number
211 * https://www.ismn-international.org/ranges/tools
213 Care was taken during the creation of the algorithms and they were
214 meticulously verified against the suggested algorithms in the official
215 ISBN, ISMN, ISSN User Manuals.
219 Germán Méndez Bravo (Kronuz), 2004–2006
221 This module was inspired by Garrett A. Wollman's isbn_issn code.