Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wBavQ-001Csb-1P for pgsql-hackers@arkaria.postgresql.org; Sat, 11 Apr 2026 16:11:12 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wBavN-00GyRe-0f for pgsql-hackers@arkaria.postgresql.org; Sat, 11 Apr 2026 16:11:10 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wBavM-00GyRU-2Y for pgsql-hackers@lists.postgresql.org; Sat, 11 Apr 2026 16:11:09 +0000 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wBavL-00000000Vjr-2PF3 for pgsql-hackers@lists.postgresql.org; Sat, 11 Apr 2026 16:11:08 +0000 Received: by mail-ed1-x533.google.com with SMTP id 4fb4d7f45d1cf-66c24b42efbso4615646a12.2 for ; Sat, 11 Apr 2026 09:11:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775923866; cv=none; d=google.com; s=arc-20240605; b=k0t+n6+hM3OeFiw3I3kp9R0vfA3zZF1NgDqBmzN/DohssUxfJnwRlkQ1zXldlSYqW5 vHjgFo6RPOQhPm2Vy2PQZ7PqrnDaZoAy10Cx0ySMjgTk7G1UGFrPfJfwRa9ENFllBfFM yqSwhUZ1d0xGAIEMAZeSgOr0yFMI4UySci4KsEET0wdNAWuiAE+yldygpen67fz/lSdp wvssgThaucp5NBknkGND+N4xdpFvSf/FBMFk4ELzNYwAiYFyk7Mx5SoxTxlD8aQs19z/ TU5H8ZNHicX9e+LmVEA98weD4KYcUHSGPvsMEhcLZX0eKe/dC6hhuOgrSEnC2NRpslbX X/KQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=WAK8XkGEIgpY/wb6CC1sAEL9z3ix9xRSYpZZLFSQxHk=; fh=5QtjYFxOr/zj0Cbic6RlBLSNyn9mrpMYSBZisjr1jD0=; b=ekDMUcVoRYF2fjDc+wUwfr2mtssoezqljhWfbT5Z6xsoa/TRcmzWQ4aDyibbzsyWCx 0oIp7fNimErx5sfcVZCx2BZzqOrRY3260irMQClN7NF4+4FG1yA2/qhf+RtmJvny9/Ql ltoQj6CEXJMLpTMwttdzHLce/BhWPHej6xe0JG4zOOagwGuqBJNR+SxVTpsrFzn4DKTN 5hLQWaSmjk9WWmWZRcuWtnn0JOBrbAErUPPy3UdBhaKbPvlnXjOf/M+IxqQyaat03c/z NHHgUqg0siDERVvKJJbB9clHhQcG+4fHI1bNBsPinIweorRhKIQjaeE9jL1HONv8Va25 ynew==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775923866; x=1776528666; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=WAK8XkGEIgpY/wb6CC1sAEL9z3ix9xRSYpZZLFSQxHk=; b=ZDUGuslF5vBg7kr0vzYjpD6+GXPG4t32UNc6v0lvFUwrEkrdDX/sVHhwaqAn9Y2BPQ Uujpz2aiCAxz6wiG0/76w+1OFMUvG/l8mT9RXXTanaVqYtkdY4qhGyRAE7sod7+jUe1I p8aQ1EWUjVAwe3Bd0hVcqM/6fNy9S3E2yI9YWVMjNFxyUbayPCUiwUwBhRYy+7serV00 Ppy0Ox5/u2DStF3hCZyLJIGYEpxyrjIB9I4NDYu4avzLCaiCdxlFZyCA1Yq4oAKf2tXt xApkxRcydaeR4MU8ZI2+a8kliVCRNvhZXTg+Xk0JSGb7GND+D4nQWkwkVpST1PWvJ5j0 IMxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775923866; x=1776528666; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=WAK8XkGEIgpY/wb6CC1sAEL9z3ix9xRSYpZZLFSQxHk=; b=cVwC+AwhKLPk8dc1Ku8rkTpInrtcQHl02949ZSjYdz5nLWPzkv3nIxDcXUIraLvFqL AX46P9N6bIpyIIUijmO86ZxU8rS4xl5ZUp7+p0v/DsuWBqYBeehpYNd6wfjeCiaY8Tby kjNmTrTiBEi6iqILEhNfLOsE4Fd/C8ci6uAFueifjcuqK8cA5rGIfEKJwl1AdQmI57QA Njg5Cp5E+MGNpUAgEfzGDSCLot6W8SUp42Gd+D8FodqaFlSlbLK7+oe9jbb4K9FegGoa enBe4/EOhAuNjOXgNK+3yJMEaRgl0s3ZWo7JWQX6c08D7pDVuRD5+/x7n1mPwlVoF3WX C28Q== X-Forwarded-Encrypted: i=1; AJvYcCXd59yTHM7o4raAs2RliC0dPHAG2R1YvP8vrbNA0wsnGYZNvvGWdMAsBErbrAMzfql7yjSd7A+FlG/RklgW@lists.postgresql.org X-Gm-Message-State: AOJu0Ywo/n3hEpOPJvIXVsmUyJAF1gWCzYrp4URALLoMUNqEn8rciTC5 tZj/DZooQVGwwxY4RJ5z9UYUMGzqTHGecYU0z3TNHSIGouuEAys8HL4khJ5qn/nyRPcyYa2TZXB R60z5Ga5bcU1Osros+7g+0p+Kpvta5eM= X-Gm-Gg: AeBDietDq2GIdGsrsA1a9vuCNeMmllPjvIwiRCSMnQuO6b7cWce8jlyZTXdgMbSzRwk bTEz53dHUC/0WqLuiWhKstUhrVwuO3efnm2Xr73oo9MUhY/DTaKcITb+HT41g10eentjXO6MyT1 eW4MK8L4YuL2yJJ3uQoo8Ajc73CYbo3GS6WeFFO0Mi394rRcOkvTsYObaZ9YKI5FO57yEMcckXI q7iFoY2buBEFotWX/qPEkyirToVzrflXMRm06sy8loZ5eWgsnG0xE17UP461yXIRHUYfhpM4D6e zaihbw== X-Received: by 2002:a05:6402:3506:b0:661:7ba8:a47c with SMTP id 4fb4d7f45d1cf-670798f0633mr3650572a12.23.1775923866101; Sat, 11 Apr 2026 09:11:06 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Sami Imseih Date: Sat, 11 Apr 2026 11:10:54 -0500 X-Gm-Features: AQROBzBLE67W5_W1-C66PQsuYOzYeWRtkl_aXbBX9XTHsZ-L28MF6Xk8y94KikE Message-ID: Subject: Re: [PATCH] Fix: Partitioned parent index remains invalid after child indexes are repaired To: Haibo Yan Cc: Mohamed ALi , pgsql-hackers@lists.postgresql.org Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, Thanks the report > 6. The parent index remains `indisvalid = false` permanently. No SQL > command can fix it. Yes, that seems confusing. the indisvalid on a parent partition should reflect the state of all index partitions; true if all index partitions are valid, and false if any index partition is invalid. I think this can only become an issue in practice with the combination of CREATING a parent index ONLY ( because the parent indisvalid is marked as false initially), then one of the partition indexes becoming invalid, then the expectation would be that if we REINEX/re-create the child index, a re-attach of this index will set the parent index indisvalid to true. The state of an invalid parent index ( with all children being valid ) breaks the ON CONFLICT case: ``` DROP TABLE IF EXISTS pt; CREATE TABLE pt (a int, b int) PARTITION BY RANGE (a); CREATE TABLE pt_1 PARTITION OF pt FOR VALUES FROM (1) TO (100); CREATE TABLE pt_2 PARTITION OF pt FOR VALUES FROM (100) TO (200); CREATE UNIQUE INDEX pt_a_idx ON pt (a); -- ON CONFLICT works fine here INSERT INTO pt VALUES (1, 1); INSERT INTO pt VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = EXCLUDED.b + 1; -- Manually invalidate the parent index EXPLAIN ANALYZE UPDATE pg_index SET indisvalid = false WHERE indexrelid = 'pt_a_idx'::regclass; SELECT c.relname, i.indisvalid, i.indisready FROM pg_class c JOIN pg_index i ON c.oid = i.indexrelid WHERE c.relname LIKE 'pt_%' ORDER BY c.relname; -- Now ON CONFLICT fails now EXPLAIN ANALYZE INSERT INTO pt VALUES (1, 1) ON CONFLICT (a) DO UPDATE SET b = EXCLUDED.b + 1; -- ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification ``` because of: ``` /* We require at least one indisvalid index */ if (results == NIL || !foundValid) ereport(ERROR, (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), errmsg("there is no unique or exclusion constraint matching the ON CONFLICT specification"))); ``` in infer_arbiter_indexes() in plancat.c > Bug 1: REINDEX Does Not Validate Parent I don't think that a REINDEX should attempt to set the parent index indisvalid. It seems the responsibility for this falls squarely on the ATTACH PARTITION command, as it currently does. Would the right solution here be to try to have the ATTACH PARTITION check if the parent index is not valid, then validatePartitionedIndex() ? ```` diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index eec09ba1ded..a46af023689 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -22029,6 +22029,14 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) free_attrmap(attmap); validatePartitionedIndex(parentIdx, parentTbl); + } else if (!parentIdx->rd_index->indisvalid) + { + /* + * The index is already attached but the parent isn't valid yet. + * Check if all partitions now have valid indexes, and if so, + * mark the parent index as valid. + */ + validatePartitionedIndex(parentIdx, parentTbl); } ```` We can add some additional documentation about this in the "ATTACH PARTITION index_name" documentation [1] so users have a way out of this condition ? [1] [https://www.postgresql.org/docs/current/sql-alterindex.html] -- Sami Imseih Amazon Web Services (AWS)