[HACKERS] Indirect assignment code for array slices is dead code? - Mailing list pgsql-hackers

From Andres Freund
Subject [HACKERS] Indirect assignment code for array slices is dead code?
Date
Msg-id 20170311005810.kuccp7t5t5jhe736@alap3.anarazel.de
Whole thread Raw
Responses Re: [HACKERS] Indirect assignment code for array slices is dead code?  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Hi,

In the context of my expression evaluation patch, I was trying to
increase test coverage of execQual.c.  I'm a bit confused about
$subject.  ExecEvalArrayRef() has the following codepath:
   if (isAssignment)   {       Datum       sourceData;       Datum       save_datum;       bool        save_isNull;
       /*        * We might have a nested-assignment situation, in which the        * refassgnexpr is itself a
FieldStoreor ArrayRef that needs to        * obtain and modify the previous value of the array element or slice
*being replaced.  If so, we have to extract that value from the        * array and pass it down via the econtext's
caseValue. It's safe to        * reuse the CASE mechanism because there cannot be a CASE between        * here and
wherethe value would be needed, and an array assignment        * can't be within a CASE either.  (So saving and
restoringthe        * caseValue is just paranoia, but let's do it anyway.)        *        * Since fetching the old
elementmight be a nontrivial expense, do it        * only if the argument appears to actually need it.        */
save_datum= econtext->caseValue_datum;       save_isNull = econtext->caseValue_isNull;
 
       if (isAssignmentIndirectionExpr(astate->refassgnexpr))           if (*isNull)           {               ...
    }           else if (lIndex == NULL)           {               ...           }           else           {
   econtext->caseValue_datum =                   array_get_slice(array_source, i,
upper.indx,lower.indx,                                   upperProvided, lowerProvided,
astate->refattrlength,                                   astate->refelemlength,
astate->refelembyval,                                  astate->refelemalign);               econtext->caseValue_isNull
=false;           }       }
 
...

That's support for multiple indirect assignments, assigning to array
slices.  But I can't figure out how to reach that bit of code.

The !slice code can be reached:
CREATE TABLE arr(d int[]);
CREATE TABLE arr2(arr arr)
INSERT INTO arr2(arr[1].d, arr[2].d) VALUES(ARRAY[1,2],ARRAY[3,4]) RETURNING *
┌───────────────────────────────┐
│              arr              │
├───────────────────────────────┤
│ {"(\"{1,2}\")","(\"{3,4}\")"} │
└───────────────────────────────┘

But I don't see how to the slice code can be reached.  The indirection
code is only triggered when isAssignmentIndirectionExpr is true, which
requires that refassgnexpr is a FieldStore/ArrayRef containing a
CaseTest.

But that doesn't make sense for slices, because there can't be a
FieldStore directly below a slice (you'd get "subfield "d" is of type
integer[] but expression is of type integer" - makes sense), nor can
there be an ArrayRef inside a slice ArrayRef for assignemnts, because
there are no parens in the LHS, and consecutive []'s are collapsed into
a single ArrayRef.

Am I standing on my own foot here?

Greetings,

Andres Freund



pgsql-hackers by date:

Previous
From: Eric Ridge
Date:
Subject: [HACKERS] How to get the 'ctid' from a record type?
Next
From: Tom Lane
Date:
Subject: Re: [HACKERS] How to get the 'ctid' from a record type?