Thread: bad variable subst after "AS"

bad variable subst after "AS"

From
Darren Duncan
Date:
I don't know if this is a bug or not, but if not, it looks like a misfeature ...

When executing the following in Pg 8.4.4:
  CREATE OR REPLACE FUNCTION f () RETURNS TABLE(a1 INTEGER) AS  $BODY$  BEGIN    RETURN QUERY SELECT a0 AS a1 FROM rv;
 RETURN;  END;  $BODY$  LANGUAGE plpgsql;
 

... I get this error:
  ERROR: syntax error at or near "$1"  SQL state: 42601

My impression of this is that Pg is treating the "a1" after the "AS" like it was
a variable reference and so substituted it for $1.

Now that just seems wrong to me.  I can understand either "a0" or "rv" getting a
substitution, but something following an "AS" being substituted is just wrong.

Is that a bug and if not then what is the rationale for working that way, and
can it be changed?

Meanwhile, what is the best way to write f to work around this misbehavior?

Thank you.

-- Darren Duncan



Re: bad variable subst after "AS"

From
Pavel Stehule
Date:
Hello

2010/9/16 Darren Duncan <darren@darrenduncan.net>:
> I don't know if this is a bug or not, but if not, it looks like a misfeature
> ...
>
> When executing the following in Pg 8.4.4:
>
>  CREATE OR REPLACE FUNCTION f () RETURNS TABLE(a1 INTEGER) AS
>  $BODY$
>  BEGIN
>    RETURN QUERY SELECT a0 AS a1 FROM rv;
>    RETURN;
>  END;
>  $BODY$
>  LANGUAGE plpgsql;
>

It's not a bug - just you cannot use a variable there. Table name,
column names are specified in planner time, and cannot be
parametrized.

Regards

Pavel Stehule

p.s. you can use a dynamic SQL - EXECUTE statement - RETURN QUERY
EXECUTE - but it doesn't help you, because you cannot overwrite a
function definition.

> ... I get this error:
>
>  ERROR: syntax error at or near "$1"
>  SQL state: 42601
>
> My impression of this is that Pg is treating the "a1" after the "AS" like it
> was
> a variable reference and so substituted it for $1.
>
> Now that just seems wrong to me.  I can understand either "a0" or "rv"
> getting a
> substitution, but something following an "AS" being substituted is just
> wrong.
>
> Is that a bug and if not then what is the rationale for working that way,
> and
> can it be changed?
>
> Meanwhile, what is the best way to write f to work around this misbehavior?
>
> Thank you.
>
> -- Darren Duncan
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
>


Re: bad variable subst after "AS"

From
Heikki Linnakangas
Date:
On 16/09/10 09:33, Darren Duncan wrote:
> I don't know if this is a bug or not, but if not, it looks like a
> misfeature ...
>
> When executing the following in Pg 8.4.4:
>
> CREATE OR REPLACE FUNCTION f () RETURNS TABLE(a1 INTEGER) AS
> $BODY$
> BEGIN
> RETURN QUERY SELECT a0 AS a1 FROM rv;
> RETURN;
> END;
> $BODY$
> LANGUAGE plpgsql;
>
> ... I get this error:
>
> ERROR: syntax error at or near "$1"
> SQL state: 42601
>
> My impression of this is that Pg is treating the "a1" after the "AS"
> like it was
> a variable reference and so substituted it for $1.
>
> Now that just seems wrong to me. I can understand either "a0" or "rv"
> getting a
> substitution, but something following an "AS" being substituted is just
> wrong.
>
> Is that a bug and if not then what is the rationale for working that
> way, and
> can it be changed?

It's a known misfeature, PL/pgSQL isn't very smart about replacing 
variables with parameter markers.

The good news is that this has been completely rewritten in 9.0. The 
above will work in 9.0.
> Meanwhile, what is the best way to write f to work around this 
misbehavior?

If you can't upgrade to 9.0, you'll have to rename the variable or use a 
different alias in the AS clause.

--   Heikki Linnakangas  EnterpriseDB   http://www.enterprisedb.com


Re: bad variable subst after "AS"

From
Andrew Dunstan
Date:

