Re: [GENERAL] invalid regular expression: invalid backreference number

2007-02-18 Thread Tom Lane
Jeff Ross <[EMAIL PROTECTED]> writes:
> To debug this I've extracted the code into its own function:

> CREATE FUNCTION gen_password() RETURNS text AS $$
> DECLARE
>   password text;
>   chars := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
> BEGIN

You forgot to give a type for the "chars" variable.

> psql:create_password.sql:12: ERROR:  invalid type name ""
> CONTEXT:  compile of PL/pgSQL function "gen_password" near line 3

I agree that this is a pretty awful error message :-( ... will take a
look at whether it can be improved.

regards, tom lane

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [GENERAL] invalid regular expression: invalid backreference number

2007-02-18 Thread Stephan Szabo
On Sun, 18 Feb 2007, Jeff Ross wrote:

> Tom Lane wrote:
> >
> > Since ceil() produces float8 which does not implicitly cast to int,
> > this call has probably never done what you thought --- AFAICS it will
> > cast all the arguments to text and invoke substring(text,text,text)
> > which treats its second argument as a SQL99 regular expression.
> > I doubt that it's useful to figure out exactly what changed to make
> > it fail more obviously than before --- I think the problem is that
> > you'd better cast the ceil() result to int.
> >
> > [ObRant: still another example of why implicit casts to text are evil.]
> >
> To debug this I've extracted the code into its own function:
>
>
> CREATE FUNCTION gen_password() RETURNS text AS $$
> DECLARE
>   password text;
>   chars := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
> BEGIN
>   FOR i IN 1..9 LOOP
> password := password || SUBSTRING(chars,
> ceil(random()*LENGTH(chars))::int, 1);
>   END LOOP;
>   return password;
> END;
> $$
> LANGUAGE plpgsql;
>
>
> when I try to generate the function with this I get the following error:
>
> psql -f create_password.sql wykids
> psql:create_password.sql:12: LOG:  statement: CREATE FUNCTION
> gen_password() RETURNS text AS $$
> DECLARE
> password text;
> chars :=
[snipped]
> psql:create_password.sql:12: ERROR:  invalid type name ""
> CONTEXT:  compile of PL/pgSQL function "gen_password" near line 3

Given the context and function, I'd say it's complaining because you
didn't put a type after chars and before the := for the initializer.
Changing it to chars text := ... should make that work.
In addition, the default initialized value for password will be a NULL
which probably won't do what you want either, since NULL || something is
NULL, so you probably want password text := '' there.

---(end of broadcast)---
TIP 9: In versions below 8.0, the planner will ignore your desire to
   choose an index scan if your joining column's datatypes do not
   match


Re: [GENERAL] invalid regular expression: invalid backreference number

2007-02-18 Thread Jeff Ross

Tom Lane wrote:

Thanks for the reply, Tom.

Jeff Ross <[EMAIL PROTECTED]> writes:
  

This used to work before my upgrade to 8.2.1.



Which version were you using before?

  

8.1.x

The error the function now throws is:



  
ERROR:  invalid regular expression: invalid backreference 
number
2007-02-15 15:32:57.264729500 CONTEXT:  SQL function 
"substring" statement 1
2007-02-15 15:32:57.264730500   PL/pgSQL function "set_people" line 58 
at assignment



You could have helped us out by mentioning exactly which line was line
58 ... but I'm guessing it's this one:

  

Sorry, my bad, but you guessed right.
   gen_pp_password := gen_pp_password || SUBSTRING(chars, 
ceil(random()*LENGTH(chars)), 1);2007-02-15 15:32:57.264727500



Since ceil() produces float8 which does not implicitly cast to int,
this call has probably never done what you thought --- AFAICS it will
cast all the arguments to text and invoke substring(text,text,text)
which treats its second argument as a SQL99 regular expression.
I doubt that it's useful to figure out exactly what changed to make
it fail more obviously than before --- I think the problem is that
you'd better cast the ceil() result to int.

[ObRant: still another example of why implicit casts to text are evil.]

regards, tom lane

  

To debug this I've extracted the code into its own function:


CREATE FUNCTION gen_password() RETURNS text AS $$
DECLARE
 password text;
 chars := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
BEGIN
 FOR i IN 1..9 LOOP
   password := password || SUBSTRING(chars, 
ceil(random()*LENGTH(chars))::int, 1);

 END LOOP;
 return password;
END;
$$
LANGUAGE plpgsql;


when I try to generate the function with this I get the following error:

psql -f create_password.sql wykids
psql:create_password.sql:12: LOG:  statement: CREATE FUNCTION 
gen_password() RETURNS text AS $$

DECLARE
   password text;
   chars := 
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';

BEGIN
   FOR i IN 1..9 LOOP
   password := password || SUBSTRING(chars, 
ceil(random()*LENGTH(chars))::int, 1);

   END LOOP;
   return password;
END;
$$
LANGUAGE plpgsql;
psql:create_password.sql:12: ERROR:  invalid type name ""
CONTEXT:  compile of PL/pgSQL function "gen_password" near line 3

I've not been able to figure out this error message at all, and google 
hasn't been any help either.  I'm only now learning functions (I 
inherited the one that used to work) so if someone can point me in the 
general direction I sure would appreciate it.


Thanks,

Jeff Ross



---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [GENERAL] invalid regular expression: invalid backreference number

2007-02-16 Thread Tom Lane
Jeff Ross <[EMAIL PROTECTED]> writes:
> This used to work before my upgrade to 8.2.1.

Which version were you using before?

> The error the function now throws is:

> ERROR:  invalid regular expression: invalid backreference 
> number
> 2007-02-15 15:32:57.264729500 CONTEXT:  SQL function 
> "substring" statement 1
> 2007-02-15 15:32:57.264730500   PL/pgSQL function "set_people" line 58 
> at assignment

You could have helped us out by mentioning exactly which line was line
58 ... but I'm guessing it's this one:

>gen_pp_password := gen_pp_password || SUBSTRING(chars, 
> ceil(random()*LENGTH(chars)), 1);2007-02-15 15:32:57.264727500

Since ceil() produces float8 which does not implicitly cast to int,
this call has probably never done what you thought --- AFAICS it will
cast all the arguments to text and invoke substring(text,text,text)
which treats its second argument as a SQL99 regular expression.
I doubt that it's useful to figure out exactly what changed to make
it fail more obviously than before --- I think the problem is that
you'd better cast the ceil() result to int.

[ObRant: still another example of why implicit casts to text are evil.]

regards, tom lane

---(end of broadcast)---
TIP 6: explain analyze is your friend


[GENERAL] invalid regular expression: invalid backreference number

2007-02-15 Thread Jeff Ross
I've got a function that generates usernames and passwords on insert if 
they haven't yet been set.  The code block is:


  -- create a new username for new people
  IF (LENGTH(COALESCE(new_pp_username, '')) = 0) THEN
LOOP
  gen_pp_username := LOWER(SUBSTRING(new_pp_first_name from 1 for 
2)) || LOWER(SUBSTRING(new_pp_last_name from 1 for 8)) || 
round(random()*100);

  gen_pp_username := regexp_replace(gen_pp_username, E'\\W', '', 'g');
  EXIT WHEN ((SELECT COUNT(*) FROM people WHERE pp_username = 
gen_pp_username AND pp_provisional_p='f') = 0);

END LOOP;
  ELSE
gen_pp_username := new_pp_username;
  END IF;

  -- create a new password if there is none
  IF (LENGTH(COALESCE(new_pp_password, '')) = 0) THEN
chars := 
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';

FOR i in 1..8 LOOP
  gen_pp_password := gen_pp_password || SUBSTRING(chars, 
ceil(random()*LENGTH(chars)), 1);2007-02-15 15:32:57.264727500

END LOOP;
  ELSE
gen_pp_password := new_pp_password;
  END IF;

This used to work before my upgrade to 8.2.1.

The error the function now throws is:

ERROR:  invalid regular expression: invalid backreference 
number
2007-02-15 15:32:57.264729500 CONTEXT:  SQL function 
"substring" statement 1
2007-02-15 15:32:57.264730500   PL/pgSQL function "set_people" line 58 
at assignment


I've futzed around with the various ways I can call substring, but I 
don't understand why this is throwing the error.


Any help would be greatly appreciated!

Jeff Ross

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly