Bound parameters in escaped functions

From: Grant Shirreffs <GShirreffs(at)stayinfront(dot)com>
To: "pgsql-odbc(at)lists(dot)postgresql(dot)org" <pgsql-odbc(at)lists(dot)postgresql(dot)org>
Subject: Bound parameters in escaped functions
Date: 2019-05-14 03:58:52
Message-ID: CY4PR18MB1079433ABC03436BFE934628CF080@CY4PR18MB1079.namprd18.prod.outlook.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-odbc

Hello,

I have found a bug in the translation of '?' parameters in escaped ODBC functions.

Where there is an escaped ODBC function within another, for example:

CASE WHEN {fn LENGTH({fn LTRIM(Name || ?))=? [...]

During convert_escape (convert.c:5471), at line 5626 the QueryBuild object is copied to a local temporary ('ncb'), which is then passed to 'processParameters', which then calls recursively back into convert_escape for the inner function.

Then, at line 5771, the parameter number from ncb is passed back into the original QueryBuild, so that query processing carries on successfully. However, crucially, the dollar_number value from ncb, which has been incremented while processing the parameters inside the function, is not passed back. So although the parameters themselves are correctly handled, the incorrect PostgreSQL placeholder symbol is generated.

In the example above, the resulting SQL is:

CASE WHEN LENGTH(LTRIM(Name || $1))=$1::int4 [...]

Where it should of course be:

CASE WHEN LENGTH(LTRIM(Name) || $1))=$2:int4

The fix is to copy the dollar_number back from ncb to the original QueryBuild:

if (SQL_ERROR != retval)
{
qb->param_number = nqb.param_number;
qb->dollar_number = nqb.dollar_number;
qb->flags = nqb.flags;
}

Responses

Browse pgsql-odbc by date

  From Date Subject
Next Message Grant Shirreffs 2019-05-15 04:03:14 SQLGetInfo
Previous Message Inoue, Hiroshi 2019-05-05 10:57:51 Re: Root certificate not found