@@ -404,18 +404,18 @@ The column-constraint or default clause may be as follows:
404404 * - NOT NULL
405405 - means "it is illegal to assign a NULL to this column"
406406 * - PRIMARY KEY
407- - explained in the later section
408- :ref: `" Table Constraint Definition" <sql_table_constraint_def >`
407+ - explained in the
408+ :ref: `Table constraint definition <sql_table_constraint_def >` section
409409 * - UNIQUE
410- - explained in the later section
411- " Table Constraint Definition"
410+ - explained in the
411+ :ref: ` Table constraint definition < sql_table_constraint_def >` section
412412 * - CHECK (expression)
413- - explained in the later section
414- " Table Constraint Definition"
413+ - explained in the
414+ :ref: ` Table constraint definition < sql_table_constraint_def >` section
415415 * - foreign-key-clause
416- - explained in the later section
417- :ref: `" Table Constraint Definition for foreign keys"
418- <sql_foreign_key>`
416+ - explained in the
417+ :ref: `Table constraint definition for foreign keys
418+ <sql_foreign_key>` section
419419 * - DEFAULT expression
420420 - means
421421 "if INSERT does not assign to this column
@@ -493,7 +493,7 @@ Data types may also appear in :ref:`CAST <sql_function_cast>` functions.
493493 .. _sql_table_constraint_def :
494494
495495++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
496- Table Constraint Definition
496+ Table constraint definition
497497++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
498498
499499Syntax:
@@ -617,143 +617,93 @@ causes no error message, although (s1, s1) is probably a user error.
617617.. _sql_foreign_key :
618618
619619++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
620- Table Constraint Definition for foreign keys
620+ Table constraint definition for foreign keys
621621++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
622622
623- FOREIGN KEY constraints look like this: | br |
624- :samp: ` FOREIGN KEY ( { referencing-column-name } [, { referencing-column-name } ...]) REFERENCES { referenced- table-name } [( { referenced-column-name } [, { referenced-column-name } ...]]) [MATCH FULL] [update-or-delete-rules] `
623+ A :ref: ` foreign key < index-box_foreign_keys >` is a constraint that can be used to enforce data integrity across related tables.
624+ A foreign key constraint is defined on the child table that references the parent table's column values.
625625
626- There is a shorthand: specifying REFERENCES in a :ref: `column definition <sql_column_def_constraint >`.
627-
628- The referencing column names must be defined in the table that is being created.
629- The referenced table name must refer to a table that already exists,
630- or to the table that is being created.
631- The referenced column names must be defined in the referenced table,
632- and have similar data types.
633- There must be a PRIMARY KEY or UNIQUE constraint or UNIQUE index on the referenced column names.
634-
635- The words MATCH FULL are optional and have no effect.
636-
637- If a foreign-key constraint exists, then the values in the referencing columns
638- must equal values in the referenced columns of the referenced table,
639- or at least one of the referencing columns must contain NULL.
640-
641- Examples:
626+ Foreign key constraints look like this:
642627
643628.. code-block :: sql
644629
645- -- A foreign key referencing a primary key in the same table
646- CREATE TABLE t1 (s1 INTEGER PRIMARY KEY, s2 INTEGER, FOREIGN KEY (s2) REFERENCES t1 (s1));
647- -- The same thing with column shorthand
648- CREATE TABLE t1 (s1 INTEGER PRIMARY KEY, s2 INTEGER REFERENCES t1(s1));
649- -- An attempt to violate the constraint -- this will fail
650- INSERT INTO t1 VALUES (1, 2);
651- -- A NULL in the referencing column -- this will succeed
652- INSERT INTO t1 VALUES (1, NULL);
653- -- A reference to a primary key that now exists -- this will succeed
654- INSERT INTO t1 VALUES (2, 1);
655-
656- The optional update-or-delete rules look like this: |br |
657- ``ON {UPDATE|DELETE} { CASCADE | SET DEFAULT | SET NULL | RESTRICT | NO ACTION} `` |br |
658- and the idea is: if something changes the referenced key, then one of these possible "referential actions" takes place: |br |
659- ``CASCADE ``: the change that is applied for the referenced key is applied for the referencing key. |br |
660- ``SET DEFAULT ``: the referencing key is set to its default value. |br |
661- ``SET NULL ``: the referencing key is set to NULL. |br |
662- ``RESTRICT ``: the UPDATE or DELETE fails if a referencing key exists; checked immediately. |br |
663- ``NO ACTION ``: the UPDATE or DELETE fails if a referencing key exists; checked at statement end. |br |
664- The default is ``NO ACTION ``.
630+ FOREIGN KEY ({referencing_column_name} [, {referencing_column_name}...])
631+ REFERENCES {referenced_table_name} [({referenced_column_name} [, {referenced_column_name}...]])
665632
666- For example :
633+ You can also add a reference in a :ref: ` column definition < sql_column_def_constraint >` :
667634
668635.. code-block :: sql
669636
670- CREATE TABLE f1 (ordinal INTEGER PRIMARY KEY,
671- referenced_planet STRING UNIQUE NOT NULL);
672- CREATE TABLE f2 (
673- ordinal INTEGER PRIMARY KEY,
674- referring_planet STRING DEFAULT 'Earth',
675- FOREIGN KEY (referring_planet) REFERENCES f1 (referenced_planet)
676- ON UPDATE SET DEFAULT
677- ON DELETE CASCADE);
678- INSERT INTO f1 VALUES (1, 'Mercury'), (2,' Venus'), (3, 'Earth');
679- INSERT INTO f2 VALUES (1, 'Mercury'), (2, 'Mercury');
680- UPDATE f1 SET referenced_planet = 'Mars'
681- WHERE referenced_planet = 'Mercury';
682- SELECT * FROM f2;
683- DELETE FROM f1 WHERE referenced_planet = 'Earth';
684- SELECT * FROM f2;
685- ... In this example, the UPDATE statement changes the referenced key,
686- and the clause is ON UPDATE SET DEFAULT, therefore both of the
687- rows in f2 have referring_planet set to their default value,
688- which is 'Earth'. The DELETE statement deletes the row that
689- has 'Earth', and the clause is ON DELETE CASCADE,
690- therefore both of the rows in f2 are deleted.
637+ {referencing_column_name} {column_definition}
638+ REFERENCES {referenced_table_name}({referenced_column_name})
691639
692- Limitations: |br |
693- * Foreign keys can have a MATCH clause (`Issue#3455 <https://github.com/tarantool/tarantool/issues/3455 >`_).
640+ .. NOTE ::
694641
695- .. COMMENT
696- Constraint Conflict Clauses are temporarily disabled.
697- However, the description is here, as a big comment.
642+ Since :doc: `2.11.0 </release/2.11.0 >`, the following referencing options aren't supported anymore:
698643
699- Constraint Conflict Clauses
644+ * The ``ON UPDATE `` and ``ON DELETE `` triggers. The ``RESTRICT `` trigger action is used implicitly.
645+ * The ``MATCH `` subclause. ``MATCH FULL `` is used implicitly.
646+ * ``DEFERRABLE `` constraints. The ``INITIALLY IMMEDIATE `` constraint check time rule is used implicitly.
700647
701- In a CREATE TABLE statement:
702- CREATE TABLE ... constraint-definition ON CONFLICT {ABORT | FAIL | IGNORE | REPLACE | ROLLBACK} ...;
648+ Note that a referenced column should meet one of the following requirements:
703649
704- In an INSERT or UPDATE statement:
705- {INSERT|UPDATE} OR {ABORT | FAIL | IGNORE | REPLACE | ROLLBACK} ...;
650+ - A referenced column is a PRIMARY KEY column.
651+ - A referenced column has a UNIQUE constraint.
652+ - A referenced column has a UNIQUE index.
706653
707- The standard way to handle a constraint violation is "statement rollback" -- all rows affected by the statement are restored to their original values -- and an error is returned. However, Tarantool allows the user to specify non-standard ways to handle PRIMARY KEY, UNIQUE, CHECK, and NOT NULL constraint violations.
654+ ** Example **
708655
709- ABORT -- do statement rollback and return an error. This is the default and is recommended, so a user's best strategy is to never use constraint conflict clauses.
656+ This example shows how to create a relation between the parent and child tables through a single-column foreign key:
710657
711- FAIL -- return an error but do not do statement rollback.
658+ 1. First, create a parent `` author `` table:
712659
713- IGNORE -- do not insert or update the row whose update would cause an error, but do not do statement rollback and do not return an error. Due to optimizations related to NoSQL, handling with IGNORE may be slightly faster than handling with ABORT.
660+ .. literalinclude :: /code_snippets/test/sql/foreign_key_table_constraint_test.lua
661+ :language: sql
662+ :start-after: create_parent_start
663+ :end-before: create_parent_end
664+ :dedent:
714665
715- REPLACE -- (for a UNIQUE or PRIMARY KEY constraint) -- instead of inserting a new row, delete the old row before putting in the new one; (for a NOT NULL constraint for a column that has a non-NULL default value) replace the NULL value with the column's default value; (for a NOT NULL constraint for a column that has a NULL default value) do statement rollback and return an error; (for a CHECK constraint) -- do statement rollback and return an error. If REPLACE action causes a row to be deleted, and if PRAGMA recursive_triggers was specified earlier, then delete triggers (if any) are activated.
666+ Then, insert data to this table:
716667
717- ROLLBACK -- do transaction rollback and return an error.
668+ .. literalinclude :: /code_snippets/test/sql/foreign_key_table_constraint_test.lua
669+ :language: sql
670+ :start-after: insert_parent_start
671+ :end-before: insert_parent_end
672+ :dedent:
718673
719- The order of constraint evaluation is described in section Order of Execution in Data-Change Statements.
674+ 2. Create a child `` book `` table whose `` author_id `` column references the `` id `` column from the `` author `` table:
720675
721- For example, suppose a new table t has one column and the column has a unique constraint.
722- A transaction starts with START TRANSACTION.
723- The first statement in the transaction is INSERT INTO t VALUES (1), (2);
724- that is, "insert 1, then insert 2" -- Tarantool processes the new rows in order.
725- This statement always succeeds, there are no constraint violations.
726- The second SQL statement is INSERT INTO t VALUES (3), (2), (5);
727- that is, "insert 3, then insert 2".
728- Inserting 3 is not a problem, but inserting 2 is a problem -- it would violate the UNIQUE constraint.
676+ .. literalinclude :: /code_snippets/test/sql/foreign_key_table_constraint_test.lua
677+ :language: sql
678+ :start-after: create_child_start
679+ :end-before: create_child_end
680+ :dedent:
729681
730- If behavior is ABORT: the second statement is rolled back, there is an error message. The table now contains (1), (2).
682+ Insert data to the `` book `` table:
731683
732- If behavior is FAIL: the second statement is not rolled back, there is an error message. The table now contains (1), (2), (3).
684+ .. literalinclude :: /code_snippets/test/sql/foreign_key_table_constraint_test.lua
685+ :language: sql
686+ :start-after: insert_child_start
687+ :end-before: insert_child_end
688+ :dedent:
733689
734- If behavior is IGNORE: the second statement is not rolled back, the (2) is not inserted, there is no error message. The table now contains (1), (2), (3), (5).
690+ 3. Check how the created foreign key constraint enforces data integrity.
691+ The following error is raised on an attempt to insert a new book with the ``author_id `` value that doesn't exist in the parent ``author `` table:
735692
736- If behavior is REPLACE: the second statement is not rolled back, the first (2) is replaced by the second (2), there is no error message. The table now contains (1), (2), (3), (5).
693+ .. literalinclude :: /code_snippets/test/sql/foreign_key_table_constraint_test.lua
694+ :language: sql
695+ :start-after: insert_error_start
696+ :end-before: insert_error_end
697+ :dedent:
737698
738- If behavior is ROLLBACK: the statement is rolled back, and the first statement is rolled back,
739- and there is an error message. The table now contains nothing.
699+ On an attempt to delete an author that already has books in the ``book `` table, the following error is raised:
740700
741- There are two ways to specify the behavior: at the end of the CREATE TABLE statement constraint clause, or as an extra clause in an INSERT or UPDATE statement. Specification in the INSERT or UPDATE statement takes precedence.
701+ .. literalinclude :: /code_snippets/test/sql/foreign_key_table_constraint_test.lua
702+ :language: sql
703+ :start-after: delete_error_start
704+ :end-before: delete_error_end
705+ :dedent:
742706
743- Another example:
744- DROP TABLE t1;
745- CREATE TABLE t1 (s1 INTEGER PRIMARY KEY ON CONFLICT REPLACE, s2 INTEGER);
746- INSERT INTO t1 VALUES (1, NULL); -- now t1 contains (1,NULL)
747- INSERT INTO t1 VALUES (1, 1); -- now t1 contains (1, 1)
748- INSERT OR ABORT INTO t1 VALUES (1, 2); -- now t1 contains (1, 1)
749- INSERT OR IGNORE INTO t1 VALUES (1, 2), (3, 4); -- now t1 contains (1, 1), (3, 4)
750- PRAGMA recursive_triggers(true);
751- CREATE TRIGGER t1d
752- AFTER DELETE ON t1 FOR EACH ROW
753- BEGIN
754- INSERT INTO t1 VALUES (18, 25);
755- END;
756- INSERT INTO t1 VALUES (1, 4); -- now t1 contains (1, 4), (3, 4), (18, 35)
757707
758708.. _sql_drop_table :
759709
0 commit comments