• Dean Rasheed's avatar
    Further fixing for multi-row VALUES lists for updatable views. · ed4653db
    Dean Rasheed authored
    Previously, rewriteTargetListIU() generated a list of attribute
    numbers from the targetlist, which were passed to rewriteValuesRTE(),
    which expected them to contain the same number of entries as there are
    columns in the VALUES RTE, and to be in the same order. That was fine
    when the target relation was a table, but for an updatable view it
    could be broken in at least three different ways ---
    rewriteTargetListIU() could insert additional targetlist entries for
    view columns with defaults, the view columns could be in a different
    order from the columns of the underlying base relation, and targetlist
    entries could be merged together when assigning to elements of an
    array or composite type. As a result, when recursing to the base
    relation, the list of attribute numbers generated from the rewritten
    targetlist could no longer be relied upon to match the columns of the
    VALUES RTE. We got away with that prior to 41531e42 because it used
    to always be the case that rewriteValuesRTE() did nothing for the
    underlying base relation, since all DEFAULTS had already been replaced
    when it was initially invoked for the view, but that was incorrect
    because it failed to apply defaults from the base relation.
    
    Fix this by examining the targetlist entries more carefully and
    picking out just those that are simple Vars referencing the VALUES
    RTE. That's sufficient for the purposes of rewriteValuesRTE(), which
    is only responsible for dealing with DEFAULT items in the VALUES
    RTE. Any DEFAULT item in the VALUES RTE that doesn't have a matching
    simple-Var-assignment in the targetlist is an error which we complain
    about, but in theory that ought to be impossible.
    
    Additionally, move this code into rewriteValuesRTE() to give a clearer
    separation of concerns between the 2 functions. There is no need for
    rewriteTargetListIU() to know about the details of the VALUES RTE.
    
    While at it, fix the comment for rewriteValuesRTE() which claimed that
    it doesn't support array element and field assignments --- that hasn't
    been true since a3c7a993 (9.6 and later).
    
    Back-patch to all supported versions, with minor differences for the
    pre-9.6 branches, which don't support array element and field
    assignments to the same column in multi-row VALUES lists.
    
    Reviewed by Amit Langote.
    
    Discussion: https://postgr.es/m/15623-5d67a46788ec8b7f@postgresql.org
    ed4653db
updatable_views.sql 50.6 KB