Thread: Validating problem in the isn contrib module

Validating problem in the isn contrib module

From
Andreas 'ads' Scherbaum
Date:
Hello all,

i'm playing around with the isn contrib module and ran into an
annoying problem. The module defines an is_valid() function which
obviously is intended to check the validity of an ISBN number. Makes
sense to have such a function because if the user mistyped the number
the application can raise an error.

Now it seems that instead of the application PostgreSQL is raising the
error:


test=# select is_valid('978-3-937514-69-7'::isbn13);is_valid
----------t
(1 row)


test=# select is_valid('978-3-937514-69-6'::isbn13);
ERROR:  invalid check digit for ISBN number: "978-3-937514-69-6",
should be 7 ROW 1: select is_valid('978-3-937514-69-6'::isbn13);                        ^


The first ISBN is valid and the validator function returns 't', that's
fine. The second ISBN is invalid, i mistyped one number. The expected
output is 'f', PG is not supposed to raise an error and break my entire
transaction.


Is this just a bug or is this intended behaviour. And if it's not a
bug, how can i validate an ISBN number in my application - without
raising an error?


Thank you & kind regards

--             Andreas 'ads' Scherbaum
German PostgreSQL User Group
European PostgreSQL User Group - Board of Directors


Re: Validating problem in the isn contrib module

From
"A. Kretschmer"
Date:
In response to Andreas 'ads' Scherbaum :
> 
> Hello all,
> 
> 
> test=# select is_valid('978-3-937514-69-7'::isbn13);
>  is_valid
> ----------
>  t
> (1 row)

Nice advertisement for your book...

Andreas
-- 
Andreas Kretschmer
Kontakt:  Heynitz: 035242/47150,   D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID:   0x3FFF606C, privat 0x7F4584DA   http://wwwkeys.de.pgp.net


Re: Validating problem in the isn contrib module

From
Bernd Helmle
Date:
--On Freitag, März 06, 2009 02:26:12 +0100 Andreas 'ads' Scherbaum
<adsmail@wars-nicht.de> wrote:

> test=# select is_valid('978-3-937514-69-6'::isbn13);
> ERROR:  invalid check digit for ISBN number: "978-3-937514-69-6",
> should be 7 ROW 1: select is_valid('978-3-937514-69-6'::isbn13);

According to the docs, this is intended behavior. If you want to validate
those values later or yourself, you have to use the weak mode:


#= SELECT isn_weak(true);isn_weak
----------t

#= SELECT is_valid('978-3-937514-69-6'::isbn13);is_valid
----------f

#= SELECT is_valid('978-3-937514-69-7'::isbn13);is_valid
----------t

--  Thanks
                   Bernd


Re: Validating problem in the isn contrib module

From
Andreas 'ads' Scherbaum
Date:
On Fri, 06 Mar 2009 00:32:40 +0100 Bernd Helmle wrote:

> --On Freitag, März 06, 2009 02:26:12 +0100 Andreas 'ads' Scherbaum
> <adsmail@wars-nicht.de> wrote:
>
> > test=# select is_valid('978-3-937514-69-6'::isbn13);
> > ERROR:  invalid check digit for ISBN number: "978-3-937514-69-6",
> > should be 7 ROW 1: select is_valid('978-3-937514-69-6'::isbn13);
>
> According to the docs, this is intended behavior. If you want to validate
> those values later or yourself, you have to use the weak mode:

No.
Straight from the source:

-- isn_weak(boolean) - Sets the weak input mode.
-- This function is intended for testing use only!


The validator function should use the weak mode for itself to return
'f' in case of invalid input. It cannot be the users job to make sure a
validator function is working as expected.


Bye

--             Andreas 'ads' Scherbaum
German PostgreSQL User Group
European PostgreSQL User Group - Board of Directors


Re: Validating problem in the isn contrib module

From
Andreas 'ads' Scherbaum
Date:
On Fri, 6 Mar 2009 07:14:20 +0100 A. Kretschmer wrote:

> Nice advertisement for your book...

Actually the example is copy&paste from the .tex file ;-)


Bye

--             Andreas 'ads' Scherbaum
German PostgreSQL User Group
European PostgreSQL User Group - Board of Directors


Re: Validating problem in the isn contrib module

From
Gregory Stark
Date:
Andreas 'ads' Scherbaum <adsmail@wars-nicht.de> writes:

> The validator function should use the weak mode for itself to return
> 'f' in case of invalid input. It cannot be the users job to make sure a
> validator function is working as expected.

Well the input function is being called before the validator function ever
gets a chance to act. The validator function receives an already-formed isbn13
datum.

Is there an is_valid() which takes text input? Perhaps there should be --
though I think it would have to be isbn_is_valid() or something like that.

--  Gregory Stark EnterpriseDB          http://www.enterprisedb.com Ask me about EnterpriseDB's RemoteDBA services!


Re: Validating problem in the isn contrib module

From
Andreas 'ads' Scherbaum
Date:
On Fri, 06 Mar 2009 10:50:41 +0000 Gregory Stark wrote:

> Andreas 'ads' Scherbaum <adsmail@wars-nicht.de> writes:
> 
> > The validator function should use the weak mode for itself to return
> > 'f' in case of invalid input. It cannot be the users job to make sure a
> > validator function is working as expected.
> 
> Well the input function is being called before the validator function ever
> gets a chance to act. The validator function receives an already-formed isbn13
> datum.

