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 1wEgZo-004I8I-0l for pgsql-hackers@arkaria.postgresql.org; Mon, 20 Apr 2026 04:49:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wEgZm-000Zx6-24 for pgsql-hackers@arkaria.postgresql.org; Mon, 20 Apr 2026 04:49:38 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wEgZm-000Zwj-12 for pgsql-hackers@lists.postgresql.org; Mon, 20 Apr 2026 04:49:38 +0000 Received: from mail-pf1-x42f.google.com ([2607:f8b0:4864:20::42f]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wEgZk-000000024oD-0iUC for pgsql-hackers@lists.postgresql.org; Mon, 20 Apr 2026 04:49:38 +0000 Received: by mail-pf1-x42f.google.com with SMTP id d2e1a72fcca58-82fa01e86e2so974193b3a.0 for ; Sun, 19 Apr 2026 21:49:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776660573; cv=none; d=google.com; s=arc-20240605; b=RNEhPuJDGUw8AtbwUxND1PPvPkOiNm4fy2aKKz66pjxhckXIkt/IvZ91aBsMSaWY3F isMN6SZY2gLWtGXbOsjk/FlOM+yMGj0gFrrvnJJntp3mChhu2sVvoVowXES9xUiPHvXq trNjpd0FUJND0b9X5+yx8aPg9zjGbSVBi6zdNaQVAtA+Kpqaj54Atdj+VANpoW2pptnq zsKbFf0ay8sRFCaFvYCD9Ouz7+hEcZQvMauGJd+VT04KmaN1BA3FcJZNNSsKG2dNHI3Z WNJuCdiJeLXr7PWTr7VwjO277mNxJkjKZdVnp9hJV+AAgq5RX77YOl2H5qJKiAqQLJ5N H+4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=EMzDiOyirBWktprg7cbEUw/F4OpDY5RuilOVwAklRwo=; fh=8vObSAGcrR+VEyjXzd4PYMJMaDUGiTCPrfcDL69mS0c=; b=YCJhAZdjgdkIVLDB4BWDCNABuY37rVZxiL6uIU/WB87b/CW5iX4NmZEiUNxutJbUEB sg3+/Ql0nSm1esdBp2fhL2nROWHABp4rseq6uxQbwFNfXWhY0lFyYs1iNzZnopCHuHJO W7gEOH0qHiV3st+3MySupm1ofRckxkp/KThCutuk+w44UErP1JhPJIHl1F9XgLar238a 8ORXkzqgAJuoqNzk9nWVBuU+fDbgsqi3YE9RVzJNJvP53GUof1t9tUDLiqLL5mP9kILz 2+xsL+q0uh+KsvVT1RRFrXk19GGybr76e9Lm39pjHzfZ4Q5LW2SwiPivQhOsAEqx8/Ax fyyg==; 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=1776660573; x=1777265373; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=EMzDiOyirBWktprg7cbEUw/F4OpDY5RuilOVwAklRwo=; b=P+Lt0ivKLrj0GEnY0H3eSEBg8BGH2RT8CzowIcSTMNN1MFKs9cxr6wkRTN6iMbRtZh 276Uh8GVZu9ADTqTMCxHl8AMjEIV79jPz89wGLxBSbMcp+263HOcrj9LKF507Dl+cusl GBzQ8HljHAM+XgzMQj7QvdELmACqG2zbj1wEL0BABe/4I6sLLhvV12TLjx4H1a+JV7sv B3p5jW/5DZgy4He3J4bpwERbC6WKSq4/smYfA5laQKrz61a1uaqXqOf6KYr/q/QvjxZo t+wt49Gan46ujf5G2K/slUqPJ8mEbGqDdxryh0RQnG7XduVIG98kobVafFEu/h5nvxNQ 4EAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776660573; x=1777265373; h=content-transfer-encoding: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=EMzDiOyirBWktprg7cbEUw/F4OpDY5RuilOVwAklRwo=; b=cFR1u5SgYvEG9htfSH4GrOzkvAwzCJGOwPs6TeMP/zKJTeooOLWyEUN1NGJs3VKfY8 qvv7nDB1xF0kr8LYVE4GmVZGhmaxVp4H0C3Wii5CeERiYID45F+syZItTr1jSoUImQm0 6syHdYHbWh1WUZP+85cTTVWajXhvOaRcTZ+PE4HcV6w/4TGl0gUKK3KZHvTPHRCL588v QQ6Q0GGEPxFnhUVc0lPIdQoTxuMnTk5ao7qkhZHnpYfkkwwOwZcEVuUEusVmyAWmB/Ig Hf7Sd2aiDZng2yyDjrBpE2Jo0mTbaG73hWuVrfGd2v28U+kyunKtIIn+jH7hh0nGT8cV 69vg== X-Forwarded-Encrypted: i=1; AFNElJ+q2LNajQ9AQjy5A8Hh8E/8GK/e0duyrjiAdRcUOqxQ0545vbv6fBpTF/0d+ur+uwsZLHGVpoOnXkMpKMd0@lists.postgresql.org X-Gm-Message-State: AOJu0Yz0EsjXARKUdUd2JyEhkPyzE3EfKJPhZFCJsKbyXD0JoXhnQIcF VANDyiSNNs0BX69oWo7/TkQvSd0StEDQn+TG/2/jo4IAyr67bLVGsvRYsTrIeJveDfZ2G32ftro 2U/8h4DxeeyenT/DBexg4oSJD9lK1ESg= X-Gm-Gg: AeBDieuepJvO16y5u/nuRav19VNKv0JDJ7ia078R2CzQMGG1Nnaeh3r7UPntks/QjVk Cct+Yxqba/H6aZReVPFA+IRVAK0KAv1dd2Ojgaxzahiu9g9L+HlmWD76RyUN+yl3ug8S0+l7Scy 1DyKuyR+qpISIhpPa/qo24umKRSQVoJe5jqUtuH8x5LvXzcA3jSVBPxz6EeO4xc1iASu717vX4C HJ7j2YAK0qphhkSYIAfbTtAJpxQF0vRDaR4OwaVw652UlEmhab+3HA0RSDHghlC172GWlPcW1KY DWnWpa+d/8LhISDhONSWjGAaNsX36xHIOfGSES6jhjZ9JKhkYHVXEZKbhqGZtvK4vtL4zuZvD2g = X-Received: by 2002:a05:6a00:4ac9:b0:823:9c6:1985 with SMTP id d2e1a72fcca58-82f8c827aa3mr12096141b3a.16.1776660572886; Sun, 19 Apr 2026 21:49:32 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Amit Langote Date: Mon, 20 Apr 2026 13:49:16 +0900 X-Gm-Features: AQROBzArxSsW9PXn7fva0E4snzjhEwvVFx2ujF1jn_oyz1wVraFa70mk23rLKF8 Message-ID: Subject: Re: POC: Comparison of partitioning key values To: John Mikk Cc: David Rowley , pgsql-hackers@lists.postgresql.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi John, On Fri, Apr 17, 2026 at 5:35=E2=80=AFAM John Mikk wr= ote: > > Dear David, thank you for the detailed response. > > I understand your concerns, so I have rethought my approach a bit and wou= ld like to discuss, > in general terms, the concept that I would try to implement. > > The ability to define a B-tree operator class (opclass) in the clause: > `PARTITION BY RANGE ( { column_name | ( expression ) } [ opclass ] [, ...= ] )` > allows partitioning over a fairly broad class of sets with a defined orde= r relation. > For example, one can obtain an elegant example using an extension > for ordinary fractions (p/q) represented as `row(p,q)` with a natural > B-tree operator class for the order relation of ordinary fractions: > > ```sql > drop table if exists axis cascade; > > create table axis ( > id serial, > key fraction, > label text > ) partition by range (key fraction_ops); > > create table segment_1 partition of axis for values from ((0,1)::fraction= ) to ((1,3)::fraction); > create table segment_2 partition of axis for values from ((2,5)::fraction= ) to ((4,5)::fraction); > create table segment_3 partition of axis for values from ((15,45)::fracti= on) to ((2,5)::fraction); > -- segment_1,2,3 : [0, 1/3], [2/5, 4/5], [1/3, 2/5], where 15/45 =3D=3D 1= /3 > > insert into axis(key,label) select (1,5)::fraction, '1/5'; > -- insert to segment_1 > insert into axis(key,label) select (1,2)::fraction, '1/2'; > -- insert to segment_2 > insert into axis(key,label) select (1,3)::fraction, '1/3'; > -- insert to segment_3 > ``` > > However, for multidimensional data structures where one desires > a multidimensional partitioning key using a B-tree, the necessary orderin= g cannot be established. > It is easy to prove that when attempting to introduce > the concept of "to the left" (less than) / "to the right" (greater than) = for rectangles on a plane, > the transitivity of such a relation is violated. > > To achieve the intended goal, > it would likely be necessary to use the GiST access method. > According to the documentation, however, > only B-tree is applicable when defining an operator class for a range par= titioning key. > > **Proposal:** Make GiST available for partitioning in the `opclass` claus= e of `PARTITION BY RANGE`. Thanks for the follow-up and the fraction example. The fraction case already works under RANGE today, as you show, and nothing needs to change there, or at least that's how I read that part. I agree with David that the grid case wants a new strategy rather than a reinterpretation of RANGE, and I'd push back on making GiST available in RANGE's opclass slot specifically. The GiST opclasses you'd actually want for this use case describe overlap and containment, not order, so applying the RANGE machinery here seems wrong to me. PARTITION BY RANGE has been around for about ~9 years and most users understand what it means, so making it accept GiST opclasses would be more confusing than helpful. But the fact that you reached for GiST tells me the grid case wants something spatial, and I've sometimes wondered whether something along the lines of PARTITION BY BOX for rectangular partitioning could work as a new strategy. The per-dimension non-overlap check you describe would cover partition creation. The same logic applies to tuple routing and pruning, though the algorithms and data structures would require careful design to scale with many partitions. Part of what got me thinking about BOX partitioning is the growth of pgvector, where smaller indexes per partition could help when index design hits scaling limits. Whether the decompositions there would actually look like boxes is another question that I haven't studied very deeply, but it's one more reason to think about spatial partitioning strategies. --=20 Thanks, Amit Langote