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.94.2) (envelope-from ) id 1tabKD-003LR3-3R for pgsql-general@arkaria.postgresql.org; Wed, 22 Jan 2025 14:03:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tabKC-00HY86-6Q for pgsql-general@arkaria.postgresql.org; Wed, 22 Jan 2025 14:03:20 +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.94.2) (envelope-from ) id 1tabKB-00HY7x-Ru for pgsql-general@lists.postgresql.org; Wed, 22 Jan 2025 14:03:19 +0000 Received: from mail-oi1-x229.google.com ([2607:f8b0:4864:20::229]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tabK9-000uwk-2E for pgsql-general@lists.postgresql.org; Wed, 22 Jan 2025 14:03:18 +0000 Received: by mail-oi1-x229.google.com with SMTP id 5614622812f47-3eba50d6da7so1599248b6e.2 for ; Wed, 22 Jan 2025 06:03:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1737554597; x=1738159397; darn=lists.postgresql.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=91zSBmvvQHobJk/RzrHdRYi8dTfYEze6G+gjsqabSUE=; b=WY4qUQAE26vJ5Q0SSVi7RfnWcdYrROZN0BXvjJLO338mYUHBhPESvMaI+OgY2MpT0g B3BCLq9cZUV0usLM/tLszIYLNOXe3dx/s/wpMQKULco9+uwyM5P7eXQb+nrkIk0Tmy7G I7V08kFOsmrXobhprL3mqfyrtJeMcTuFj78o3JYXwkvSHNuRolfubSRXw4f/AfK65aup kjVFUvZbQ3PW4l0srP04Z0GR3aeBkpYM9uD8pQ3f+la8W6r3YM0maadeKAYOp7Afr3BX TGga7CC4fGRAOS5ydRBbheyZUHgTG06QaT3WYPZHomME5HVlHT/mItfnMq393aIPPRzx eIsQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737554597; x=1738159397; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=91zSBmvvQHobJk/RzrHdRYi8dTfYEze6G+gjsqabSUE=; b=i0pKhrqDOCl5jVnOK6kkAg5H3Mm6FR7vmxdHTeF0b0gnFNbzQNsm4QLgRubM8cIhzz Dgf/TOHVtDj+o6FjOFtDqCG30lXHp9zmPSXLhO2ravK8sPV5nfkWBYtoV+2hd38ER7JJ xoPKiaJvzcs4DdpAIroOeRF5UWAW0kwhQXAf6EC20wusOyONJpSsrXubU+kj5sEnBhVx 6b0SPq4880J1YUQ3q5HdZXa5bG/bO2WBzkd+S5G+gNJX5m3leQzbjiQ6dgNVCWDC8Ika +quKGXz23WzY4d4+UANfvlDUu1bFse5vUAuIM0VNr7H1Scc65i3sjxkOwdSvgZjkNmTe /pVw== X-Gm-Message-State: AOJu0Yx6pmvNT6S6qpitUmvsWhw+NbMEpY1OBQrcDSilJDi52DhlPYim UzNTWm0dWSDljc1xGFpLiEfQdrU1s/nRxLDXy4fwdb75KrD1mDBQRfV7B4BRAE/YW7He40aaMuR CrpAn+R+Rj8l7Syc4vdx4UhRbKKtvfA== X-Gm-Gg: ASbGncvi4Gyr2DGjfRKJ73umzxK3Q0pXMDm0G8mAE/wm8CcCyod8vXdP82PykruWDAy FoCAQpDt1XnKB4p/pJls8mclbwbpnfhHsQuENdZd3yKp3yuXQcNAc X-Google-Smtp-Source: AGHT+IGji9IjnIxRD4hmpTHvx6FEAGg/GRGopd9ME4lMUxyzMTmoq7BaxSsZB6uw9Xb9Wck1xsNb5dQ9tuQL7v0Dfk4= X-Received: by 2002:a05:6870:6486:b0:29e:76d1:db32 with SMTP id 586e51a60fabf-2b1c0823187mr11468172fac.8.1737554597300; Wed, 22 Jan 2025 06:03:17 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Ron Johnson Date: Wed, 22 Jan 2025 09:03:06 -0500 X-Gm-Features: AbW1kvYS3-sA-fekBbL5RI3nWCRvWlnuF3eGf0yIYRrTC52azgsjme52tV5ZwyM Message-ID: Subject: Re: Automatic deletion of orphaned rows To: "pgsql-generallists.postgresql.org" Content-Type: multipart/alternative; boundary="0000000000008cd209062c4bf4f8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000008cd209062c4bf4f8 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, Jan 22, 2025 at 2:00=E2=80=AFAM Runxi Yu wrote: > Hi, > > While writing a new program, I encountered the following: > > I have three tables: A, B, and X. Rows in X are referenced by A and/or B > via foreign keys, one or more times. I would like to delete all orphaned > rows in X, i.e. a row in X is deleted if and only if it is no longer > referenced by any row in A or B. (When inserting these rows, I would > insert X first, then the reference in A or B, in the same transaction.) > > To the best of my knowledge, there is no such functionality natively > built into PostgreSQL. Alternatives include (1) using triggers or (2) > using application logic. Both would involve locking the row in table X, > and since I don't see a native "reference count" feature in PostgreSQL, > the reference count would have to be maintained as a field in X. Both of > these alternatives could get somewhat messy. In more complex schemas > where circular references may be involved and a mark-and-sweep garbage > collector is preferred, this would be even more difficult to implement. > > I therefore propose a feature, to be able to specify in a table schema > that a row should be deleted if orphaned. For one thing, rows *can't* be orphaned if there's a foreign key reference. That's the whole point of creating a foreign key. As to automatically deleting children, ON DELETE CASCADE has been a feature of foreign keys for at least 20 years. --=20 Death to , and butter sauce. Don't boil me, I'm still alive. lobster! --0000000000008cd209062c4bf4f8 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Wed, Jan 22, 2025 at 2:00=E2=80=AFAM R= unxi Yu <me@runxiyu.org> wrote:=
Hi,

While writing a new program, I encountered the following:

I have three tables: A, B, and X. Rows in X are referenced by A and/or B via foreign keys, one or more times. I would like to delete all orphaned rows in X, i.e. a row in X is deleted if and only if it is no longer
referenced by any row in A or B. (When inserting these rows, I would
insert X first, then the reference in A or B, in the same transaction.)

To the best of my knowledge, there is no such functionality natively
built into PostgreSQL. Alternatives include (1) using triggers or (2)
using application logic. Both would involve locking the row in table X,
and since I don't see a native "reference count" feature in P= ostgreSQL,
the reference count would have to be maintained as a field in X. Both of these alternatives could get somewhat messy. In more complex schemas
where circular references may be involved and a mark-and-sweep garbage
collector is preferred, this would be even more difficult to implement.

I therefore propose a feature, to be able to specify in a table schema
that a row should be deleted if orphaned.

F= or one thing, rows can't=C2=A0be orphaned if there's a forei= gn key reference.=C2=A0 That's the whole point of creating a foreign ke= y.

As to automatically deleting children, ON DELET= E CASCADE has been a feature of foreign keys=C2=A0for at least 20 years.

--
Death to <= Redacted>, and butter sauce.
Don't boil me, I'm still alive.=
<Redacted> lobster!
--0000000000008cd209062c4bf4f8--