Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sKcsH-00BKGR-7s for pgsql-hackers@arkaria.postgresql.org; Fri, 21 Jun 2024 11:56:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sKcsE-00GuSz-4W for pgsql-hackers@arkaria.postgresql.org; Fri, 21 Jun 2024 11:56:10 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sKcsD-00GuSb-Mk for pgsql-hackers@lists.postgresql.org; Fri, 21 Jun 2024 11:56:10 +0000 Received: from mail-vs1-xe31.google.com ([2607:f8b0:4864:20::e31]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sKcs8-002PXD-HS for pgsql-hackers@postgresql.org; Fri, 21 Jun 2024 11:56:08 +0000 Received: by mail-vs1-xe31.google.com with SMTP id ada2fe7eead31-48c54370c56so549334137.3 for ; Fri, 21 Jun 2024 04:56:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718970963; x=1719575763; darn=postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=bFYtOpmoe6L10J8g7EmK3I5AUc+RaVtBs+tE3AcK+rw=; b=fhcGWacu6SKrzQfgj3cgyPLJN6kfwBPdBcOHLSeANh78cN23iITFlq0I21eHNHQYSB Y8Yt7RxI4qaFkuSTnH+tjWZ7jZlUzzB2F2QG4V+MeL+E7AE4EqU9dpfnjbrylLqaaeqH 5swYk7Cil6TrTtAIY67+luhWM192v5Zx1rufNtn4+ScAo3DmpCBR0cX2xo2LMdT97eGm 5QUjD3vnOWLKsOFfgba7XQ2Z5w3hf1vJX9Xgf/ZQQT0GdBw3MXM5gm1rrLDBSoeF1AjS vVIOZzcv+jkPiksnXaS2MU+a/VsKSIiDBv3LZ36zYyjW0VGsNYTDtSyeDbhZ7jrgQR9t cnCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718970963; x=1719575763; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=bFYtOpmoe6L10J8g7EmK3I5AUc+RaVtBs+tE3AcK+rw=; b=jolaExgdvrDH9Bu30izVUaycniEuJNzZ4eKdDK2fi68jMVOy3tdg2AruuGfzJUDkr2 luddMF3++MpoJSM7rxvzxIrKAg0QQM4xj9R+M2w6JmGyQuaONXrD9/gG1lQQaGcMo2K/ +0Hf3T7Z7Z9/3t7o9Kj5o6ehW5ig6W+c5Uh/wXnm3nWX5CjfSOesiMg/4DKV70nyO4Qv dV0svK2zLdzdF7EaI5LYeqyui4K6s8UzDzbZT6IwPWasZf5lVbuFqlamnJ600pIs84TQ U5yz7dldVXbit2hruDUZDmJ+IYs8vRgbet9IIPItviqkxuYKG+RezPJObqdr9eptziBD ZcEQ== X-Gm-Message-State: AOJu0YzShCa4J6fIYqsknSvOomMKSR0pqyUHbpImEN98gkEpY4cH4+qL 8E1q/ZJZR7HideWoEOZ9wTMusWtSLgmDD54hXZeBYjJTnAXAQeBIL/k1FhsxenNY1VsvWhrN4Zx rc9ODhIG7HJWcQ0mHSEJk0axzIOY= X-Google-Smtp-Source: AGHT+IF7qyuVobJ6HL0WrdMFb8Vjo+cWBnaEb4sMgFLyycweVB/I5sm31U6BxTeTAhutWwH4nWSn3CvHxLFunuGtHYg= X-Received: by 2002:a05:6102:216d:b0:48d:8199:cc9d with SMTP id ada2fe7eead31-48f130b78eamr8922877137.27.1718970963097; Fri, 21 Jun 2024 04:56:03 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Ashutosh Bapat Date: Fri, 21 Jun 2024 17:25:51 +0530 Message-ID: Subject: Re: Custom TupleTableSlotOps while Initializing Custom Scan To: V N G Samba Siva Reddy Chinta Cc: pgsql-hackers@postgresql.org Content-Type: multipart/alternative; boundary="000000000000a27e17061b651d8c" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000a27e17061b651d8c Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi, On Thu, Jun 20, 2024 at 5:58=E2=80=AFPM V N G Samba Siva Reddy Chinta < sambasivareddychinta@gmail.com> wrote: > Hello Team, > Good Day, > > I have been working on adding a CustomScanState object in the executor > state in my project. As part of CustomScanState, I execute queries and > store their results in the Tuplestorestate object. After storing all > tuples in the Tuplestorestate, I retrieve each tuple and place it in the > TupleTableSlot using the tuplestore_gettupleslot() function. > > However, I encounter an error: *"trying to store a minimal tuple into the > wrong type of slot."* Upon debugging, I discovered that the TupleTableSlo= t > only holds virtual tuples (tupleTableSlot->tts_ops is set to TTSOpsVirtua= l). > In contrast, tuplestore_gettupleslot() calls ExecStoreMinimalTuple(), > which expects TupleTableSlotOps of type TTSOpsMinimalTuple. > > Further investigation revealed that in the ExecInitCustomScan() function > within the nodeCustom.c source file, where ScanTupleSlot and > ResultTupleSlots are initialized, users can choose custom slots by > setting slotOps in CustomScanState. We initialize the ScanTupleSlot based > on user-specified slotOps, but for ResultTupleSlot, we proceed with > TTSOpsVirtual instead of the custom slotOps, which is causing the issue. > > Is this behavior expected? Is there a way to store tuples in slots > according to the TupleTableSlot type? > > I found a function ExecForceStoreMinimalTuple() which can be used in my > case. We need to pass the MinimalTuple to this function, but I was unable > to find a way to fetch the tuple from tuple storestate. We do have tuples= tore_gettuple() > function to get the minimal tuple but it is a static function, is there a= ny > other function like that? > From the description I assume that you are passing ResultTupleSlot to tuplestore_gettupleslot(). Please confirm. I think the reason for CustomScan's ResultTupleSlot to be set to virtual tuple slot is it's the most general kind of tuple - values and isnulls. Other kinds depend upon the heap tuple format. And the rest of the code needs CustomScans to produce a deterministic tuple slot type. Without knowing the details of your code, I think what you need to do is declare a minimal tuple slot, fetch the tuple from store using this slot and then store it into ResultTupleSlot using its ttsops. Other types of planstate nodes some times return the slot they get from their subplans as is without going through ResultTupleSlot. You may want to do something like that, if the result tuple contents are same as the tuple stored in tuplestore --=20 Best Wishes, Ashutosh Bapat --000000000000a27e17061b651d8c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

On Thu, Jun 20, 2024 at 5:58=E2=80=AFPM V N G Samb= a Siva Reddy Chinta <s= ambasivareddychinta@gmail.com> wrote:
Hello Team,
Good Day,

I have been working on adding a CustomScanState object in the executor state in my project. As part of CustomSc= anState, I execute queries and store their results in the Tupl= estorestate object. After storing all tuples in the Tuplestore= state, I retrieve each tuple and place it in the TupleTableSlo= t using the tuplestore_gettupleslot() function.

H= owever, I encounter an error: "trying to store a minimal tuple into= the wrong type of slot." Upon debugging, I discovered that the TupleTableSlot only holds virtual tuples (tupleTableSlot-&= gt;tts_ops is set to TTSOpsVirtual). In contrast, tuplestore_gettupleslot() calls ExecStoreMinimalTuple(), which expects TupleTableSlotOps of type TTSOpsMinimal= Tuple.

Further investigation revealed that in the ExecIn= itCustomScan() function within the nodeCustom.c source = file, where ScanTupleSlot and ResultTupleSlots ar= e initialized, users can choose custom slots by setting slotOps in CustomScanState. We initialize the ScanTupleSlot based on user-specified slotOps, but for ResultTupl= eSlot, we proceed with TTSOpsVirtual instead of the cus= tom slotOps, which is causing the issue.

Is= this behavior expected? Is there a way to store tuples in slots according = to the TupleTableSlot type?

I found a function=C2= =A0ExecForceStoreMinimalTuple() which can be used= in my case. We need to pass the MinimalTuple to this function, but I was u= nable to find a way to fetch the tuple from tuple storestate. We do have tuplestore_gettuple() function t= o get the minimal tuple but it is a static function, is there any other fun= ction like that?


From the = description I assume that you are passing ResultTupleSlot to tuplestore_get= tupleslot(). Please confirm.

I think the reason fo= r CustomScan's ResultTupleSlot to be set to virtual tuple slot is it= 9;s the most general kind of tuple - values and isnulls. Other kinds depend= upon the heap tuple format. And the rest of the code needs CustomScans to = produce a deterministic tuple slot type.

Witho= ut knowing the details of your code, I think what you need to do is declare= a minimal tuple slot, fetch the tuple from store using this slot and then = store it into ResultTupleSlot using its ttsops. Other types of planstate no= des some times return the slot they get from their subplans as is without g= oing through ResultTupleSlot. You may want to do something like that, if th= e result tuple contents are same as the tuple stored in tuplestore

--
Best Wishes,
Ashutosh Bapat
--000000000000a27e17061b651d8c--