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 FieldStore or 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 where the value would be needed, and an array assignment
         * can't be within a CASE either.  (So saving and restoring the
         * caseValue is just paranoia, but let's do it anyway.)
         *
         * Since fetching the old element might 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


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to