Text-any concatenation volatility acting as optimization barrier - Mailing list pgsql-hackers

From Marti Raudsepp
Subject Text-any concatenation volatility acting as optimization barrier
Date
Msg-id CABRT9RBKy-OAjaxWMFMRSaj=1+4_=vmaTeCBbi2BJ-s195Fdyw@mail.gmail.com
Whole thread Raw
Responses Re: Text-any concatenation volatility acting as optimization barrier  (Andrew Dunstan <andrew@dunslane.net>)
Re: Text-any concatenation volatility acting as optimization barrier  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Hi list,

Andrew Dunstan reported an awkward-seeming case on IRC where shifting
around a concatenation expression in a view made the planner choose a
good or a bad execution plan.

Simplified, it boils down to this:

db=# create table foo(i int);
db=# explain verbose select i from (select i, i::text || 'x' as asd
from foo) as subq;
Seq Scan on public.foo  (cost=0.00..34.00 rows=2400 width=4) Output: foo.i

db=# explain verbose select i from (select i, i || 'x'::text as asd
from foo) as subq;
Subquery Scan on subq  (cost=0.00..76.00 rows=2400 width=4) Output: subq.i ->  Seq Scan on public.foo
(cost=0.00..52.00rows=2400 width=4)       Output: foo.i, ((foo.i)::text || 'x'::text)
 

Case #1 uses the normal textcat(text, text) operator by automatically
coercing 'x' as text.
However, case #2 uses the anytextcat(anynonarray, text), which is
marked as volatile thus acts as an optimization barrier. Later, the
anytextcat SQL function is inlined and the EXPLAIN VERBOSE output has
no trace of what happened.

Is this something we can, or want, to fix?

One way would be doing preprocess_expression() before
pull_up_subqueries() so function inlining happens earlier, but I can't
imagine what unintended consequences that might have.

Another option would be creating explicit immutable  text || foo
operators for common types, but that sounds pretty hacky.

Regards,
Marti


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: When do we lose column names?
Next
From: Bruce Momjian
Date:
Subject: Re: random_page_cost vs seq_page_cost