Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nT4I4-0004SA-N5 for pgsql-hackers@arkaria.postgresql.org; Sat, 12 Mar 2022 16:08:24 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nT4I2-0001ju-2c for pgsql-hackers@arkaria.postgresql.org; Sat, 12 Mar 2022 16:08:22 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nT4I1-0001ir-LR for pgsql-hackers@lists.postgresql.org; Sat, 12 Mar 2022 16:08:21 +0000 Received: from mail-io1-xd2d.google.com ([2607:f8b0:4864:20::d2d]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nT4Hy-0007jC-CP for pgsql-hackers@lists.postgresql.org; Sat, 12 Mar 2022 16:08:20 +0000 Received: by mail-io1-xd2d.google.com with SMTP id e22so13441662ioe.11 for ; Sat, 12 Mar 2022 08:08:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20210112.gappssmtp.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=CtNSSaVDj37f7ZcixQyy7PTTbN4Ol6oyJqgSC33p/0k=; b=4qsJhbjuMi06TSZTNd8gKyFaaLpQrca3zOSUfnDTedUEszrhIOO5VkLzEIoatix9wK JgEjAsv5AI4lz+CpDmXKid+slghGyt8acAOQ2hipBeCizOUXbM/DBjbyZl3oRMp67eNQ k2GT3WnsD4ygqaIMAxwGqdelFM33yGVtMRsNkggSl78m6nddY/SMPApP+TSMObRj+jrQ ouCxmFvGrer7FYAnpCB5n+IsY8so27oeFTgIU3oMRjGaqFIXQmzF+W+Low9KN32kVAXF UGlc16ba86VgAcGpfDhhWH7nP3gj0pPhukPULD35MWoSRH4IKPkcd6vSJVmk2k3fZNP1 foPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=CtNSSaVDj37f7ZcixQyy7PTTbN4Ol6oyJqgSC33p/0k=; b=kHlb0UaGRMyDZMO6O/6UwKKOCv8x6G5GkalJcTLi/QwAkE+O7csin09ig4PTi3QuFt TtpXMOWW9BbvW1hnwvsBnV8od01xTuUgLNLsYg8O8s1Jq9oSS+iQgNxi7jdQS3H5ZYIx qbqqJEDiTCK7nlyenfsxiNS9Q6IlzNPdp/pNsCYLGmoEsBgc8gKC6OXIgYMZcC5DQf1B ASC4sE5a4+FRT22ZroD7OdD7Sg4v8gIG55g540h30tm31409k8RYYzVP8dzKmuhbeFVP dHEvm/Oe0H0SzWhZ9+q9prq/AG9HxCxmDXaOk+guH8qkbtarBItBVpQbxlTuHwz9Dpx1 9cHA== X-Gm-Message-State: AOAM531y7wVXxr63AoDyOqAJYYMV1dyZdiFeA4Lh0mFbYVuIVR90wQwe JhS23l4rws/eqKdwu8oPzqsCUw== X-Google-Smtp-Source: ABdhPJxyuQdY1dyL2B/YVj0FJRtn7mTAWm+0fltRHrYvcrymXktY1InfY32f3Nm3LTG0AtQZJo8eLw== X-Received: by 2002:a02:ceb2:0:b0:314:f9b9:d420 with SMTP id z18-20020a02ceb2000000b00314f9b9d420mr12763764jaq.177.1647101297598; Sat, 12 Mar 2022 08:08:17 -0800 (PST) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id v23-20020a056602015700b006409f5261a4sm5648619iot.40.2022.03.12.08.08.16 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 12 Mar 2022 08:08:17 -0800 (PST) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id C892A800DCA; Sat, 12 Mar 2022 10:08:15 -0600 (CST) Date: Sat, 12 Mar 2022 10:08:15 -0600 From: Justin Pryzby To: Alvaro Herrera Cc: Zhihong Yu , Simon Riggs , Pg Hackers , Tomas Vondra , Daniel Westermann , Amit Langote , Japin Li , Erik Rijkers , Jaime Casanova , Andres Freund Subject: Re: support for MERGE Message-ID: <20220312160815.GP28503@telsasoft.com> References: <202203120353.sdof7mld5qfc@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <202203120353.sdof7mld5qfc@alvherre.pgsql> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sat, Jan 29, 2022 at 12:03:35AM -0600, Justin Pryzby wrote: > Note that MergeWhenClause and MergeAction have the node definition in a > different order than the header, which is a bit confusing. The .h files still order these fields differently than the other .h files, and then the node funcs (at least MergeAction) also have a different order than the .h files. > diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h > index 1617702d9d..c8e8254b16 100644 > --- a/src/include/nodes/parsenodes.h > +++ b/src/include/nodes/parsenodes.h > @@ -117,7 +117,7 @@ typedef struct Query > +typedef struct MergeWhenClause > +{ > + NodeTag type; > + bool matched; /* true=MATCHED, false=NOT MATCHED */ > + CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ > + Node *condition; /* WHEN conditions (raw parser) */ > + List *targetList; /* INSERT/UPDATE targetlist */ > + /* the following members are only useful for INSERT action */ > + List *cols; /* optional: names of the target columns */ > + List *values; /* VALUES to INSERT, or NULL */ > + OverridingKind override; /* OVERRIDING clause */ > +} MergeWhenClause; > +/* > + * WHEN [NOT] MATCHED THEN action info > + */ > +typedef struct MergeAction > +{ > + NodeTag type; > + bool matched; /* true=MATCHED, false=NOT MATCHED */ > + OverridingKind override; /* OVERRIDING clause */ > + Node *qual; /* transformed WHEN conditions */ > + CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ > + List *targetList; /* the target list (of TargetEntry) */ > + List *updateColnos; /* target attribute numbers of an UPDATE */ > +} MergeAction; > diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c > index d4f8455a2b..234a701045 100644 > --- a/src/backend/nodes/copyfuncs.c > +++ b/src/backend/nodes/copyfuncs.c > +static MergeAction * > +_copyMergeAction(const MergeAction *from) > +{ > + MergeAction *newnode = makeNode(MergeAction); > + > + COPY_SCALAR_FIELD(matched); > + COPY_SCALAR_FIELD(commandType); > + COPY_SCALAR_FIELD(override); > + COPY_NODE_FIELD(qual); > + COPY_NODE_FIELD(targetList); > + COPY_NODE_FIELD(updateColnos); > +static MergeWhenClause * > +_copyMergeWhenClause(const MergeWhenClause *from) > +{ > + MergeWhenClause *newnode = makeNode(MergeWhenClause); > + > + COPY_SCALAR_FIELD(matched); > + COPY_SCALAR_FIELD(commandType); > + COPY_NODE_FIELD(condition); > + COPY_NODE_FIELD(targetList); > + COPY_NODE_FIELD(cols); > + COPY_NODE_FIELD(values); > + COPY_SCALAR_FIELD(override); > + return newnode; > +} > diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c > index f1002afe7a..5e1ff02a55 100644 > --- a/src/backend/nodes/equalfuncs.c > +++ b/src/backend/nodes/equalfuncs.c > @@ -841,6 +841,20 @@ _equalOnConflictExpr(const OnConflictExpr *a, const OnConflictExpr *b) > +static bool > +_equalMergeAction(const MergeAction *a, const MergeAction *b) > +{ > + COMPARE_SCALAR_FIELD(matched); > + COMPARE_SCALAR_FIELD(commandType); > + COMPARE_SCALAR_FIELD(override); > + COMPARE_NODE_FIELD(qual); > + COMPARE_NODE_FIELD(targetList); > + COMPARE_NODE_FIELD(updateColnos); > +static bool > +_equalMergeWhenClause(const MergeWhenClause *a, const MergeWhenClause *b) > +{ > + COMPARE_SCALAR_FIELD(matched); > + COMPARE_SCALAR_FIELD(commandType); > + COMPARE_NODE_FIELD(condition); > + COMPARE_NODE_FIELD(targetList); > + COMPARE_NODE_FIELD(cols); > + COMPARE_NODE_FIELD(values); > + COMPARE_SCALAR_FIELD(override); > + > + return true; > +} > diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c > index 6bdad462c7..7549b27b39 100644 > --- a/src/backend/nodes/outfuncs.c > +++ b/src/backend/nodes/outfuncs.c > @@ -429,6 +429,21 @@ _outModifyTable(StringInfo str, const ModifyTable *node) > +static void > +_outMergeWhenClause(StringInfo str, const MergeWhenClause *node) > +{ > + WRITE_NODE_TYPE("MERGEWHENCLAUSE"); > + > + WRITE_BOOL_FIELD(matched); > + WRITE_ENUM_FIELD(commandType, CmdType); > + WRITE_NODE_FIELD(condition); > + WRITE_NODE_FIELD(targetList); > + WRITE_NODE_FIELD(cols); > + WRITE_NODE_FIELD(values); > + WRITE_ENUM_FIELD(override, OverridingKind); > +static void > +_outMergeAction(StringInfo str, const MergeAction *node) > +{ > + WRITE_NODE_TYPE("MERGEACTION"); > + > + WRITE_BOOL_FIELD(matched); > + WRITE_ENUM_FIELD(commandType, CmdType); > + WRITE_ENUM_FIELD(override, OverridingKind); > + WRITE_NODE_FIELD(qual); > + WRITE_NODE_FIELD(targetList); > + WRITE_NODE_FIELD(updateColnos); > +} > diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c > index 3f68f7c18d..d3ca5f0e45 100644 > --- a/src/backend/nodes/readfuncs.c > +++ b/src/backend/nodes/readfuncs.c > +static MergeAction * > +_readMergeAction(void) > +{ > + READ_LOCALS(MergeAction); > + > + READ_BOOL_FIELD(matched); > + READ_ENUM_FIELD(commandType, CmdType); > + READ_ENUM_FIELD(override, OverridingKind); > + READ_NODE_FIELD(qual); > + READ_NODE_FIELD(targetList); > + READ_NODE_FIELD(updateColnos); > + > + READ_DONE(); > +} > +static MergeWhenClause * > +_readMergeWhenClause(void) > +{ > + READ_LOCALS(MergeWhenClause); > + > + READ_BOOL_FIELD(matched); > + READ_ENUM_FIELD(commandType, CmdType); > + READ_NODE_FIELD(condition); > + READ_NODE_FIELD(targetList); > + READ_NODE_FIELD(cols); > + READ_NODE_FIELD(values); > + READ_ENUM_FIELD(override, OverridingKind);