|
| 1 | +Object Names |
| 2 | +============ |
| 3 | + |
| 4 | +Doctrine DBAL provides an abstraction for representing names of database objects such as tables, columns, indexes, and |
| 5 | +so on. Each object name consists of one or more identifiers. |
| 6 | + |
| 7 | +.. _unquoted-and-quoted-identifiers: |
| 8 | + |
| 9 | +Unquoted and Quoted Identifiers |
| 10 | +------------------------------- |
| 11 | + |
| 12 | +The ``Identifier`` class from the ``Doctrine\DBAL\Schema\Name`` namespace (not to be confused with the internal |
| 13 | +``Doctrine\DBAL\Schema\Identifier`` class) represents an SQL identifier. An identifier may be *unquoted* or *quoted*. |
| 14 | +Use ``Identifier::unquoted($name)`` or ``Identifier::quoted($name)`` to create an unquoted or quoted identifier, |
| 15 | +respectively. |
| 16 | + |
| 17 | +Whether an identifier is quoted affects how its value is normalized (upper-cased, lower-cased, or used as-is) depending |
| 18 | +on the database platform. |
| 19 | + |
| 20 | +.. note:: |
| 21 | + |
| 22 | + The fact that an identifier is declared as unquoted does **not** mean that it can be used to inject arbitrary |
| 23 | + fragments into the resulting SQL. |
| 24 | + |
| 25 | + Although this behavior is not yet consistent across the codebase, the goal is for DBAL to **quote all identifiers** |
| 26 | + in SQL, regardless of whether they are declared as quoted or unquoted. Application developers remain responsible — |
| 27 | + both before and after this improvement — for ensuring that only valid object names are passed to DBAL. |
| 28 | + |
| 29 | +Rendering of Quoted Identifiers in SQL |
| 30 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 31 | + |
| 32 | +The original case of quoted identifiers is preserved on all platforms. |
| 33 | +For example, a quoted ``UserId`` is rendered as ``"UserId"``. |
| 34 | + |
| 35 | +Rendering of Unquoted Identifiers in SQL |
| 36 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 37 | + |
| 38 | +1. On **Oracle** [1]_ and **Db2** [2]_, the value is upper-cased. |
| 39 | + For example, an unquoted ``user_id`` is rendered as ``"USER_ID"``. |
| 40 | +2. On **PostgreSQL** [3]_, the value is lower-cased. |
| 41 | + For example, an unquoted ``USER_ID`` is rendered as ``"user_id"``. |
| 42 | +3. On **MySQL**, **SQLite**, and **SQL Server**, the value is used as-is. |
| 43 | + For example, an unquoted ``UserId`` is rendered as ``"UserId"``. |
| 44 | + |
| 45 | +Choosing Between Unquoted and Quoted Identifiers |
| 46 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 47 | + |
| 48 | +Whether to use quoted or unquoted identifiers depends on the target database platforms and the desired SQL rendering. |
| 49 | +See the :ref:`quoting-identifiers` article for platform-specific recommendations. |
| 50 | + |
| 51 | +Unqualified and Optionally Qualified Names |
| 52 | +------------------------------------------ |
| 53 | + |
| 54 | +The ``Name`` interface represents SQL object names. Currently, Doctrine DBAL supports *unqualified* and *optionally |
| 55 | +qualified* names. |
| 56 | + |
| 57 | +An **unqualified name** is represented by the ``UnqualifiedName`` class and consists of a single identifier. |
| 58 | +Example: ``user_id``. |
| 59 | + |
| 60 | +An **optionally qualified name** is represented by the ``OptionallyQualifiedName`` class and consists of an identifier and |
| 61 | +an optional qualifier. |
| 62 | +Examples: ``users``, ``public.users``. |
| 63 | + |
| 64 | +Doctrine DBAL uses unqualified names for objects that belong to a table, and optionally qualified names for objects that belong to a database. The following table summarizes the mapping: |
| 65 | + |
| 66 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 67 | +| Object Type | Name Type | Examples | |
| 68 | ++============================+======================+============================================================+ |
| 69 | +| **Table** | Optionally qualified | ``products``, ``inventory.products`` | |
| 70 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 71 | +| **Column** | Unqualified | ``id`` | |
| 72 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 73 | +| **Index** | Unqualified | ``category_id_idx`` | |
| 74 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 75 | +| **Primary key constraint** | Unqualified | ``products_pk`` | |
| 76 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 77 | +| **Unique constraint** | Unqualified | ``sku_uq`` | |
| 78 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 79 | +| **Foreign key constraint** | Unqualified | ``category_fk`` | |
| 80 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 81 | +| **View** | Optionally qualified | ``available_products``, ``fulfillment.available_products`` | |
| 82 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 83 | +| **Sequence** | Optionally qualified | ``product_id_seq``, ``inventory.product_id_seq`` | |
| 84 | ++----------------------------+----------------------+------------------------------------------------------------+ |
| 85 | + |
| 86 | +Named and Optionally Named Objects |
| 87 | +---------------------------------- |
| 88 | + |
| 89 | +All classes representing database objects implement either the ``NamedObject`` or ``OptionallyNamedObject`` interface. |
| 90 | + |
| 91 | +* A ``NamedObject`` instance is guaranteed to have a name (a concrete implementation of the ``Name`` interface). |
| 92 | +* An ``OptionallyNamedObject`` instance may or may not have a name (also a concrete ``Name``). |
| 93 | + |
| 94 | +All database objects except constraints are named. |
| 95 | +Constraints are optionally named. |
| 96 | + |
| 97 | +.. [1] `Oracle: Database Object Naming Rules <https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/Database-Object-Names-and-Qualifiers.html#GUID-75337742-67FD-4EC0-985F-741C93D918DA>`_ |
| 98 | +.. [2] `Db2: Case sensitivity and the correct use of quotation marks <https://www.ibm.com/docs/en/db2/12.1.0?topic=sources-case-sensitivity-correct-use-quotation-marks>`_ |
| 99 | +.. [3] `PostgreSQL: Identifiers and Key Words <https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS>`_ |
0 commit comments