LCOV - differential code coverage report
Current view: top level - src/backend/parser - parse_merge.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 96.9 % 127 123 4 17 106 16
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 3 3 2 1
Baseline: 16@8cea358b128 Branches: 75.0 % 104 78 3 23 13 65
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 100.0 % 18 18 17 1
(240..) days: 96.3 % 109 105 4 105
Function coverage date bins:
(240..) days: 100.0 % 3 3 2 1
Branch coverage date bins:
[..60] days: 81.2 % 16 13 3 13
(240..) days: 73.9 % 88 65 23 65

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * parse_merge.c
                                  4                 :                :  *    handle merge-statement in parser
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                  7                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * IDENTIFICATION
                                 11                 :                :  *    src/backend/parser/parse_merge.c
                                 12                 :                :  *
                                 13                 :                :  *-------------------------------------------------------------------------
                                 14                 :                :  */
                                 15                 :                : 
                                 16                 :                : #include "postgres.h"
                                 17                 :                : 
                                 18                 :                : #include "access/sysattr.h"
                                 19                 :                : #include "nodes/makefuncs.h"
                                 20                 :                : #include "parser/analyze.h"
                                 21                 :                : #include "parser/parse_clause.h"
                                 22                 :                : #include "parser/parse_collate.h"
                                 23                 :                : #include "parser/parse_cte.h"
                                 24                 :                : #include "parser/parse_expr.h"
                                 25                 :                : #include "parser/parse_merge.h"
                                 26                 :                : #include "parser/parse_relation.h"
                                 27                 :                : #include "parser/parse_target.h"
                                 28                 :                : #include "parser/parsetree.h"
                                 29                 :                : #include "utils/rel.h"
                                 30                 :                : 
                                 31                 :                : static void setNamespaceForMergeWhen(ParseState *pstate,
                                 32                 :                :                                      MergeWhenClause *mergeWhenClause,
                                 33                 :                :                                      Index targetRTI,
                                 34                 :                :                                      Index sourceRTI);
                                 35                 :                : static void setNamespaceVisibilityForRTE(List *namespace, RangeTblEntry *rte,
                                 36                 :                :                                          bool rel_visible,
                                 37                 :                :                                          bool cols_visible);
                                 38                 :                : 
                                 39                 :                : /*
                                 40                 :                :  * Make appropriate changes to the namespace visibility while transforming
                                 41                 :                :  * individual action's quals and targetlist expressions. In particular, for
                                 42                 :                :  * INSERT actions we must only see the source relation (since INSERT action is
                                 43                 :                :  * invoked for NOT MATCHED [BY TARGET] tuples and hence there is no target
                                 44                 :                :  * tuple to deal with). On the other hand, UPDATE and DELETE actions can see
                                 45                 :                :  * both source and target relations, unless invoked for NOT MATCHED BY SOURCE.
                                 46                 :                :  *
                                 47                 :                :  * Also, since the internal join node can hide the source and target
                                 48                 :                :  * relations, we must explicitly make the respective relation as visible so
                                 49                 :                :  * that columns can be referenced unqualified from these relations.
                                 50                 :                :  */
                                 51                 :                : static void
  748 alvherre@alvh.no-ip.       52                 :CBC        1420 : setNamespaceForMergeWhen(ParseState *pstate, MergeWhenClause *mergeWhenClause,
                                 53                 :                :                          Index targetRTI, Index sourceRTI)
                                 54                 :                : {
                                 55                 :                :     RangeTblEntry *targetRelRTE,
                                 56                 :                :                *sourceRelRTE;
                                 57                 :                : 
                                 58                 :           1420 :     targetRelRTE = rt_fetch(targetRTI, pstate->p_rtable);
                                 59                 :           1420 :     sourceRelRTE = rt_fetch(sourceRTI, pstate->p_rtable);
                                 60                 :                : 
   15 dean.a.rasheed@gmail       61         [ +  + ]:GNC        1420 :     if (mergeWhenClause->matchKind == MERGE_WHEN_MATCHED)
                                 62                 :                :     {
  748 alvherre@alvh.no-ip.       63   [ +  +  +  +  :CBC         880 :         Assert(mergeWhenClause->commandType == CMD_UPDATE ||
                                              -  + ]
                                 64                 :                :                mergeWhenClause->commandType == CMD_DELETE ||
                                 65                 :                :                mergeWhenClause->commandType == CMD_NOTHING);
                                 66                 :                : 
                                 67                 :                :         /* MATCHED actions can see both target and source relations. */
                                 68                 :            880 :         setNamespaceVisibilityForRTE(pstate->p_namespace,
                                 69                 :                :                                      targetRelRTE, true, true);
                                 70                 :            880 :         setNamespaceVisibilityForRTE(pstate->p_namespace,
                                 71                 :                :                                      sourceRelRTE, true, true);
                                 72                 :                :     }
   15 dean.a.rasheed@gmail       73         [ +  + ]:GNC         540 :     else if (mergeWhenClause->matchKind == MERGE_WHEN_NOT_MATCHED_BY_SOURCE)
                                 74                 :                :     {
                                 75                 :                :         /*
                                 76                 :                :          * NOT MATCHED BY SOURCE actions can see the target relation, but they
                                 77                 :                :          * can't see the source relation.
                                 78                 :                :          */
                                 79   [ +  +  -  +  :             66 :         Assert(mergeWhenClause->commandType == CMD_UPDATE ||
                                              -  - ]
                                 80                 :                :                mergeWhenClause->commandType == CMD_DELETE ||
                                 81                 :                :                mergeWhenClause->commandType == CMD_NOTHING);
                                 82                 :             66 :         setNamespaceVisibilityForRTE(pstate->p_namespace,
                                 83                 :                :                                      targetRelRTE, true, true);
                                 84                 :             66 :         setNamespaceVisibilityForRTE(pstate->p_namespace,
                                 85                 :                :                                      sourceRelRTE, false, false);
                                 86                 :                :     }
                                 87                 :                :     else                        /* MERGE_WHEN_NOT_MATCHED_BY_TARGET */
                                 88                 :                :     {
                                 89                 :                :         /*
                                 90                 :                :          * NOT MATCHED [BY TARGET] actions can't see target relation, but they
                                 91                 :                :          * can see source relation.
                                 92                 :                :          */
  748 alvherre@alvh.no-ip.       93   [ +  +  -  + ]:CBC         474 :         Assert(mergeWhenClause->commandType == CMD_INSERT ||
                                 94                 :                :                mergeWhenClause->commandType == CMD_NOTHING);
                                 95                 :            474 :         setNamespaceVisibilityForRTE(pstate->p_namespace,
                                 96                 :                :                                      targetRelRTE, false, false);
                                 97                 :            474 :         setNamespaceVisibilityForRTE(pstate->p_namespace,
                                 98                 :                :                                      sourceRelRTE, true, true);
                                 99                 :                :     }
                                100                 :           1420 : }
                                101                 :                : 
                                102                 :                : /*
                                103                 :                :  * transformMergeStmt -
                                104                 :                :  *    transforms a MERGE statement
                                105                 :                :  */
                                106                 :                : Query *
                                107                 :            930 : transformMergeStmt(ParseState *pstate, MergeStmt *stmt)
                                108                 :                : {
                                109                 :            930 :     Query      *qry = makeNode(Query);
                                110                 :                :     ListCell   *l;
                                111                 :            930 :     AclMode     targetPerms = ACL_NO_RIGHTS;
                                112                 :                :     bool        is_terminal[3];
                                113                 :                :     Index       sourceRTI;
                                114                 :                :     List       *mergeActionList;
                                115                 :                :     ParseNamespaceItem *nsitem;
                                116                 :                : 
                                117                 :                :     /* There can't be any outer WITH to worry about */
                                118         [ -  + ]:            930 :     Assert(pstate->p_ctenamespace == NIL);
                                119                 :                : 
                                120                 :            930 :     qry->commandType = CMD_MERGE;
                                121                 :            930 :     qry->hasRecursive = false;
                                122                 :                : 
                                123                 :                :     /* process the WITH clause independently of all else */
                                124         [ +  + ]:            930 :     if (stmt->withClause)
                                125                 :                :     {
                                126         [ +  + ]:             24 :         if (stmt->withClause->recursive)
                                127         [ +  - ]:              3 :             ereport(ERROR,
                                128                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                129                 :                :                      errmsg("WITH RECURSIVE is not supported for MERGE statement")));
                                130                 :                : 
                                131                 :             21 :         qry->cteList = transformWithClause(pstate, stmt->withClause);
                                132                 :             21 :         qry->hasModifyingCTE = pstate->p_hasModifyingCTE;
                                133                 :                :     }
                                134                 :                : 
                                135                 :                :     /*
                                136                 :                :      * Check WHEN clauses for permissions and sanity
                                137                 :                :      */
   15 dean.a.rasheed@gmail      138                 :GNC         927 :     is_terminal[MERGE_WHEN_MATCHED] = false;
                                139                 :            927 :     is_terminal[MERGE_WHEN_NOT_MATCHED_BY_SOURCE] = false;
                                140                 :            927 :     is_terminal[MERGE_WHEN_NOT_MATCHED_BY_TARGET] = false;
  748 alvherre@alvh.no-ip.      141   [ +  -  +  +  :CBC        2365 :     foreach(l, stmt->mergeWhenClauses)
                                              +  + ]
                                142                 :                :     {
                                143                 :           1441 :         MergeWhenClause *mergeWhenClause = (MergeWhenClause *) lfirst(l);
                                144                 :                : 
                                145                 :                :         /*
                                146                 :                :          * Collect permissions to check, according to action types. We require
                                147                 :                :          * SELECT privileges for DO NOTHING because it'd be irregular to have
                                148                 :                :          * a target relation with zero privileges checked, in case DO NOTHING
                                149                 :                :          * is the only action.  There's no damage from that: any meaningful
                                150                 :                :          * MERGE command requires at least some access to the table anyway.
                                151                 :                :          */
                                152   [ +  +  +  +  :           1441 :         switch (mergeWhenClause->commandType)
                                                 - ]
                                153                 :                :         {
                                154                 :            476 :             case CMD_INSERT:
                                155                 :            476 :                 targetPerms |= ACL_INSERT;
                                156                 :            476 :                 break;
                                157                 :            706 :             case CMD_UPDATE:
                                158                 :            706 :                 targetPerms |= ACL_UPDATE;
                                159                 :            706 :                 break;
                                160                 :            229 :             case CMD_DELETE:
                                161                 :            229 :                 targetPerms |= ACL_DELETE;
                                162                 :            229 :                 break;
                                163                 :             30 :             case CMD_NOTHING:
   53                           164                 :             30 :                 targetPerms |= ACL_SELECT;
  748                           165                 :             30 :                 break;
  748 alvherre@alvh.no-ip.      166                 :UBC           0 :             default:
                                167         [ #  # ]:              0 :                 elog(ERROR, "unknown action in MERGE WHEN clause");
                                168                 :                :         }
                                169                 :                : 
                                170                 :                :         /*
                                171                 :                :          * Check for unreachable WHEN clauses
                                172                 :                :          */
   15 dean.a.rasheed@gmail      173         [ +  + ]:GNC        1441 :         if (is_terminal[mergeWhenClause->matchKind])
  748 alvherre@alvh.no-ip.      174         [ +  - ]:CBC           3 :             ereport(ERROR,
                                175                 :                :                     (errcode(ERRCODE_SYNTAX_ERROR),
                                176                 :                :                      errmsg("unreachable WHEN clause specified after unconditional WHEN clause")));
  460 dean.a.rasheed@gmail      177         [ +  + ]:           1438 :         if (mergeWhenClause->condition == NULL)
   15 dean.a.rasheed@gmail      178                 :GNC        1049 :             is_terminal[mergeWhenClause->matchKind] = true;
                                179                 :                :     }
                                180                 :                : 
                                181                 :                :     /*
                                182                 :                :      * Set up the MERGE target table.  The target table is added to the
                                183                 :                :      * namespace below and to joinlist in transform_MERGE_to_join, so don't do
                                184                 :                :      * it here.
                                185                 :                :      *
                                186                 :                :      * Initially mergeTargetRelation is the same as resultRelation, so data is
                                187                 :                :      * read from the table being updated.  However, that might be changed by
                                188                 :                :      * the rewriter, if the target is a trigger-updatable view, to allow
                                189                 :                :      * target data to be read from the expanded view query while updating the
                                190                 :                :      * original view relation.
                                191                 :                :      */
  748 alvherre@alvh.no-ip.      192                 :CBC        1848 :     qry->resultRelation = setTargetTable(pstate, stmt->relation,
                                193                 :            924 :                                          stmt->relation->inh,
                                194                 :                :                                          false, targetPerms);
   45 dean.a.rasheed@gmail      195                 :GNC         924 :     qry->mergeTargetRelation = qry->resultRelation;
                                196                 :                : 
                                197                 :                :     /* The target relation must be a table or a view */
  748 alvherre@alvh.no-ip.      198         [ +  + ]:CBC         924 :     if (pstate->p_target_relation->rd_rel->relkind != RELKIND_RELATION &&
   45 dean.a.rasheed@gmail      199         [ +  + ]:GNC         381 :         pstate->p_target_relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE &&
                                200         [ +  + ]:            315 :         pstate->p_target_relation->rd_rel->relkind != RELKIND_VIEW)
  748 alvherre@alvh.no-ip.      201         [ +  - ]:CBC           3 :         ereport(ERROR,
                                202                 :                :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                203                 :                :                  errmsg("cannot execute MERGE on relation \"%s\"",
                                204                 :                :                         RelationGetRelationName(pstate->p_target_relation)),
                                205                 :                :                  errdetail_relkind_not_supported(pstate->p_target_relation->rd_rel->relkind)));
                                206                 :                : 
                                207                 :                :     /* Now transform the source relation to produce the source RTE. */
                                208                 :            921 :     transformFromClause(pstate,
                                209                 :            921 :                         list_make1(stmt->sourceRelation));
                                210                 :            918 :     sourceRTI = list_length(pstate->p_rtable);
                                211                 :            918 :     nsitem = GetNSItemByRangeTablePosn(pstate, sourceRTI, 0);
                                212                 :                : 
                                213                 :                :     /*
                                214                 :                :      * Check that the target table doesn't conflict with the source table.
                                215                 :                :      * This would typically be a checkNameSpaceConflicts call, but we want a
                                216                 :                :      * more specific error message.
                                217                 :                :      */
                                218                 :            918 :     if (strcmp(pstate->p_target_nsitem->p_names->aliasname,
                                219         [ +  + ]:            918 :                nsitem->p_names->aliasname) == 0)
                                220         [ +  - ]:              3 :         ereport(ERROR,
                                221                 :                :                 errcode(ERRCODE_DUPLICATE_ALIAS),
                                222                 :                :                 errmsg("name \"%s\" specified more than once",
                                223                 :                :                        pstate->p_target_nsitem->p_names->aliasname),
                                224                 :                :                 errdetail("The name is used both as MERGE target table and data source."));
                                225                 :                : 
                                226                 :                :     /*
                                227                 :                :      * There's no need for a targetlist here; it'll be set up by
                                228                 :                :      * preprocess_targetlist later.
                                229                 :                :      */
  733                           230                 :            915 :     qry->targetList = NIL;
  748                           231                 :            915 :     qry->rtable = pstate->p_rtable;
  495                           232                 :            915 :     qry->rteperminfos = pstate->p_rteperminfos;
                                233                 :                : 
                                234                 :                :     /*
                                235                 :                :      * Transform the join condition.  This includes references to the target
                                236                 :                :      * side, so add that to the namespace.
                                237                 :                :      */
  748                           238                 :            915 :     addNSItemToQuery(pstate, pstate->p_target_nsitem, false, true, true);
   15 dean.a.rasheed@gmail      239                 :GNC         915 :     qry->mergeJoinCondition = transformExpr(pstate, stmt->joinCondition,
                                240                 :                :                                             EXPR_KIND_JOIN_ON);
                                241                 :                : 
                                242                 :                :     /*
                                243                 :                :      * Create the temporary query's jointree using the joinlist we built using
                                244                 :                :      * just the source relation; the target relation is not included. The join
                                245                 :                :      * will be constructed fully by transform_MERGE_to_join.
                                246                 :                :      */
                                247                 :            915 :     qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
                                248                 :                : 
                                249                 :                :     /* Transform the RETURNING list, if any */
   28                           250                 :            915 :     qry->returningList = transformReturningList(pstate, stmt->returningList,
                                251                 :                :                                                 EXPR_KIND_MERGE_RETURNING);
                                252                 :                : 
                                253                 :                :     /*
                                254                 :                :      * We now have a good query shape, so now look at the WHEN conditions and
                                255                 :                :      * action targetlists.
                                256                 :                :      *
                                257                 :                :      * Overall, the MERGE Query's targetlist is NIL.
                                258                 :                :      *
                                259                 :                :      * Each individual action has its own targetlist that needs separate
                                260                 :                :      * transformation. These transforms don't do anything to the overall
                                261                 :                :      * targetlist, since that is only used for resjunk columns.
                                262                 :                :      *
                                263                 :                :      * We can reference any column in Target or Source, which is OK because
                                264                 :                :      * both of those already have RTEs. There is nothing like the EXCLUDED
                                265                 :                :      * pseudo-relation for INSERT ON CONFLICT.
                                266                 :                :      */
  748 alvherre@alvh.no-ip.      267                 :CBC         915 :     mergeActionList = NIL;
                                268   [ +  -  +  +  :           2317 :     foreach(l, stmt->mergeWhenClauses)
                                              +  + ]
                                269                 :                :     {
                                270                 :           1420 :         MergeWhenClause *mergeWhenClause = lfirst_node(MergeWhenClause, l);
                                271                 :                :         MergeAction *action;
                                272                 :                : 
                                273                 :           1420 :         action = makeNode(MergeAction);
                                274                 :           1420 :         action->commandType = mergeWhenClause->commandType;
   15 dean.a.rasheed@gmail      275                 :GNC        1420 :         action->matchKind = mergeWhenClause->matchKind;
                                276                 :                : 
                                277                 :                :         /*
                                278                 :                :          * Set namespace for the specific action. This must be done before
                                279                 :                :          * analyzing the WHEN quals and the action targetlist.
                                280                 :                :          */
  748 alvherre@alvh.no-ip.      281                 :CBC        1420 :         setNamespaceForMergeWhen(pstate, mergeWhenClause,
                                282                 :           1420 :                                  qry->resultRelation,
                                283                 :                :                                  sourceRTI);
                                284                 :                : 
                                285                 :                :         /*
                                286                 :                :          * Transform the WHEN condition.
                                287                 :                :          *
                                288                 :                :          * Note that these quals are NOT added to the join quals; instead they
                                289                 :                :          * are evaluated separately during execution to decide which of the
                                290                 :                :          * WHEN MATCHED or WHEN NOT MATCHED actions to execute.
                                291                 :                :          */
                                292                 :           1420 :         action->qual = transformWhereClause(pstate, mergeWhenClause->condition,
                                293                 :                :                                             EXPR_KIND_MERGE_WHEN, "WHEN");
                                294                 :                : 
                                295                 :                :         /*
                                296                 :                :          * Transform target lists for each INSERT and UPDATE action stmt
                                297                 :                :          */
                                298   [ +  +  +  +  :           1411 :         switch (action->commandType)
                                                 - ]
                                299                 :                :         {
                                300                 :            464 :             case CMD_INSERT:
                                301                 :                :                 {
                                302                 :            464 :                     List       *exprList = NIL;
                                303                 :                :                     ListCell   *lc;
                                304                 :                :                     RTEPermissionInfo *perminfo;
                                305                 :                :                     ListCell   *icols;
                                306                 :                :                     ListCell   *attnos;
                                307                 :                :                     List       *icolumns;
                                308                 :                :                     List       *attrnos;
                                309                 :                : 
                                310                 :            464 :                     pstate->p_is_insert = true;
                                311                 :                : 
                                312                 :            464 :                     icolumns = checkInsertTargets(pstate,
                                313                 :                :                                                   mergeWhenClause->targetList,
                                314                 :                :                                                   &attrnos);
                                315         [ -  + ]:            464 :                     Assert(list_length(icolumns) == list_length(attrnos));
                                316                 :                : 
                                317                 :            464 :                     action->override = mergeWhenClause->override;
                                318                 :                : 
                                319                 :                :                     /*
                                320                 :                :                      * Handle INSERT much like in transformInsertStmt
                                321                 :                :                      */
                                322         [ +  + ]:            464 :                     if (mergeWhenClause->values == NIL)
                                323                 :                :                     {
                                324                 :                :                         /*
                                325                 :                :                          * We have INSERT ... DEFAULT VALUES.  We can handle
                                326                 :                :                          * this case by emitting an empty targetlist --- all
                                327                 :                :                          * columns will be defaulted when the planner expands
                                328                 :                :                          * the targetlist.
                                329                 :                :                          */
                                330                 :             12 :                         exprList = NIL;
                                331                 :                :                     }
                                332                 :                :                     else
                                333                 :                :                     {
                                334                 :                :                         /*
                                335                 :                :                          * Process INSERT ... VALUES with a single VALUES
                                336                 :                :                          * sublist.  We treat this case separately for
                                337                 :                :                          * efficiency.  The sublist is just computed directly
                                338                 :                :                          * as the Query's targetlist, with no VALUES RTE.  So
                                339                 :                :                          * it works just like a SELECT without any FROM.
                                340                 :                :                          */
                                341                 :                : 
                                342                 :                :                         /*
                                343                 :                :                          * Do basic expression transformation (same as a ROW()
                                344                 :                :                          * expr, but allow SetToDefault at top level)
                                345                 :                :                          */
                                346                 :            452 :                         exprList = transformExpressionList(pstate,
                                347                 :                :                                                            mergeWhenClause->values,
                                348                 :                :                                                            EXPR_KIND_VALUES_SINGLE,
                                349                 :                :                                                            true);
                                350                 :                : 
                                351                 :                :                         /* Prepare row for assignment to target table */
                                352                 :            446 :                         exprList = transformInsertRow(pstate, exprList,
                                353                 :                :                                                       mergeWhenClause->targetList,
                                354                 :                :                                                       icolumns, attrnos,
                                355                 :                :                                                       false);
                                356                 :                :                     }
                                357                 :                : 
                                358                 :                :                     /*
                                359                 :                :                      * Generate action's target list using the computed list
                                360                 :                :                      * of expressions. Also, mark all the target columns as
                                361                 :                :                      * needing insert permissions.
                                362                 :                :                      */
  495                           363                 :            458 :                     perminfo = pstate->p_target_nsitem->p_perminfo;
  748                           364   [ +  +  +  +  :           1440 :                     forthree(lc, exprList, icols, icolumns, attnos, attrnos)
                                     +  -  +  +  +  
                                     -  +  +  +  +  
                                     +  -  +  -  +  
                                                 + ]
                                365                 :                :                     {
                                366                 :            982 :                         Expr       *expr = (Expr *) lfirst(lc);
                                367                 :            982 :                         ResTarget  *col = lfirst_node(ResTarget, icols);
                                368                 :            982 :                         AttrNumber  attr_num = (AttrNumber) lfirst_int(attnos);
                                369                 :                :                         TargetEntry *tle;
                                370                 :                : 
                                371                 :            982 :                         tle = makeTargetEntry(expr,
                                372                 :                :                                               attr_num,
                                373                 :                :                                               col->name,
                                374                 :                :                                               false);
                                375                 :            982 :                         action->targetList = lappend(action->targetList, tle);
                                376                 :                : 
  495                           377                 :            982 :                         perminfo->insertedCols =
                                378                 :            982 :                             bms_add_member(perminfo->insertedCols,
                                379                 :                :                                            attr_num - FirstLowInvalidHeapAttributeNumber);
                                380                 :                :                     }
                                381                 :                :                 }
  748                           382                 :            458 :                 break;
                                383                 :            700 :             case CMD_UPDATE:
                                384                 :                :                 {
                                385                 :            700 :                     pstate->p_is_insert = false;
                                386                 :            697 :                     action->targetList =
                                387                 :            700 :                         transformUpdateTargetList(pstate,
                                388                 :                :                                                   mergeWhenClause->targetList);
                                389                 :                :                 }
                                390                 :            697 :                 break;
                                391                 :            220 :             case CMD_DELETE:
                                392                 :            220 :                 break;
                                393                 :                : 
                                394                 :             27 :             case CMD_NOTHING:
                                395                 :             27 :                 action->targetList = NIL;
                                396                 :             27 :                 break;
  748 alvherre@alvh.no-ip.      397                 :UBC           0 :             default:
                                398         [ #  # ]:              0 :                 elog(ERROR, "unknown action in MERGE WHEN clause");
                                399                 :                :         }
                                400                 :                : 
  748 alvherre@alvh.no-ip.      401                 :CBC        1402 :         mergeActionList = lappend(mergeActionList, action);
                                402                 :                :     }
                                403                 :                : 
                                404                 :            897 :     qry->mergeActionList = mergeActionList;
                                405                 :                : 
                                406                 :            897 :     qry->hasTargetSRFs = false;
                                407                 :            897 :     qry->hasSubLinks = pstate->p_hasSubLinks;
                                408                 :                : 
                                409                 :            897 :     assign_query_collations(pstate, qry);
                                410                 :                : 
                                411                 :            897 :     return qry;
                                412                 :                : }
                                413                 :                : 
                                414                 :                : static void
                                415                 :           2840 : setNamespaceVisibilityForRTE(List *namespace, RangeTblEntry *rte,
                                416                 :                :                              bool rel_visible,
                                417                 :                :                              bool cols_visible)
                                418                 :                : {
                                419                 :                :     ListCell   *lc;
                                420                 :                : 
                                421   [ +  -  +  -  :           4356 :     foreach(lc, namespace)
                                              +  - ]
                                422                 :                :     {
                                423                 :           4356 :         ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc);
                                424                 :                : 
                                425         [ +  + ]:           4356 :         if (nsitem->p_rte == rte)
                                426                 :                :         {
                                427                 :           2840 :             nsitem->p_rel_visible = rel_visible;
                                428                 :           2840 :             nsitem->p_cols_visible = cols_visible;
                                429                 :           2840 :             break;
                                430                 :                :         }
                                431                 :                :     }
                                432                 :           2840 : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622