v1-0001-refactoring-svariableStartupReceiver.no-cfbot
application/octet-stream
Filename: v1-0001-refactoring-svariableStartupReceiver.no-cfbot
Type: application/octet-stream
Part: 0
Message:
Re: Re: proposal: schema variables
From 42e83449476b5adbdd24ca9a093e10840cc47f79 Mon Sep 17 00:00:00 2001
From: jian he <jian.universality@gmail.com>
Date: Fri, 3 Jan 2025 15:09:06 +0800
Subject: [PATCH v1 1/1] refactoring svariableStartupReceiver
---
src/backend/executor/svariableReceiver.c | 66 ++++--------------------
1 file changed, 9 insertions(+), 57 deletions(-)
diff --git a/src/backend/executor/svariableReceiver.c b/src/backend/executor/svariableReceiver.c
index c4cff44ecf..a3574b4685 100644
--- a/src/backend/executor/svariableReceiver.c
+++ b/src/backend/executor/svariableReceiver.c
@@ -28,19 +28,16 @@
/*
* This DestReceiver is used by the LET command for storing the result to a
* session variable. The result has to have only one tuple with only one
- * non-deleted attribute. The row counter (field "rows") is incremented
+ * attribute. The row counter (field "rows") is incremented
* after receiving a row, and an error is raised when there are no rows or
- * there are more than one received rows. Because a received tuple can have
- * deleted attributes, we need to find the first non-deleted attribute
- * (field "slot_offset"). The value is detoasted before storing it in the
- * session variable.
+ * there are more than one received rows.
+ * The value is detoasted before storing it in the session variable.
*/
typedef struct
{
DestReceiver pub;
Oid varid;
bool need_detoast; /* do we need to detoast the attribute? */
- int slot_offset; /* position of non-deleted attribute */
int rows; /* row counter */
} SVariableState;
@@ -52,8 +49,7 @@ svariableStartupReceiver(DestReceiver *self, int operation, TupleDesc typeinfo)
{
SVariableState *myState = (SVariableState *) self;
int natts = typeinfo->natts;
- int outcols = 0;
- int i;
+ Form_pg_attribute attr;
LOCKTAG locktag PG_USED_FOR_ASSERTS_ONLY;
Assert(myState->pub.mydest == DestVariable);
@@ -71,53 +67,9 @@ svariableStartupReceiver(DestReceiver *self, int operation, TupleDesc typeinfo)
Assert(LockHeldByMe(&locktag, AccessShareLock, false));
#endif
-
- for (i = 0; i < natts; i++)
- {
- Form_pg_attribute attr = TupleDescAttr(typeinfo, i);
- Oid typid;
- Oid collid;
- int32 typmod;
-
- if (attr->attisdropped)
- continue;
-
- if (++outcols > 1)
- continue;
-
- get_session_variable_type_typmod_collid(myState->varid,
- &typid,
- &typmod,
- &collid);
-
- /*
- * Double check - the type and typmod of target variable should be the
- * same as the type and typmod of assignment expression. The
- * expression should be wrapped by a cast to the target type/typmod.
- */
- if (attr->atttypid != typid ||
- (attr->atttypmod >= 0 &&
- attr->atttypmod != typmod))
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("target session variable is of type %s"
- " but expression is of type %s",
- format_type_with_typemod(typid, typmod),
- format_type_with_typemod(attr->atttypid,
- attr->atttypmod))));
-
- myState->need_detoast = attr->attlen == -1;
- myState->slot_offset = i;
- }
-
- if (outcols != 1)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg_plural("assignment expression returned %d column",
- "assignment expression returned %d columns",
- outcols,
- outcols)));
-
+ Assert(natts == 1);
+ attr = TupleDescAttr(typeinfo, 0);
+ myState->need_detoast = attr->attlen == -1;
myState->rows = 0;
}
@@ -135,8 +87,8 @@ svariableReceiveSlot(TupleTableSlot *slot, DestReceiver *self)
/* make sure the tuple is fully deconstructed */
slot_getallattrs(slot);
- value = slot->tts_values[myState->slot_offset];
- isnull = slot->tts_isnull[myState->slot_offset];
+ value = slot->tts_values[0];
+ isnull = slot->tts_isnull[0];
if (myState->need_detoast && !isnull && VARATT_IS_EXTERNAL(DatumGetPointer(value)))
{
--
2.34.1