I am using postgres 9.3 and trying to ensure that stored procedures are called in order when invoked from an sql statement. Does the following work (ensuring that foo() is called first and then bar())?
select null::void from (
select 1 from foo()
union select 1 from bar() ) _;
How about the following as well? [NB as it stands just a slightly more longer-winded version of the above -- what I'm after is whether in general CTEs will be executed in order of "invocation", in order of specification, or is it undefined?]
with x as ( select foo() ),
y as ( select bar() )
select null::void from ( select 1 from x union select 1 from y );
In addition to whether the proceeding work, is there a more idiomatic way to ensure execution order (with arbitrary/unimportant return values)? Perhaps just?
select null::void from ( select foo(), bar() ) _;
UPDATE -- to explain why:
What I'm hoping is that, if I specify my functions in sql, the optimizer can eliminate common subexpressions (etc), while keeping in order the parts that contain DDL. For instance, if foo, bar are
create function foo() returns void language sql as $$
with x as (select is_immutable())
select is_volatile(x.is_immutable) from x
$$;
create function bar() returns void language sql as $$
with x as (select is_immutable())
select is_volatile_2(x.is_immutable) from x
$$;
The optimizer will inline them in sql, and be able to factor out the call to is_immutable()
, while still keeping the volatile calls in order.
Punchline (if you don't want to read all of Craig's patient explanation)
The optimizer will inline "language sql" procedures, but it won't eliminate "common subexpressions" (or at least not in the way I was hoping). Thus, trying to affect order or execution within one statement, rather than use more than one statement, wouldn't be helpful, at least for what I was trying to accomplish. There is one trick listed below using CTEs that will work -- but as noted by @harmic in the comments, it might not work in future versions of postgres, and could introduce hard-to-find sporadic errors if this happens.... I'm not convinced that it would never be useful to control execution order, but Craig's advice to make sure you have a good reason before trying is certainly good.