{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://gmr.github.io/pglifecycle/schemata/domain.json",
  "title": "Domain",
  "description": "Creates a user-defined data type with optional constraints.",
  "type": "object",
  "properties": {
    "name": {
      "title": "Name",
      "description": "The name of the domain function to create.",
      "type": "string"
    },
    "schema": {
      "title": "Schema",
      "description": "The schema to create the domain function in.",
      "type": "string"
    },
    "owner": {
      "title": "Owner",
      "description": "The role that owns the domain function.",
      "type": "string"
    },
    "sql": {
      "title": "SQL Statement",
      "description": "User-provided raw SQL snippet",
      "type": "string"
    },
    "data_type": {
      "title": "Data Type",
      "description": "The underlying data type of the domain.",
      "type": "string"
    },
    "collation": {
      "title": "Collation",
      "description": "An optional collation for the domain. If no collation is specified, the underlying data type's default collation is used. The underlying type must be collatable if COLLATE is specified.\n",
      "type": "string"
    },
    "default": {
      "title": "Default",
      "description": "The DEFAULT clause specifies a default value for columns of the domain data type. The value is any variable-free expression (but subqueries are not allowed). The data type of the default expression must match the data type of the domain. If no default value is specified, then the default value is the null value.\n",
      "oneOf": [
        {
          "type": "boolean"
        },
        {
          "type": "integer"
        },
        {
          "type": "null"
        },
        {
          "type": "number"
        },
        {
          "type": "string"
        }
      ]
    },
    "check_constraints": {
      "title": "An array of one or more check constraints",
      "type": "array",
      "items": {
        "title": "Constraint",
        "type": "object",
        "properties": {
          "name": {
            "title": "Constraint Name",
            "type": "string"
          },
          "nullable": {
            "title": "Domain is Nullable",
            "type": "boolean"
          },
          "expression": {
            "title": "Constraint Expression",
            "type": "string"
          }
        },
        "oneOf": [
          {
            "required": [
              "expression"
            ],
            "not": {
              "required": [
                "nullable"
              ]
            }
          },
          {
            "required": [
              "nullable"
            ],
            "not": {
              "required": [
                "expression"
              ]
            }
          }
        ],
        "additionalProperties": false
      },
      "uniqueItems": true
    },
    "comment": {
      "title": "Comment",
      "description": "An optional comment about the domain.",
      "type": "string"
    },
    "dependencies": {
      "title": "Dependencies",
      "description": "Objects this object depends on, for the cases the dependency graph cannot infer: an ordering the topological sort would otherwise get wrong, such as a foreign key between tables or an inheritance parent.\nEach entry names an object as `schema.name`, or unqualified for a schemaless type. A function or aggregate carries its argument signature (`test.f(integer)`) and a cast its types (`(int4 AS timestamp)`), since the name alone is ambiguous.\n",
      "type": "object",
      "properties": {
        "aggregates": {
          "description": "The aggregates this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "collations": {
          "description": "The collations this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "domains": {
          "description": "The domains this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "event_triggers": {
          "description": "The event triggers this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "extensions": {
          "description": "The extensions this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "foreign_data_wrappers": {
          "description": "The foreign data wrappers this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "functions": {
          "description": "The functions this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "languages": {
          "description": "The languages this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "materialized_views": {
          "description": "The materialized views this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "publications": {
          "description": "The publications this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "sequences": {
          "description": "The sequences this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "servers": {
          "description": "The servers this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "subscriptions": {
          "description": "The subscriptions this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "tables": {
          "description": "The tables this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "types": {
          "description": "The types this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "user_mappings": {
          "description": "The user mappings this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "users": {
          "description": "The users this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "views": {
          "description": "The views this object depends on.",
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": false
    }
  },
  "requires": [
    "name",
    "schema"
  ],
  "additionalProperties": false,
  "oneOf": [
    {
      "required": [
        "sql"
      ],
      "not": {
        "required": [
          "data_type",
          "check_constraints"
        ]
      }
    },
    {
      "required": [
        "data_type"
      ],
      "not": {
        "required": [
          "sql"
        ]
      }
    }
  ]
}