forked from postgres/postgres
-
Notifications
You must be signed in to change notification settings - Fork 0
Fix CTE handling in foreign key join parsing #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
joelonsql
wants to merge
7
commits into
jj/fk-joins-6
Choose a base branch
from
codex/fix-cte-handling-in-parse-fkjoin-c
base: jj/fk-joins-6
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This commit introduces a new SQL syntax, Foreign Key Joins, allowing joins to be specified based on existing foreign key constraints. This provides a more declarative and self-documenting way to express joins that follow defined relationships, enhancing query clarity and resilience to schema changes like column or table renames. The new syntax is: from_item join_type from_item KEY ( column_name [, ...] ) { <- | -> } from_reference ( column_name [, ...] ) The directionality (`->` or `<-`) indicates which table is referencing and which is referenced, aligning with the foreign key definition. Key aspects of the implementation and behavior include: 1. **Constraint Validation:** The parser and analyzer verify that a matching foreign key constraint exists between the underlying base tables corresponding to the joined relations. The columns specified in the KEY clause must match (order-insensitively) the columns defined in an existing foreign key constraint in the specified direction. 2. **Derived Table Validation:** The feature extends validation beyond base tables to derived relations (views, subqueries, CTEs). To ensure semantic correctness equivalent to the underlying foreign key, two critical properties are checked and must hold through all layers of derived relations: * Uniqueness Preservation: The referenced columns must remain unique in the derived relation. Operations like joins that might duplicate referenced rows invalidate the FK join. * Set Containment (Row Preservation): The referenced derived relation must contain all rows necessary to satisfy the foreign key relationship. Filtering operations (WHERE, LIMIT, HAVING, RLS policies) on the referenced side that could remove potentially referenced rows are disallowed. 3. **Implementation Details:** * Introduces `parse_fkjoin.c` for transformation and validation logic. * Adds `ForeignKeyClause` (parse node) and `ForeignKeyJoinNode` (analysis node). * Adds `RTEId`, `uniqueness_preservation`, and `functional_dependencies` fields to `RangeTblEntry` to track necessary properties through query analysis, particularly for derived tables. `RTEId` provides a globally unique identifier for base relation RTEs. * Updates `gram.y` and `scan.l` for the new syntax and operators. * Modifies dependency tracking (`dependency.c`) to add dependencies on the underlying `pg_constraint` OID for views using FK joins. * Implements view revalidation (`view.c`) to ensure that replacing a view doesn't break dependent views that use FK joins based on the old definition. Violations during revalidation now raise a specific error. * Updates ruleutils (`ruleutils.c`) to deparse the KEY syntax correctly for view definitions, EXPLAIN, etc. * Extends ECPG and PL/pgSQL parsers to recognize the new syntax. 4. **Documentation and Testing:** * Adds documentation for the new syntax to `select.sgml`. * Includes extensive regression tests (`foreign_key_join.sql`) covering various scenarios, including syntax, basic usage, composite keys, derived tables, error conditions, view revalidation, and partitioned tables. Example Usage: -- Assuming orders.customer_id REFERENCES customers.id SELECT o.*, c.name FROM orders o JOIN customers c KEY (id) <- o (customer_id); -- Assuming payments.order_id REFERENCES orders.id SELECT o.*, p.amount FROM orders o JOIN payments p KEY (order_id) -> o (id); This feature aims to make SQL queries involving relational integrity constraints more robust and easier to understand. If the validation rules are not met during query planning, an error is raised, preventing potentially incorrect results that could arise if the derived tables no longer accurately reflect the underlying foreign key relationship.
fcfd0ce
to
002872c
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
find_cte_for_rte
helperTesting
git status --short