> adrian.kla...@aklaver.com wrote:
> 
>> Bryn wrote:
>> 
>>> mmonc...@gmail.com wrote:
>>> 
>>> SQL language functions have one clear advantage in that they can be inlined 
>>> in narrow contexts; this can give dramatic performance advantages when it 
>>> occurs. They have a lot of disadvantages:
>>> 
>>> (1) Tables can’t be created then used without turning off function body 
>>> evaluation.
>>> 
>>> (2) Queries must be parsed and planned upon each evocation (this can be 
>>> construed as advantage in scenarios where you want to float a function over 
>>> schemas).
>>> 
>>> (3) Generally constrained to basic SQL statements (no variables, logic etc).
>>> 
>>> …simplifies down to, “use SQL functions [only] when inlining”.
>> 
>> About your point #1, I used a procedure to test this… I started with a 
>> working “language plpgsql” example… Then I changed it to a “language sql” 
>> test:
>> 
>> drop table if exists t cascade;
>> drop procedure if exists p() cascade;
>> create procedure p()
>>   language sql
>> as $body$
>>   drop table if exists t cascade;
>>   create table t(k int primary key, v text not null);
>>   -- Causes compilation error: 42P01: relation "t" does not exist
>>   -- insert into t(k, v) values (1, 'dog'), (2, 'cat'), (3, 'frog');
>> $body$;
>> 
>> With the “insert” in place, it fails the syntax check with the error that I 
>> mentioned. When it’s commented out, it passes the syntax check and executes 
>> without error and has the expected effect.
> 
> Which is documented:
> 
> https://www.postgresql.org/docs/current/xfunc-sql.html 
> <https://www.postgresql.org/docs/current/xfunc-sql.html>
> 
> «
> Note
> 
> The entire body of an SQL function is parsed before any of it is executed. 
> While an SQL function can contain commands that alter the system catalogs 
> (e.g., CREATE TABLE), the effects of such commands will not be visible during 
> parse analysis of later commands in the function. Thus, for example, CREATE 
> TABLE foo (...); INSERT INTO foo VALUES(...); will not work as desired if 
> packaged up into a single SQL function, since foo won't exist yet when the 
> INSERT command is parsed. It's recommended to use PL/pgSQL instead of an SQL 
> function in this type of situation.
> »
> 
>> Bryn continued:
>> 
>> The upshot of this is that I can’t design a test to demonstrate the effect 
>> that I thought you meant. Could you show me a code example, please?
> 
> To turn off function body evaluation:
> 
> https://www.postgresql.org/docs/current/runtime-config-client.html
> 
> «
> check_function_bodies (boolean)
> 
> This parameter is normally on. When set to off, it disables validation of the 
> routine body string during CREATE FUNCTION and CREATE PROCEDURE. Disabling 
> validation avoids side effects of the validation process, in particular 
> preventing false positives due to problems such as forward references. Set 
> this parameter to off before loading functions on behalf of other users; 
> pg_dump does so automatically.
> »

Thanks for those doc URLs, Adrian. Very helpful. I’ll do some serious reading 
and testing.

Reply via email to