From 42e83449476b5adbdd24ca9a093e10840cc47f79 Mon Sep 17 00:00:00 2001 From: jian he 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