[HACKERS] Why type coercion is not performed for parameters? - Mailing list pgsql-hackers

From Konstantin Knizhnik
Subject [HACKERS] Why type coercion is not performed for parameters?
Date
Msg-id ca994443-40ac-5e3f-d3b3-70e9d1590278@postgrespro.ru
Whole thread Raw
Responses Re: [HACKERS] Why type coercion is not performed for parameters?  (Marko Tiikkaja <marko@joh.to>)
Re: [HACKERS] Why type coercion is not performed for parameters?  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Hi hackers,

If I evaluate expression typename('literal'), then type coercion is 
performed and the function is successfully resolved, i.e.
    SELECT regnamespace('"pg_catalog"');

But if I want to prepare this query, I get the error:
    postgres=#  prepare foo as SELECT regnamespace($1);    ERROR:  function regnamespace(unknown) does not exist
LINE1: prepare foo as SELECT regnamespace($1);
 

Certainly, I can explicitly specify parameter type:
    prepare foo (text) as SELECT regnamespace($1);

and it will work. But it is not always possible.

Actually coerce_type function can normally handle parameters.
But func_get_detail always allows coercion only for constants:

                if (sourceType == UNKNOWNOID && IsA(arg1, Const))                {                    /* always treat
typename('literal')as coercion */                    iscoercion = true;                }
 

If this condition is changed to:
                if (sourceType == UNKNOWNOID && (IsA(arg1, Const) || 
IsA(arg1, Param)))

then the example above will normally work.

Why do I need it? I want to implement autoprepare.
My original intention was to let parse_analyze_varparams to infer type 
of parameters from the context.
But it is not always possible  and sometime leads to different behavior 
of query.
For example if the query:
     select count(*) from test_range_gist where ir @> 10;

is replaced with
     select count(*) from test_range_gist where ir @> $1;

then type of parameter will be int4range rather then int, which 
corresponds to the different operator.

This is why now I infer parameter type from literal value. But in this 
case I get errors in parse_analyze_varparams which is not able to 
resolve some functions.
The fix in func_get_detail functions solves the problem and doesn't 
cause some new issues: all regression tests are passed.

So my question is whether it is possible to use the same rule for type 
coercion of parameters as for constant?

-- 
Konstantin Knizhnik
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company




pgsql-hackers by date:

Previous
From: Paresh More
Date:
Subject: Re: [HACKERS] Patch - Tcl 8.6 version support for PostgreSQL
Next
From: Michael Paquier
Date:
Subject: Re: [HACKERS] logical replication and PANIC during shutdowncheckpoint in publisher