Re: Idea: Avoid JOINs by using path expressions to follow FKs - Mailing list pgsql-hackers

From Vik Fearing
Subject Re: Idea: Avoid JOINs by using path expressions to follow FKs
Date
Msg-id 916290b8-676e-5cc6-3bcf-5321c1d08300@postgresfriends.org
Whole thread Raw
In response to Re: Idea: Avoid JOINs by using path expressions to follow FKs  ("Joel Jacobson" <joel@compiler.org>)
Responses Re: Idea: Avoid JOINs by using path expressions to follow FKs  ("Joel Jacobson" <joel@compiler.org>)
Re: Idea: Avoid JOINs by using path expressions to follow FKs  ("Joel Jacobson" <joel@compiler.org>)
Re: Idea: Avoid JOINs by using path expressions to follow FKs  ("Joel Jacobson" <joel@compiler.org>)
List 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



pgsql-hackers by date:

Previous
From: Arne Roland
Date:
Subject: Re: Rename of triggers for partitioned tables
Next
From: David Steele
Date:
Subject: Re: pgbench stopped supporting large number of client connections on Windows