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 1nDaX8-0000Tv-SR for pgsql-hackers@arkaria.postgresql.org; Fri, 28 Jan 2022 23:19:59 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nDaX7-0001YI-G7 for pgsql-hackers@arkaria.postgresql.org; Fri, 28 Jan 2022 23:19:57 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nDaX7-0001Y9-0G for pgsql-hackers@lists.postgresql.org; Fri, 28 Jan 2022 23:19:57 +0000 Received: from mail-il1-x129.google.com ([2607:f8b0:4864:20::129]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nDaX2-00084L-FW for pgsql-hackers@lists.postgresql.org; Fri, 28 Jan 2022 23:19:56 +0000 Received: by mail-il1-x129.google.com with SMTP id c18so156818ilr.3 for ; Fri, 28 Jan 2022 15:19:52 -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=nBMNgpKXe8PXQkb7MsRA++jHiEoElCPairusGIvGf14=; b=f5ofJC6KGbDpAZ0fmhYV/ZxtRN00qqGnJJ4ra6imkwgxFrqQKbvlviFdk0R55MAYu9 gIU5beO2kVt8ofFNWjlhAqH+3ZTnf3Y/O+SZbB+26XKcZ1gVbQK53EK4YXAocKDjMO+C kzDzRHFwkQAOvXC5ppz1c2NiZ4Uu0mO7tUr0tHODjkTYD6NgCbDzmNZHB99aBLsDTf5j SMdLxxikzu78KWAL6qi7wPsKRZYPtMkW7tjddz8xLDW5asidJtaQZ8Xh/yfOhRzwV6lf M5cbgqoE+QEj6S/hMvB4H0tkE04GvFrv6gAJ0EbyF6Z5/Upkl7B9rBXvul550Dunh6St ql4g== 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=nBMNgpKXe8PXQkb7MsRA++jHiEoElCPairusGIvGf14=; b=Gt3QHCSLKxT1IXcGzSBBxa97WFQ3boStG7gYAUpUfAMCxDsnzYz/1NmZm12GJFYwwA WFUI12swO0P/4byvvXoiSkI+1UbLxb2izxy/DhEQYpG0gfew2fS+VhBU/7R604i5jMCV ue2i97YFTjPZdO8e5oTULIVjEPE8DvsBamZigcfZ2HbrmU1pLMNS6R+c5ObsyzlJtsOX 9AcqcHp39lEh4bxmgMGijeOxDG1OQOsHsdB54j0j+dwHbZwEsjIxTeeQziS4SIlHXKpP HN3X7yXFa4zLECGbenCfRHto3O6dhrLdHNUMbAVf0BQyHJ6ohugeZIPu22jl2l9jEeVC kH4A== X-Gm-Message-State: AOAM532OfwGFqc5k1G0nFTmdF7Gq2fjezUBpcaJC0JQ4up9OVLak9X6G ftp3HihXzgVb7hY3W2sA1sznLA== X-Google-Smtp-Source: ABdhPJzxmUj7L1mr54E6Pa2CQbxk6KTGtJfgAdVoGPa2xyzbjn7mxGzoPlSVQOTxExZGIPHh6VCF4A== X-Received: by 2002:a92:2605:: with SMTP id n5mr7603927ile.230.1643411990422; Fri, 28 Jan 2022 15:19:50 -0800 (PST) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id u8sm14557530ilb.39.2022.01.28.15.19.49 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Jan 2022 15:19:49 -0800 (PST) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id A891D800BCE; Fri, 28 Jan 2022 17:19:48 -0600 (CST) Date: Fri, 28 Jan 2022 17:19:48 -0600 From: Justin Pryzby To: Alvaro Herrera Cc: pgsql-hackers@lists.postgresql.org, Simon Riggs , Tomas Vondra , Zhihong Yu , Daniel Westermann , Amit Langote , Japin Li , Erik Rijkers , Jaime Casanova Subject: Re: support for MERGE Message-ID: <20220128231948.GI23027@telsasoft.com> References: <202201202106.tbs3a6tyk453@alvherre.pgsql> <202201282027.jt555atu6hlh@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <202201282027.jt555atu6hlh@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 Fri, Jan 28, 2022 at 05:27:37PM -0300, Alvaro Herrera wrote: > The one thing I'm a bit bothered about is the fact > that we expose a lot of executor functions previously static. I am now > wondering if it would be better to move the MERGE executor support > functions into nodeModifyTable.c, which I think would mean we would not > have to expose those function prototypes. It's probably a good idea. If you wanted to avoid bloating nodeModifyTable.c, maybe you could #include "execMerge.c" From commit message: > MERGE does not yet support inheritance, It does support it now, right ? From merge.sgml: "If you specify an update action...": => should say "If an update action is specified, ..." s/an delete/a delete/ ".. the WHEN clause is executed" => should say "the WHEN clause's action is executed" ? " If a later WHEN clause of that kind is specified" => + COMMA > --- a/doc/src/sgml/ref/allfiles.sgml > +++ b/doc/src/sgml/ref/allfiles.sgml > @@ -159,6 +159,7 @@ Complete list of usable sgml source files in this directory. > > > > + > > > Looks like this is intended to be in alpha order. > + insert, update, or delete rows of a table based upon source data based on ? > --- a/src/backend/executor/README > +++ b/src/backend/executor/README > @@ -41,6 +41,19 @@ be used for other table types.) For DELETE, the plan tree need only deliver > junk row-identity column(s), and the ModifyTable node visits each of those > rows and marks the row deleted. > > +MERGE runs one generic plan that returns candidate change rows. Each row > +consists of the output of the data-source table or query, plus CTID and > +(if the target table is partitioned) TABLEOID junk columns. If the target s/partitioned/has child tables/ ? > case CMD_INSERT: > case CMD_DELETE: > case CMD_UPDATE: > + case CMD_MERGE: Is it intended to stay in alpha order (?) > + case WCO_RLS_MERGE_UPDATE_CHECK: > + case WCO_RLS_MERGE_DELETE_CHECK: > + if (wco->polname != NULL) > + ereport(ERROR, > + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), > + errmsg("target row violates row-level security policy \"%s\" (USING expression) for table \"%s\"", > + wco->polname, wco->relname))); The parens around errcode are optional and IMO should be avoided for new code. > + * This duplicates much of the logic in ExecInitMerge(), so something > + * changes there, look here too. so *if* ? > case T_InsertStmt: > case T_DeleteStmt: > case T_UpdateStmt: > + case T_MergeStmt: > lev = LOGSTMT_MOD; > break; alphabetize (?) > + /* selcondition */ > + "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " > + CppAsString2(RELKIND_PARTITIONED_TABLE) ") AND " > + "c.relhasrules = false AND " > + "(c.relhassubclass = false OR " > + " c.relkind = " CppAsString2(RELKIND_PARTITIONED_TABLE) ")", relhassubclass=false is wrong now ? > +-- prepare > +RESET SESSION AUTHORIZATION; > +DROP TABLE target, target2; > +DROP TABLE source, source2; > +DROP FUNCTION merge_trigfunc(); > +DROP USER merge_privs; > +DROP USER merge_no_privs; Why does it say "prepare" ? I think it means to say "Clean up" WRITE_READ_PARSE_PLAN_TREES exposes errors in make check: +ERROR: targetColnos does not match subplan target list Have you looked at code coverage ? I have an experimental patch to add that to cirrus, and ran it with this patch; visible here: https://cirrus-ci.com/task/6362512059793408 -- Justin