> ## Documentation Index
> Fetch the complete documentation index at: https://www.cockroachlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CREATE DOMAIN

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

The `CREATE DOMAIN` <InternalLink path="sql-statements">statement</InternalLink> creates a new <InternalLink path="domain">domain data type</InternalLink> in a <InternalLink path="create-database">database</InternalLink>. A domain is based on an existing data type, with optional <InternalLink path="constraints">constraints</InternalLink> that restrict its allowed values and an optional <InternalLink path="default-value">`DEFAULT`</InternalLink> value. After the domain is created, it can only be referenced from the database that contains the domain.

<Note>
  The `CREATE DOMAIN` statement performs a schema change. For more information about how online schema changes work in CockroachDB, refer to <InternalLink path="online-schema-changes">Online Schema Changes</InternalLink>.
</Note>

## Synopsis

<img src="https://mintcdn.com/cockroachlabs/ccT6XAedsjs6XuK5/images/sql-diagrams/v26.3/create_domain.svg?fit=max&auto=format&n=ccT6XAedsjs6XuK5&q=85&s=5e2f3f8db89a975a0b5d78b0be602d24" alt="create_domain syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="659" height="287" data-path="images/sql-diagrams/v26.3/create_domain.svg" />

## Parameters

| Parameter         | Description                                                                                                                                                                                                                                                                     |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type_name`       | The name of the domain. You can qualify the name with a <InternalLink path="sql-name-resolution">database and schema name</InternalLink> (for example, `db.domainname`), but after the domain is created, it can only be referenced from the database that contains the domain. |
| `typename`        | The base <InternalLink path="data-types">data type</InternalLink> of the domain.                                                                                                                                                                                                |
| `DEFAULT a_expr`  | The default value for columns that use the domain data type. A column inherits this value unless the column defines its own `DEFAULT` value.                                                                                                                                    |
| `NOT NULL`        | Disallow `NULL` values for the domain.                                                                                                                                                                                                                                          |
| `NULL`            | Allow `NULL` values for the domain. This is the default behavior; the clause is accepted for PostgreSQL compatibility.                                                                                                                                                          |
| `CONSTRAINT name` | The name of a `CHECK` constraint. If not specified, CockroachDB generates a name (for example, `order_qty_check` for a domain named `order_qty`).                                                                                                                               |
| `CHECK (a_expr)`  | A <InternalLink path="check">`CHECK`</InternalLink> expression that values of the domain must satisfy. Use the `VALUE` keyword to reference the value being tested. A domain can have multiple `CHECK` constraints.                                                             |

## Required privileges

To create a domain, the user must have <InternalLink path="security-reference/authorization#supported-privileges">the `CREATE` privilege</InternalLink> on the parent database and the schema in which the domain is being created.

To use a domain in a table (for example, when defining a column's type), the user must have <InternalLink path="security-reference/authorization#supported-privileges">the `USAGE` privilege</InternalLink> on the domain.

## Details

* Columns that use a domain data type enforce the domain's constraints on <InternalLink path="insert">`INSERT`</InternalLink>, <InternalLink path="update">`UPDATE`</InternalLink>, and cast operations.
* Domain `DEFAULT` and `CHECK` expressions cannot reference database objects such as tables, sequences, <InternalLink path="user-defined-functions">user-defined functions</InternalLink>, or user-defined types. A domain can be based on a user-defined type such as an <InternalLink path="enum">`ENUM`</InternalLink>.
* The base type of a domain cannot be an array, composite, or domain data type.

## Examples

### Create a domain with a default value and constraints

The following statement creates a domain based on `DECIMAL` that defaults to `0`, disallows `NULL` values, and rejects negative values:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> CREATE DOMAIN price AS DECIMAL DEFAULT 0 NOT NULL CHECK (VALUE >= 0);
```

### Create a domain with a named constraint

The following statement creates a domain with a `CHECK` constraint named `us_phone_format`:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> CREATE DOMAIN us_phone AS STRING CONSTRAINT us_phone_format CHECK (VALUE ~ '^[0-9]{10}$');
```

To view the domains in the current database, use <InternalLink path="show-create">`SHOW CREATE ALL TYPES`</InternalLink>:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT create_statement FROM [SHOW CREATE ALL TYPES];
```

```
                                                create_statement
-----------------------------------------------------------------------------------------------------------------
  CREATE DOMAIN public.price AS DECIMAL DEFAULT 0:::DECIMAL NOT NULL CONSTRAINT price_check CHECK (value >= 0);
  CREATE DOMAIN public.us_phone AS STRING CONSTRAINT us_phone_format CHECK (value ~ '^[0-9]{10}$');
(2 rows)
```

### Use a domain in a table

Use the domains created in the preceding examples as column types:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> CREATE TABLE products (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
        name STRING,
        list_price price,
        support_line us_phone
);
```

The `list_price` column inherits the domain's `DEFAULT` value:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> INSERT INTO products (name, support_line) VALUES ('widget', '8005550100');
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> SELECT name, list_price, support_line FROM products;
```

```
   name  | list_price | support_line
---------+------------+---------------
  widget | 0          | 8005550100
(1 row)
```

A value that violates the `price_check` constraint returns an error:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> INSERT INTO products (name, list_price) VALUES ('gadget', -1.99);
```

```
ERROR: value for domain price violates check constraint "price_check"
SQLSTATE: 23514
```

The error message includes the constraint name that was specified at creation:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
> INSERT INTO products (name, support_line) VALUES ('gizmo', '555-0100');
```

```
ERROR: value for domain us_phone violates check constraint "us_phone_format"
SQLSTATE: 23514
```

## Known limitations

Refer to <InternalLink path="domain#known-limitations">`DOMAIN`: Known limitations</InternalLink>.

## See also

* <InternalLink path="domain">`DOMAIN`</InternalLink>
* <InternalLink path="alter-domain">`ALTER DOMAIN`</InternalLink>
* <InternalLink path="drop-type#drop-a-domain">`DROP DOMAIN`</InternalLink>
* <InternalLink path="data-types">Data types</InternalLink>
* <InternalLink path="online-schema-changes">Online Schema Changes</InternalLink>
