Thread: function prepared plan

function prepared plan

From
Franco Bruno Borghesi
Date:
Hi everyone! I have a little problem, and was wondering if anyone could help me. 
I've created a simplified working example to show you what's going on:

//table with data
CREATE TABLE testTable (  intValue INTEGER,  textValue TEXT
);
INSERT INTO testTable VALUES (1, 'one');
INSERT INTO testTable VALUES (2, 'two');
INSERT INTO testTable VALUES (3, 'three');
INSERT INTO testTable VALUES (4, 'four');

//type used by my "test()" function to return the data
CREATE TYPE myType AS (  value TEXT
);

//function that returns a set records of type "myType"
CREATE OR REPLACE FUNCTION test(BOOLEAN) RETURNS SETOF myType AS '
DECLARE  flag ALIAS FOR $1;  mt myType%ROWTYPE;  r RECORD;
BEGIN  FOR r IN     EXECUTE testSQL(flag)  LOOP     mt.value:=CAST(r.value AS TEXT);     RETURN NEXT mt;  END LOOP;
RETURNNULL;
 
END;
' LANGUAGE 'plpgsql';


//function that dynamically generates a query for my "test()" function
CREATE OR REPLACE FUNCTION testSQL(BOOLEAN) RETURNS TEXT AS '
DECLARE  flag ALIAS FOR $1;  result TEXT;
BEGIN  IF (flag) THEN     result:=''SELECT textValue AS value FROM testTable'';  ELSE     result:=''SELECT intValue AS
valueFROM testTable'';  END IF;
 
  RETURN result;
END;
' LANGUAGE 'plpgsql';

//try the function
franco=# SELECT * FROM test(true);value
-------onetwothreefour
(4 rows)

//try it again 
franco=# SELECT * FROM test(false);
WARNING:  Error occurred while executing PL/pgSQL function test
WARNING:  line 9 at assignment
ERROR:  type of r.value doesn't match that when preparing the plan

Of course if y reconnect to the database:
franco=# SELECT * FROM test(false);value
-------1234
(4 rows)

franco=# SELECT * FROM test(true);
WARNING:  Error occurred while executing PL/pgSQL function test
WARNING:  line 9 at assignment
ERROR:  type of r.value doesn't match that when preparing the plan

does anyone know if there is any way to unprepare the plan between queries? I don't care about performance, 
so re-preparing the plan every time is ok for me.

Thanks in advance.

PS: I know the example doesn't make much sense, but in the real life case it does.






Re: function prepared plan

From
Tom Lane
Date:
Franco Bruno Borghesi <franco@akyasociados.com.ar> writes:
> Hi everyone! I have a little problem, and was wondering if anyone
> could help me.

Change the EXECUTEd query strings so that all the variants return TEXT,
instead of trying to cast after-the-fact.

If that doesn't seem reasonable, you might be better off working in
pltcl.  plpgsql is designed on the assumption that it can cache query
plans from one execution to the next, which is a good speed optimization
but does require a certain amount of stability of datatypes.  If you'd
prefer to kiss off speed for flexibility, pltcl is your tool.

plpython might work too, but I'm not very familiar with it and couldn't
say for certain.
        regards, tom lane


Re: function prepared plan

From
Franco Bruno Borghesi
Date:
Ok Tom, I'll try casting in the testSQL function like you said... but let me ask you another thing: 
what is plpgsql exactily caching?

I mean, in the real case, the testSQL function receives about 10 arguments, and based on theese 
arguments the function generates the SQL string with very diferent grouping criterias, joins and orders.

If plpgsql is caching the plan, I don't think the same plan will work with diferent parameters. Will just
casting datatypes do the work? Or should I directly use plctl?

Thanks.


On Wednesday 21 May 2003 23:45, you wrote:
> Franco Bruno Borghesi <franco@akyasociados.com.ar> writes:
> > Hi everyone! I have a little problem, and was wondering if anyone
> > could help me.
>
> Change the EXECUTEd query strings so that all the variants return TEXT,
> instead of trying to cast after-the-fact.
>
> If that doesn't seem reasonable, you might be better off working in
> pltcl.  plpgsql is designed on the assumption that it can cache query
> plans from one execution to the next, which is a good speed optimization
> but does require a certain amount of stability of datatypes.  If you'd
> prefer to kiss off speed for flexibility, pltcl is your tool.
>
> plpython might work too, but I'm not very familiar with it and couldn't
> say for certain.
>
>             regards, tom lane



Re: function prepared plan

From
Tom Lane
Date:
Franco Bruno Borghesi <franco@akyasociados.com.ar> writes:
> Ok Tom, I'll try casting in the testSQL function like you said... but let me ask you another thing: 
> what is plpgsql exactily caching?

The plan for the "CAST(foo AS TEXT)" expression.  Under the hood that's
a SELECT CAST($1 AS TEXT), and it has a plan.
        regards, tom lane


Re: function prepared plan

From
Franco Bruno Borghesi
Date:
That's great! I'll cast everything then.

Thanks Tom.

On Thursday 22 May 2003 12:15, Tom Lane wrote:
> Franco Bruno Borghesi <franco@akyasociados.com.ar> writes:
> > Ok Tom, I'll try casting in the testSQL function like you said... but let
> > me ask you another thing: what is plpgsql exactily caching?
>
> The plan for the "CAST(foo AS TEXT)" expression.  Under the hood that's
> a SELECT CAST($1 AS TEXT), and it has a plan.
>
>             regards, tom lane