Re: Idea: Avoid JOINs by using path expressions to follow FKs

From: Vik Fearing <vik(at)postgresfriends(dot)org>
To: Joel Jacobson <joel(at)compiler(dot)org>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Andrew Dunstan <andrew(at)dunslane(dot)net>
Cc: Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Idea: Avoid JOINs by using path expressions to follow FKs
Date: 2021-03-29 14:17:50
Message-ID: 916290b8-676e-5cc6-3bcf-5321c1d08300@postgresfriends.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 3/29/21 11:59 AM, Joel Jacobson wrote:
> On Sun, Mar 28, 2021, at 16:04, Tom Lane wrote:
>> I'm imagining a syntax in which
>> you give the constraint name instead of the column name. Thought
>> experiment: how could the original syntax proposal make any use of
>> a multi-column foreign key?
>
> Thanks for coming up with this genius idea.
>
> At first I didn't see the beauty of it; I wrongly thought the constraint name needed to be
> unique per schema, but I realize we could just use the foreign table's name
> as the constraint name, which will allow a nice syntax:
>
> SELECT DISTINCT order_details.orders.customers.company_name
> FROM order_details
> WHERE order_details.products.product_name = 'Chocolade';
>
> Given this data model:
>
> CREATE TABLE customers (
> customer_id bigint NOT NULL GENERATED ALWAYS AS IDENTITY,
> company_name text,
> PRIMARY KEY (customer_id)
> );
>
> CREATE TABLE orders (
> order_id bigint NOT NULL GENERATED ALWAYS AS IDENTITY,
> customer_id bigint NOT NULL,
> PRIMARY KEY (order_id),
> CONSTRAINT customers FOREIGN KEY (customer_id) REFERENCES customers
> );
>
> CREATE TABLE products (
> product_id bigint NOT NULL GENERATED ALWAYS AS IDENTITY,
> product_name text NOT NULL,
> PRIMARY KEY (product_id)
> );
>
> CREATE TABLE order_details (
> order_id bigint NOT NULL,
> product_id bigint NOT NULL,
> PRIMARY KEY (order_id, product_id),
> CONSTRAINT orders FOREIGN KEY (order_id) REFERENCES orders,
> CONSTRAINT products FOREIGN KEY (product_id) REFERENCES products
> );

If you write your schema like this, then it becomes standards compliant:

CREATE TYPE customers AS (
company_name text
);
CREATE TABLE customers OF customers (
REF IS customer_id SYSTEM GENERATED
);

CREATE TYPE orders AS (
customer REF(customers) NOT NULL
);
CREATE TABLE orders OF orders (
REF IS order_id SYSTEM GENERATED
);

CREATE TYPE products AS (
product_name text
);
CREATE TABLE products OF products (
REF IS product_id SYSTEM GENERATED
);

CREATE TABLE order_details (
"order" REF(orders),
product REF(products),
quantity integer,
PRIMARY KEY ("order", product)
);

And the query would be:

SELECT DISTINCT order_details."order"->customer->company_name
FROM order_details
WHERE order_details.product->product_name = 'Chocolade';

Postgres already supports most of that, but not all of it.
--
Vik Fearing

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message David Steele 2021-03-29 14:32:29 Re: pgbench stopped supporting large number of client connections on Windows
Previous Message Arne Roland 2021-03-29 14:02:35 Re: Rename of triggers for partitioned tables