Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1U84th-0005fY-E7 for pgsql-sql@arkaria.postgresql.org; Wed, 20 Feb 2013 08:19:25 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.72) (envelope-from ) id 1U84tg-0002n3-UM for pgsql-sql@arkaria.postgresql.org; Wed, 20 Feb 2013 08:19:24 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1U84tf-0002mV-PD for pgsql-sql@postgresql.org; Wed, 20 Feb 2013 08:19:24 +0000 Received: from isis.morrow.me.uk ([204.109.63.142]) by magus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1U84ta-0004vG-CN for pgsql-sql@postgresql.org; Wed, 20 Feb 2013 08:19:22 +0000 Received: from anubis.morrow.me.uk (host109-150-212-220.range109-150.btcentralplus.com [109.150.212.220]) (Authenticated sender: mauzo) by isis.morrow.me.uk (Postfix) with ESMTPSA id A5D46450C8; Wed, 20 Feb 2013 08:19:15 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.7.4 isis.morrow.me.uk A5D46450C8 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=morrow.me.uk; s=dkim201101; t=1361348356; bh=T3vgb0LK6Wwgr4/1DPYTS2Ng4kqs7AbFKngF43Xvn3g=; h=Date:From:To:Subject:References:In-Reply-To; b=y+xRgKrWdhBQDfbFH76l+KlQJu6AtPibrpZoC4RNPHb/g+7+erZVFebmczUKCN8qh 1osXAFxHUxFcr9mWeNGOBrDIEyVY+ktSSrw+7s8xJet0f2E8AWwxq3UygYpCm2HMVi 3SLktP0eF4dk6n7HWpw2AOLKf1o257+S9yppMcCY= X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.97.6 at isis.morrow.me.uk Received: by anubis.morrow.me.uk (Postfix, from userid 5001) id 97BC29925; Wed, 20 Feb 2013 08:19:12 +0000 (GMT) Date: Wed, 20 Feb 2013 08:19:12 +0000 From: Ben Morrow To: gray.ru@gmail.com, pgsql-sql@postgresql.org Subject: Re: Volatile functions in WITH Message-ID: <20130220081905.GA95525@anubis.morrow.me.uk> References: <20130217075859.GE8029@anubis.morrow.me.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Newsgroups: pgsql.sql Organization: morrow.me.uk User-Agent: Mutt/1.5.21 (2010-09-15) X-Pg-Spam-Score: -2.6 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org Quoth gray.ru@gmail.com (Sergey Konoplev): > On Sat, Feb 16, 2013 at 11:58 PM, Ben Morrow wrote: > > WITH "exp" AS ( -- as before > > ), > > "subst" AS ( > > SELECT add_item(e.basket, e.nref, e.count) > > FROM "exp" e > > WHERE e.nref IS NOT NULL > > ) > > SELECT DISTINCT e.msg > > FROM "exp" e > > Alternatively I suppose you can try this one: > > WITH "exp" AS ( > DELETE FROM "item" i > USING "item_expired" e > WHERE e.oref = i.ref > AND i.basket = $1 > RETURNING i.basket, e.oref, e.nref, i.count, e.msg > ), > "upd" AS ( > UPDATE "item" SET "count" = e.count > FROM "exp" e > WHERE e.nref IS NOT NULL > AND ("basket", "nref") IS NOT DISTINCT FROM (e.basket, e.nref) > RETURNING "basket", "nref" > ) > "ins" AS ( > INSERT INTO "item" ("basket", "ref", "count") > SELECT e.basket, e.nref, e.count > FROM "exp" e LEFT JOIN "upd" u > ON ("basket", "nref") IS NOT DISTINCT FROM (e.basket, e.nref) > WHERE e.nref IS NOT NULL AND (u.basket, u.nref) IS NULL > ) > SELECT DISTINCT e.msg > FROM "exp" e That's not reliable. A concurrent txn could insert a conflicting row between the update and the insert, which would cause the insert to fail with a unique constraint violation. > > then the planner sees that the results of "subst" are not used, and > > doesn't include it in the query plan at all. > > > > Is there any way I can tell WITH that add_item is actually a data- > > modifying statement? Adding FOR UPDATE doesn't seem to help (I didn't > > really expect it would.) > > In this regard I would like to listen to gugrus' opinion too. > > EXPLAIN ANALYZE WITH t AS (SELECT random()) SELECT 1; > QUERY PLAN > ------------------------------------------------------------------------------------ > Result (cost=0.00..0.01 rows=1 width=0) (actual time=0.002..0.003 > rows=1 loops=1) > Total runtime: 0.063 ms > (2 rows) > > EXPLAIN ANALYZE WITH t AS (SELECT random()) SELECT 1 from t; > QUERY PLAN > -------------------------------------------------------------------------------------------- > CTE Scan on t (cost=0.01..0.03 rows=1 width=0) (actual > time=0.048..0.052 rows=1 loops=1) > CTE t > -> Result (cost=0.00..0.01 rows=1 width=0) (actual > time=0.038..0.039 rows=1 loops=1) > Total runtime: 0.131 ms > (4 rows) > > I couldn't manage to come to any solution except faking the reference > in the resulting query: > > WITH t AS (SELECT random()) SELECT 1 UNION ALL (SELECT 1 FROM t LIMIT 0); Yes, I can do experiments too; the alternatives I gave before both work on my test database. What I was asking was whether they are guaranteed to work in all situations, given that the planner can in principle see that the extra table reference won't affect the result. Ben -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql