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 1qHJxb-0000lt-U0 for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Jul 2023 08:03:33 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1qHJxa-0005Kb-Gq for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Jul 2023 08:03:30 +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 1qHJxY-0005KS-PD for pgsql-hackers@lists.postgresql.org; Thu, 06 Jul 2023 08:03:30 +0000 Received: from out3-smtp.messagingengine.com ([66.111.4.27]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qHJxV-002Jm6-A5 for pgsql-hackers@lists.postgresql.org; Thu, 06 Jul 2023 08:03:27 +0000 Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id CEADB5C0111; Thu, 6 Jul 2023 04:03:23 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Thu, 06 Jul 2023 04:03:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eisentraut.org; h=cc:cc:content-transfer-encoding:content-type:content-type :date:date:from:from:in-reply-to:in-reply-to:message-id :mime-version:references:reply-to:sender:subject:subject:to:to; s=fm1; t=1688630603; x=1688717003; bh=pMLgAVjNMNeEg7sWqW6EoWCN2 SmVydXWpDtXtEjTV7k=; b=JqyxRLzwLrhwLu207rlyhXnu7NWwnTanD5nv2xqcB mL8B+30+c4ldR6JX45iVm++gpWQl2iotKqFaqTad6dGZaRVm6dQdvIpr586cOU4e bsF11J9fzQYMFXFSaAtsqV+2jy78PGKFJq2UJu1Qz250PGOpiiZSs3z/+EP1mbMF aUYjU7ZUrnmGdxv/tXpNnLpffXsQnzxYq2Clqg9E3/YpN46/iTeDXNW4AVmSSgrN NriNOW3YfP8BtZfl+LgFznkeOHCzLomhaf4P9jO3dWs1WERRx7NWMkTfWYGdXFen 1XRbC6Tv2pZ6zgtEcagrtQLnPjHg0/Red1UCCOPpHgHIg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:sender:subject:subject:to:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1688630603; x=1688717003; bh=pMLgAVjNMNeEg7sWqW6EoWCN2SmVydXWpDt XtEjTV7k=; b=PYRuLzUrBWdgcvIfPFp0RR7uqUl7Y3L6Boyko9lLMllQqsFvYzR jodka60bCLN6Pn97nvVa3jFK51pD//rFzp8xfsGftVEWG3bFk94zgTPEhJItyHAc aM3Oejw4nq0pyiuNapCjX6+UQAPCjzNYNst5bTM/YhndimnPckxM+5SgM5umh6l8 O7FtEWqG1f7eqge/Yxb3s0xg9CpeL1N4R9t1bzvtf+UZ2wiKHHghNEOrODPRyWV9 FWvtkPsQJomFTu87RKnJ6qn2JzO1eodEM0MpTawmmeCB2sa0FHrOvLOhANn3GZcL 333urpwqPpNoN6XoopIAmiaHlL1Fc5QB9ZQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedviedrudekgdduvdehucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepkfffgggfuffvvehfhfgjtgfgsehtjeertddtfeejnecuhfhrohhmpefrvght vghrucfgihhsvghnthhrrghuthcuoehpvghtvghrsegvihhsvghnthhrrghuthdrohhrgh eqnecuggftrfgrthhtvghrnhepheeiuefhleelfeeikeehkefgkeeggfevheeuvdejveet tdegleekffffieekuedtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrg hilhhfrhhomhepphgvthgvrhesvghishgvnhhtrhgruhhtrdhorhhg X-ME-Proxy: Feedback-ID: ie0a040ee:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 6 Jul 2023 04:03:22 -0400 (EDT) Message-ID: Date: Thu, 6 Jul 2023 10:03:20 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: Re: Exclusion constraints on partitioned tables Content-Language: en-US To: Paul Jungwirth , pgsql-hackers@lists.postgresql.org Cc: Ronan Dunklau , Tom Lane References: <3585070.1671149527@sss.pgh.pa.us> <9ad3257d-db5b-e54e-f5e0-a54727b19327@illuminatedcomputing.com> <10212835.nUPlyArG6x@aivenlaptop> <608a9a52-0aab-e3a1-40fa-55536b4ef6a9@illuminatedcomputing.com> From: Peter Eisentraut In-Reply-To: <608a9a52-0aab-e3a1-40fa-55536b4ef6a9@illuminatedcomputing.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 17.03.23 17:03, Paul Jungwirth wrote: > Thank you for taking a look! I did some research on the history of the > code here, and I think I understand Tom's concern about making sure the > index uses the same equality operator as the partition. I was confused > about his remarks about the opfamily, but I agree with you that if the > operator is the same, we should be okay. > > I added the code about RTEqualStrategyNumber because that's what we need > to find an equals operator when the index is GiST (except if it's using > an opclass from btree_gist; then it needs to be BTEqual again). But then > I realized that for exclusion constraints we have already figured out > the operator (in RelationGetExclusionInfo) and put it in > indexInfo->ii_ExclusionOps. So we can just compare against that. This > works whether your index uses btree_gist or not. > > Here is an updated patch with that change (also rebased). > > I also included a more specific error message. If we find a matching > column in the index but with the wrong operator, we should say so, and > not say there is no matching column. This looks all pretty good to me. A few more comments: It seems to me that many of the test cases added in indexing.sql are redundant with create_table.sql/alter_table.sql (or vice versa). Is there a reason for this? This is not really a problem in your patch, but I think in - if (partitioned && (stmt->unique || stmt->primary)) + if (partitioned && (stmt->unique || stmt->primary || stmt->excludeOpNames != NIL)) the stmt->primary is redundant and should be removed. Right now "primary" is always a subset of "unique", but presumably a future patch of yours wants to change that. Furthermore, I think it would be more elegant in your patch if you wrote stmt->excludeOpNames without the "== NIL" or "!= NIL", so that it becomes a peer of stmt->unique. (I understand some people don't like that style. But it is already used in that file.) I would consider rearranging some of the conditionals more as a selection of cases, like "is it a unique constraint?", "else, is it an exclusion constraint?" -- rather than the current "is it an exclusion constraint?, "else, various old code". For example, instead of if (stmt->excludeOpNames != NIL) idx_eqop = indexInfo->ii_ExclusionOps[j]; else idx_eqop = get_opfamily_member(..., eq_strategy); consider if (stmt->unique) idx_eqop = get_opfamily_member(..., eq_strategy); else if (stmt->excludeOpNames) idx_eqop = indexInfo->ii_ExclusionOps[j]; Assert(idx_eqop); Also, I would push the code if (accessMethodId == BTREE_AM_OID) eq_strategy = BTEqualStrategyNumber; further down into the loop, so that you don't have to remember in which cases eq_strategy is assigned or not. (It's also confusing that the eq_strategy variable is used for two different things in this function, and that would clean that up.) Finally, this code + att = TupleDescAttr(RelationGetDescr(rel), + key->partattrs[i] - 1); + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot match partition key to index on column \"%s\" using non-equal operator \"%s\".", + NameStr(att->attname), get_opname(indexInfo->ii_ExclusionOps[j])))); could be simplified by using get_attname(). This is all just a bit of polishing. I think it would be good to go after that.