From: | Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> |
---|---|
To: | Vincenzo Romano <vincenzo(dot)romano(at)notorand(dot)it> |
Cc: | pgsql-bugs(at)postgresql(dot)org |
Subject: | Re: BUG #5274: [PL/PgSQL] EXECUTE ... USING variable expansion |
Date: | 2010-01-14 08:54:41 |
Message-ID: | 162867791001140054w2f383578v7b59b5545310f21f@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
Hello
it is not bug.
DDL statements like CREATE TABLE, ALTER TABLE are doesn't support
parametrisation - you cannot use a placeholder for parameter
everywhere. So you cannot to write PQexecParams(..."ALTER TABLE test
ALTER COLUMN $1 ...", ...), so it cannot be supported by EXECUTE
USING. Parameters are available only for DML statements - for
statements with execution plan. You can store a plan and you can call
stored plan with different parameters - it means - parameter cannot be
a SQL identifier - like column or table name, because this changes a
plan.
so
you can do
EXECUTE 'SELECT * FROM tab WHERE col = $1' USING var1
but you cannot do:
EXECUTE 'SELECT * FROM $1 WHERE col = 10' USING var1, because SELECT
FROM tab1 or SELECT FROM tab2 needs different execution plans. You
cannot do too:
EXECUTE 'CREATE TABLE $1' USING var1, bacause CREATE TABLE is DDL
statement without plan, and without possibility to use a parameters.
You have to do:
EXECUTE 'SELECT * FROM ' || var1::regclass || ' WHERE col=10' --
var1::regclass is minimum protection against SQL injection
EXECUTE 'CREATE TABLE '|| quote_ident(var1) || '(....
Regards
Pavel Stehule
2010/1/13 Vincenzo Romano <vincenzo(dot)romano(at)notorand(dot)it>:
>
> The following bug has been logged online:
>
> Bug reference: 5274
> Logged by: Vincenzo Romano
> Email address: vincenzo(dot)romano(at)notorand(dot)it
> PostgreSQL version: 8.4.2
> Operating system: Linux
> Description: [PL/PgSQL] EXECUTE ... USING variable expansion
> Details:
>
> My system says:
> ~ lsb_release -a
> LSB Version:
> :core-3.1-amd64:core-3.1-noarch:core-3.2-amd64:core-3.2-noarch:desktop-3.1-a
> md64:desktop-3.1-noarch:desktop-3.2-amd64:desktop-3.2-noarch
> Distributor ID: Fedora
> Description: Fedora release 12 (Constantine)
> Release: 12
> Codename: Constantine
>
> If you try the following:
>
> CREATE TABLE test ( i INT );
>
> CREATE OR REPLACE FUNCTION func()
> RETURNS void
> LANGUAGE plpgsql
> AS $function$
> DECLARE
> e TEXT;
> t TEXT;
> i INT;
> BEGIN
> i := 42;
> t := 'answer';
> EXECUTE 'SELECT $1' INTO e USING t;
> RAISE INFO '%',e;
> EXECUTE 'ALTER TABLE test ALTER COLUMN i SET DEFAULT $1' USING i;
> END;
> $function$;
>
> SELECT func();
>
> The first EXECUTE...USING replaces the variable $1 with the value of the
> variable "t". The first output line reads:
>
> INFO: answer
>
> The second EXECUTE...USING doesn't do the replacement and triggers an
> error:
>
> ERROR: there is no parameter $1
> CONTEXT: SQL statement "ALTER TABLE test ALTER COLUMN i SET DEFAULT $1"
> PL/pgSQL function "func" line 10 at EXECUTE statement
>
> --
> Sent via pgsql-bugs mailing list (pgsql-bugs(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-bugs
>
From | Date | Subject | |
---|---|---|---|
Next Message | louis | 2010-01-14 11:06:23 | BUG #5277: plperl can't get args properly |
Previous Message | Tom Lane | 2010-01-14 05:37:01 | Re: Termination When Switching between PL/Perl and PL/PerlU |