Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1egvVF-0002d0-Tu for pgsql-hackers@arkaria.postgresql.org; Wed, 31 Jan 2018 16:44:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1egvVE-0003w5-Ez for pgsql-hackers@arkaria.postgresql.org; Wed, 31 Jan 2018 16:44:52 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1egvVE-0003vv-4Q for pgsql-hackers@lists.postgresql.org; Wed, 31 Jan 2018 16:44:52 +0000 Received: from sraihb2.sra.co.jp ([202.32.10.6]) by makus.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1egvV9-0006zM-1p for pgsql-hackers@postgresql.org; Wed, 31 Jan 2018 16:44:50 +0000 Received: from srascf.sra.co.jp (srascf [133.137.8.80]) by sraihb2.sra.co.jp (Postfix) with ESMTP id 62DDB2A15E9 for ; Thu, 1 Feb 2018 01:44:45 +0900 (JST) Received: from srascb.sra.co.jp (unknown [133.137.8.65]) by srascf.sra.co.jp with smtp id 2b34_0502_36add17c_6250_4a5c_ac4e_4ca41697562f; Thu, 01 Feb 2018 01:44:45 +0900 Received: from sranhm.sra.co.jp (osspc25 [133.137.174.97]) by srascb.sra.co.jp (Postfix) with ESMTP id 3CDA32D6942 for ; Thu, 1 Feb 2018 01:44:45 +0900 (JST) Received: from yugo-n-ubuntu (sraihb-hub.sra.co.jp [133.137.8.6]) by sranhm.sra.co.jp (Postfix) with SMTP id D995DA12A8; Thu, 1 Feb 2018 01:44:44 +0900 (JST) Date: Thu, 1 Feb 2018 01:44:44 +0900 From: Yugo Nagata To: Yugo Nagata Cc: pgsql-hackers@postgresql.org Subject: Re: CURRENT OF causes an error when IndexOnlyScan is used Message-Id: <20180201014444.f78358df.nagata@sraoss.co.jp> In-Reply-To: <20180201013349.937dfc5f.nagata@sraoss.co.jp> References: <20180201013349.937dfc5f.nagata@sraoss.co.jp> X-Mailer: Sylpheed Pro 2.1.4 (GTK+ 2.24.23; x86_64-unknown-linux-gnu; Pro 2.1.4) Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart=_Thu__1_Feb_2018_01_44_44_+0900_ZdDWt_639mx5cmQ9" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --Multipart=_Thu__1_Feb_2018_01_44_44_+0900_ZdDWt_639mx5cmQ9 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Thu, 1 Feb 2018 01:33:49 +0900 Yugo Nagata wrote: I'm sorry the patch attached in the previous mail is broken and not raises a compile error. I attached the fixed patch. Regards, > Hi, > > I found that updating a cursor by using CURRENT OF causes the > following error when the query is executed by IndexOnlyScan. > > ERROR: cannot extract system attribute from virtual tuple > > IndexOnlyScan returns a virtual tuple that doesn't have system > column, so we can not get ctid in the same way of other plans. > However, the error message is not convinient and users would > not understand why the error occurs. > > Attached is a patch to fix this. By this fix, execCurrentOf > get ctid from IndexScanDesc->xs_ctup.t_self when the plan is > IndexOnlyScan, and it works sucessfully without errors. > > > Here is the example of the error: > > ======= > postgres=# create table test (i int primary key); > CREATE TABLE > postgres=# insert into test values(1); > INSERT 0 1 > postgres=# set enable_seqscan to off; > SET > > postgres=# explain select * from test where i = 1; > QUERY PLAN > --------------------------------------------------------------------------- > Index Only Scan using test_pkey on test (cost=0.15..8.17 rows=1 width=4) > Index Cond: (i = 1) > (2 rows) > > postgres=# begin; > BEGIN > postgres=# declare c cursor for select * from test where i = 1; > DECLARE CURSOR > postgres=# fetch from c; > i > --- > 1 > (1 row) > > postgres=# update test set i=i+1 where current of c; > ERROR: cannot extract system attribute from virtual tuple > ======= > > The patch fixes the error and allows this update successfully. > > Regards, > > -- > Yugo Nagata -- Yugo Nagata --Multipart=_Thu__1_Feb_2018_01_44_44_+0900_ZdDWt_639mx5cmQ9 Content-Type: text/x-diff; name="current_of_index_only_scan_v2.patch" Content-Disposition: attachment; filename="current_of_index_only_scan_v2.patch" Content-Transfer-Encoding: 7bit diff --git a/src/backend/executor/execCurrent.c b/src/backend/executor/execCurrent.c index ce7d4ac..aa2da16 100644 --- a/src/backend/executor/execCurrent.c +++ b/src/backend/executor/execCurrent.c @@ -19,6 +19,7 @@ #include "utils/lsyscache.h" #include "utils/portal.h" #include "utils/rel.h" +#include "access/relscan.h" static char *fetch_cursor_param_value(ExprContext *econtext, int paramId); @@ -183,21 +184,35 @@ execCurrentOf(CurrentOfExpr *cexpr, if (TupIsNull(scanstate->ss_ScanTupleSlot)) return false; - /* Use slot_getattr to catch any possible mistakes */ - tuple_tableoid = - DatumGetObjectId(slot_getattr(scanstate->ss_ScanTupleSlot, - TableOidAttributeNumber, - &lisnull)); - Assert(!lisnull); - tuple_tid = (ItemPointer) - DatumGetPointer(slot_getattr(scanstate->ss_ScanTupleSlot, - SelfItemPointerAttributeNumber, - &lisnull)); - Assert(!lisnull); - - Assert(tuple_tableoid == table_oid); - - *current_tid = *tuple_tid; + /* In IndexOnlyScan case, the tuple stored in ss_ScanTupleSlot is a + * virtual tuple that does not have ctid column, so we have to get TID + * from xs_ctup.t_self. */ + if (IsA(scanstate, IndexOnlyScanState)) + { + IndexScanDesc scan = ((IndexOnlyScanState *)scanstate)->ioss_ScanDesc; + + Assert(RelationGetRelid(scan.heapRelation) == table_oid); + + *current_tid = scan->xs_ctup.t_self; + } + else + { + /* Use slot_getattr to catch any possible mistakes */ + tuple_tableoid = + DatumGetObjectId(slot_getattr(scanstate->ss_ScanTupleSlot, + TableOidAttributeNumber, + &lisnull)); + Assert(!lisnull); + tuple_tid = (ItemPointer) + DatumGetPointer(slot_getattr(scanstate->ss_ScanTupleSlot, + SelfItemPointerAttributeNumber, + &lisnull)); + Assert(!lisnull); + + Assert(tuple_tableoid == table_oid); + + *current_tid = *tuple_tid; + } return true; } --Multipart=_Thu__1_Feb_2018_01_44_44_+0900_ZdDWt_639mx5cmQ9--