Received: from maia.hub.org (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 049B66330E3 for ; Thu, 14 Jan 2010 10:26:41 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 13666-02 for ; Thu, 14 Jan 2010 14:26:30 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mail-pz0-f201.google.com (mail-pz0-f201.google.com [209.85.222.201]) by mail.postgresql.org (Postfix) with ESMTP id 4AFE16325DE for ; Thu, 14 Jan 2010 10:26:29 -0400 (AST) Received: by pzk39 with SMTP id 39so387455pzk.15 for ; Thu, 14 Jan 2010 06:26:27 -0800 (PST) MIME-Version: 1.0 Received: by 10.142.8.12 with SMTP id 12mr612097wfh.70.1263479187765; Thu, 14 Jan 2010 06:26:27 -0800 (PST) In-Reply-To: <162867791001140054w2f383578v7b59b5545310f21f@mail.gmail.com> References: <201001131910.o0DJArAo086208@wwwmaster.postgresql.org> <162867791001140054w2f383578v7b59b5545310f21f@mail.gmail.com> Date: Thu, 14 Jan 2010 15:26:27 +0100 Message-ID: <3eff28921001140626v2f5d5957l10853bd3fa37d4e9@mail.gmail.com> Subject: Re: BUG #5274: [PL/PgSQL] EXECUTE ... USING variable expansion From: Vincenzo Romano To: Pavel Stehule Cc: pgsql-bugs@postgresql.org Content-Type: text/plain; charset=ISO-8859-1 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.589 tagged_above=-10 required=5 tests=BAYES_00=-2.599, FH_DATE_PAST_20XX=3.188 X-Spam-Level: X-Archive-Number: 201001/129 X-Sequence-Number: 25633 2010/1/14 Pavel Stehule : > 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 Documentation (v8.*) clearly states that you cannot use the placeholders for table and column names. What I'm reporting here is that even: EXECUTE 'ALTER TABLE test ALTER COLUMN i SET DEFAULT $1' USING 42; is complaining with: ERROR: there is no parameter $1 CONTEXT: SQL statement "ALTER TABLE test ALTER COLUMN i SET DEFAULT $1" while: EXECUTE 'SELECT $1' USING 42; works. There's no variable, just a constant value. The usefulness of the EXECUTE USING is thus dramatically reduced. Also because the documentation reports something really meaningful and reasonable: The command string can use parameter values, which are referenced in the command as $1, $2, etc. These symbols refer to values supplied in the USING clause. This method is often preferable to inserting data values into the command string as text: it avoids run-time overhead of converting the values to text and back, and it is much less prone to SQL-injection attacks since there is no need for quoting or escaping. (http://www.postgresql.org/files/documentation/pdf/8.4/postgresql-8.4.2-A4.pdf page 800 or http://www.postgresql.org/docs/8.4/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN "38.5.4. Executing Dynamic Commands") -- Vincenzo Romano NotOrAnd Information Technologies NON QVIETIS MARIBVS NAVTA PERITVS