That's the problem.


> Is there an is_valid() which takes text input? Perhaps there should be --
> though I think it would have to be isbn_is_valid() or something like that.

I think that's the intention of the is_valid() function. However it's
not working. And yes, a moe descriptive name would be fine.


Bye

--             Andreas 'ads' Scherbaum
German PostgreSQL User Group
European PostgreSQL User Group - Board of Directors


Re: Validating problem in the isn contrib module

From
Bernd Helmle
Date:
--On Freitag, März 06, 2009 11:32:14 +0100 Andreas 'ads' Scherbaum
<adsmail@wars-nicht.de> wrote:

> No.
> Straight from the source:
>
> -- isn_weak(boolean) - Sets the weak input mode.
> -- This function is intended for testing use only!
>
>
> The validator function should use the weak mode for itself to return
> 'f' in case of invalid input. It cannot be the users job to make sure a
> validator function is working as expected.
>

I don't see anything that's not already documented. is_valid() checks the
presence of the invalid (!) marker only. It looks like the author never
intended is_valid() to be a "check wether this ISBN is semantically
correct", this is done by the input routines before.

I agree that the naming is a little bit misleading.

--  Thanks
                   Bernd


Re: Validating problem in the isn contrib module

From
Andreas 'ads' Scherbaum
Date:
On Fri, 06 Mar 2009 12:44:31 +0100 Bernd Helmle wrote:

> --On Freitag, März 06, 2009 11:32:14 +0100 Andreas 'ads' Scherbaum
> <adsmail@wars-nicht.de> wrote:
>
> I don't see anything that's not already documented. is_valid() checks the
> presence of the invalid (!) marker only. It looks like the author never
> intended is_valid() to be a "check wether this ISBN is semantically
> correct", this is done by the input routines before.

So this function is useless. If the syntax is valid, the check is
already done and is_valid() returns true. If the syntax is invalid, PG
will raise an error even before this function returns. The invalid
marker is not checked at all.

This leads back to my initial question: intended behaviour or just a
bug? And how can one validate an ISBN without raising an error?


Bye

--             Andreas 'ads' Scherbaum
German PostgreSQL User Group
European PostgreSQL User Group - Board of Directors


Re: Validating problem in the isn contrib module

From
Gregory Stark
Date:
Andreas 'ads' Scherbaum <adsmail@wars-nicht.de> writes:

> So this function is useless. If the syntax is valid, the check is
> already done and is_valid() returns true. If the syntax is invalid, PG
> will raise an error even before this function returns. The invalid
> marker is not checked at all.

This seems pretty clearly explained in the documentation. 
 When you insert invalid numbers in a table using the weak mode, the number will be inserted with the corrected check
digit,but it will be displayed with an exclamation mark (!) at the end, for example 0-11-000322-5!. This invalid marker
canbe checked with the is_valid function and cleared with the make_valid function.
 
 You can also force the insertion of invalid numbers even when not in the weak mode, by appending the ! character at
theend of the number.
 

> This leads back to my initial question: intended behaviour or just a
> bug? And how can one validate an ISBN without raising an error?



--  Gregory Stark EnterpriseDB          http://www.enterprisedb.com Ask me about EnterpriseDB's 24x7 Postgres support!


Re: Validating problem in the isn contrib module

From
Tom Lane
Date:
"Andreas 'ads' Scherbaum" <adsmail@wars-nicht.de> writes:
> This leads back to my initial question: intended behaviour or just a
> bug? And how can one validate an ISBN without raising an error?

Judging from the comments, is_valid (and the internal validity bit)
were a bad design decision that the author later regretted, but felt
he couldn't change for compatibility reasons.  I'm not sure why not
... we make bigger incompatible changes than that all the time.

The way to validate an ISBN is exactly the same as it is for every
other data type: feed the string to the input function and see if
it throws an error.
        regards, tom lane


Re: Validating problem in the isn contrib module

From
Andreas 'ads' Scherbaum
Date:
On Fri, 06 Mar 2009 10:27:52 -0500 Tom Lane wrote:

> Judging from the comments, is_valid (and the internal validity bit)
> were a bad design decision that the author later regretted, but felt
> he couldn't change for compatibility reasons.  I'm not sure why not
> ... we make bigger incompatible changes than that all the time.

Looks a bit ugly and the way this module handles the input is unusual.


> The way to validate an ISBN is exactly the same as it is for every
> other data type: feed the string to the input function and see if
> it throws an error.

For the record here's a function which validates a text if it contains
an ISBN-13, similar functions are possible for the other datatypes
defined by isn:


CREATE OR REPLACE FUNCTION validate_isbn13(TEXT)         RETURNS BOOLEAN
AS $$
DECLARE isbn_nr ALIAS FOR $1; weak_status BOOLEAN; isbn_status BOOLEAN;
BEGIN
 -- make sure weak mode is off weak_status := isn_weak(FALSE); -- this will either return 'true' or throw an exception
isbn_status:= is_valid(isbn_nr::isbn13); weak_status := isn_weak(weak_status);
 
 RETURN isbn_status;
 EXCEPTION   -- handle (only) the exception which is thrown by is_valid()   WHEN invalid_text_representation THEN
RETURNfalse;
 
END;
$$
LANGUAGE 'plpgsql';


Bye

--             Andreas 'ads' Scherbaum
German PostgreSQL User Group
European PostgreSQL User Group - Board of Directors