On 09/16/2010 02:33 AM, Darren Duncan wrote:
> I don't know if this is a bug or not, but if not, it looks like a 
> misfeature ...
>
> When executing the following in Pg 8.4.4:
>
>   CREATE OR REPLACE FUNCTION f () RETURNS TABLE(a1 INTEGER) AS
>   $BODY$
>   BEGIN
>     RETURN QUERY SELECT a0 AS a1 FROM rv;
>     RETURN;
>   END;
>   $BODY$
>   LANGUAGE plpgsql;
>
> ... I get this error:
>
>   ERROR: syntax error at or near "$1"
>   SQL state: 42601
>
> My impression of this is that Pg is treating the "a1" after the "AS" 
> like it was
> a variable reference and so substituted it for $1.
>
> Now that just seems wrong to me.  I can understand either "a0" or "rv" 
> getting a
> substitution, but something following an "AS" being substituted is 
> just wrong.
>
> Is that a bug and if not then what is the rationale for working that 
> way, and
> can it be changed?
>
> Meanwhile, what is the best way to write f to work around this 
> misbehavior?
>
> Thank you.
>

Remove the AS clause. You don't need it here at all.

cheers

andrew


Re: bad variable subst after "AS"

From
Alvaro Herrera
Date:
Excerpts from Darren Duncan's message of jue sep 16 02:33:37 -0400 2010:

> My impression of this is that Pg is treating the "a1" after the "AS" like it was
> a variable reference and so substituted it for $1.

Yes.

> Now that just seems wrong to me.  I can understand either "a0" or "rv" getting a
> substitution, but something following an "AS" being substituted is just wrong.
> 
> Is that a bug and if not then what is the rationale for working that way, and
> can it be changed?

Fixed in 9.0.

> Meanwhile, what is the best way to write f to work around this misbehavior?

Give the column a different alias, one not colliding with a variable name.

-- 
Álvaro Herrera <alvherre@commandprompt.com>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support


Re: bad variable subst after "AS"

From
Darren Duncan
Date:
Thank you to the 4 people who replied.

Heikki Linnakangas wrote:
> It's a known misfeature, PL/pgSQL isn't very smart about replacing variables with parameter markers.
> 
> The good news is that this has been completely rewritten in 9.0. The above will work in 9.0.
> 
> If you can't upgrade to 9.0, you'll have to rename the variable or use a different alias in the AS clause.

Good to hear that this is fixed in 9.0; and I do intend to upgrade any week now.

Andrew Dunstan wrote:
> Remove the AS clause. You don't need it here at all.

Okay, that seems to be the best workaround while running under 8.4; or I would 
use something like _a1 instead for documentation purposes or for referencing.

Alvaro Herrera wrote:
>> Meanwhile, what is the best way to write f to work around this misbehavior?
> 
> Give the column a different alias, one not colliding with a variable name.

In this circumstance, the whole point of the AS clause is, because I was 
declaring in the function signature that it exported a table with a column named 
a1, I used the AS clause to make sure the selected column was named a1, else 
conceptually there would be a type mismatch between declared and actual result.  Making them exactly the same is the
wholepoint of the exercise.
 

I'm in the school of thought that a table column's name is the only proper way 
to identify it, rather than the ordinal position being significant for identity, 
so even though SQL supports the latter, I consider it a misfeature of SQL that 
leads to error-prone code, and try to not rely on it when I can help it.

The fact that Pg would make things work when the result column name is different 
than the declared name points squarely to ordinal position as identity, as 
that's the only way it could work.

Considering that behavior, I agree that using a different name is reasonable 
under 8.4 to make this work.

Pavel Stehule said:
> It's not a bug - just you cannot use a variable there. Table name,
> column names are specified in planner time, and cannot be
> parametrized.
> 
> p.s. you can use a dynamic SQL - EXECUTE statement - RETURN QUERY
> EXECUTE - but it doesn't help you, because you cannot overwrite a
> function definition.

I think you misunderstood what I was trying to do.  In contrast to what you 
said, I was *not* expecting the a1 in "AS a1" to be treated as a variable.  But 
no worries; Heikki/Andrew/Alvaro understood what I meant.

-- Darren Duncan