xBRL-CSV Table Constraints 1.0

Public Working Draft 1 April 2025

This version
https://www.xbrl.org/Specification/table-constraints/PWD-2025-04-01/table-constraints-PWD-2025-04-01.html
Editors
Mark Goodhand, CoreFiling <mrg@corefiling.com>
Paul Hulst, De Nederlandsche Bank N.V. <P.J.Hulst@dnb.nl>
Contributors
Herm Fischer, ExBee <herm@exbee.dev>
Nobuyuki Sambuichi, XBRL Japan <nobuyuki@sambuichi.jp>
Paul Warren, XBRL International Inc. <pdw@xbrl.org>

Table of Contents

Definitions

Error codes

1 Status

This Public Working Draft has been approved for publication by the XBRL Standards Board for the purpose of obtaining feedback.

2 Abstract

xBRL-CSV Table Constraints are a set of backwards-compatible extensions to xBRL-CSV that enable basic but extremely efficient validation checks.

3 Introduction

This specification defines a number of additional validation instructions that sit within xBRL-CSV metadata files, supporting efficient validation of CSV files prior to loading of an XBRL taxonomy and construction of an OIM report model.

This specification does not stipulate a processing model. The design is intended to enable streaming and parallelisation. Most checks can be performed using constant memory, operating on a single row at a time. However, processors remain free to load entire CSV files into memory, or transfer them to persistent storage, if this is convenient for implementing the checks described here or for later operations.

3.1 Documentation conventions

3.1.1 Error codes

QNames in parenthetical red text after a "MUST" or "MUST NOT" statement prescribe standardised error codes to be used if the preceding condition is violated. "MUST" or "MUST NOT" statements that do not have a prescribed error code are not automatically enforceable, and processors are not required to detect violations.

3.2 Namespaces and namespace prefixes

Prefixes used in this specification are to be interpreted according to the following table:

Prefix Namespace URI
tc https://xbrl.org/PWD/2025-04-01/tc
tcme https://xbrl.org/PWD/2025-04-01/tc/metadataerror
tcre https://xbrl.org/PWD/2025-04-01/tc/reporterror
tcl https://xbrl.org/PWD/2025-04-01/tc/lint
xbrl https://xbrl.org/2021
xs http://www.w3.org/2001/XMLSchema

4 Validation

This specification defines three types of validation and two types of processor.

Validation falls into the following categories:

A Table Constraint report validator is a processor that takes an xBRL-CSV report as input and enforces report related constraints defined in this specification.

On encountering a document with the xBRL-CSV document type, a Table Constraint report validator MUST perform Report validation, raising tcre error codes as appropriate.

A Table Constraint metadata validator is a processor that takes an xBRL-CSV report as input and enforces metadata related constraints defined in this specification.

On encountering a document with the xBRL-CSV document type, a Table Constraint metadata validator MUST perform Metadata validation, raising tcme error codes as appropriate.

Some table constraint metadata overlaps with information present in the taxonomy, and it is important that this information is consistent.

A Table Constraint linter is a processor that checks consistency of Table Constraint metadata with the taxonomy.

When directed to check a document with the xBRL-CSV document type, a Table Constraint linter MUST raise errors with the specified tcl error codes if the document does not conform to the Metadata linting checks defined in this specification.

Note that Metadata validation and Metadata linting checks are independent of the values in the report. That being the case, they need to run only once, not for every report.

4.1 JSON structure

Table constraint instructions are embedded within xBRL-CSV metadata files, and subject to the same basic JSON syntax restrictions (xbrlce:invalidJSON).

This specification documents the allowed types for all values in JSON metadata. Types are specified using JSON primitive types (string, array, object, number, boolean and null), and values in the JSON metadata MUST conform to these types (xbrlce:invalidJSONStructure).

In addition, the following constraints apply to JSON metadata (tcme:invalidJSONStructure):

A set is a collection of values that contains no repeated members. The ordering of the values within the set is not significant.

An ordered set is a collection of values that contains no repeated members. The order of values within the set is significant.

4.2 Column roles

The xBRL-CSV specification explicitly defines three roles for a column:

This specification uses the following additional definitions:

Note that xBRL-CSV does not prevent a fact column from also providing dimension values for fact columns. Such a hybrid column would not qualify as a dimension column according to this specification.

4.3 Parameter definitions

Expected parameters can be documented by placing a tc:parameters property in the additional properties of a table template object.

The value of the tc:parameters property is a parameters object.

The keys of a parameters object MUST be identifiers (xbrlce:invalidIdentifier).

Each value is a value constraint object.

A parameter that has been defined using this mechanism is known as a defined parameter.

4.4 Column value constraints

Constraints can be applied to all values in an xBRL-CSV column by placing a tc:constraints property in the additional properties of a column object.

The value of the tc:constraints property is a value constraint object.

4.5 Value constraints

A value constraint object specifies constraints on the values for a column or parameter. It has the following properties:

type (string)
(required) Identifies an XML Schema or XBRL-CSV type that values MUST satisfy.
optional (boolean)
(optional) Controls whether a value MAY be omitted. Defaults to false.
nillable (boolean)
(optional) Controls whether nil values are allowed. Defaults to true.
allowedValues (array)
(optional) A set of strings specifying the allowed values.
allowedPatterns (array)
(optional) A set of patterns constraining the allowed values.
timeZone (boolean)
(optional) Controls whether date values include a time zone component.
periodType (string)
(optional) Additional type restriction for values of type period
durationType (string)
(optional) Additional type restriction for values of type xs:duration

The constrained column or defined parameter associated with a value constraint object is known as the constraint subject.

4.5.1 Type validation

All core dimensions except noteId MAY be specified in xBRL-CSV metadata and data tables. Such a dimension is known in this specification as an xBRL-CSV core dimension and identified by one of the following strings: concept, entity, period, unit, language.

Its value MUST identify (tcme:invalidTypeConstraint):

All values for the constraint subject MUST be valid against type (tcre:invalidValue).

In the case of an XML Schema type, validation is prescribed by that specification.

In the case of an xBRL-CSV core dimension, the allowed representations are defined by xBRL-CSV.

            "c0090": {
                "dimensions": {
                    "concept": "dict:somedate"
                }
                "tc:constraints": {
                    "type": "xs:date"
                }
            },

value 2024-12-31 must be accepted, value 31/12/2024 must return tcre:invalidValue.

4.5.2 Required values

If optional is set to false, then for each row in a table based on the containing table template, values for the constraint subject MUST be present (tcre:missingValue):

#nil and JSON null are values and therefore fulfil this constraint.

4.5.3 Nillable values

If nillable is set to false, values for the constraint subject MUST NOT be #nil or the JSON null value (tcre:invalidValue).

4.5.4 Allowed values

If allowedValues is specified, each item in the set MUST conform to type (tcme:illegalAllowedValue), and every value for the constraint subject MUST match one of the allowedValues (tcre:invalidValue).

When type is an XML Schema type, equality is determined according to the rules of XML Schema, and allowedValues behaves equivalently to <xs:enumeration>.

When type is a an xBRL-CSV core dimension, equality is determined as defined in OIM 5.1.

"tc:constraints": {
    "type": "xs:string",
    "allowedValues": [ 
        "RP:x53", "RP:x551", "RP:x56", "RP:x21", "RP:x210" ]
}

a value RP:x11 must return tcre:invalidValue.

4.5.5 Allowed patterns

If allowedPatterns is specified, the values for the constraint subject MUST conform to at least one of the patterns (tcre:invalidValue).

For each pattern, matching proceeds according to XML Schema, as if the pattern were specified in <xs:pattern>.

"tc:constraints": {
    "type": "xs:string",
    "allowedPatterns": [ 
        "[a-z][a-z][a-z]","[A-Z][A-Z][A-Z]" ]
}

values aaa and AAA are valid, a value aaA must return tcre:invalidValue.

4.5.6 Timezone

The following XML Schema types optionally allow a timezone component; each of these is known in this specification as optionally-timezoned schema type: xs:date, xs:time, xs:dateTime, xs:gYearMonth, xs:gMonthDay, xs:gDay.

If the timeZone property is specified, type MUST be period or an optionally-timezoned schema type (tcme:unknownTimeZone).

If timeZone is set to true, all values for the constraint subject MUST have a timezone component (tcre:missingTimeZone).

If timeZone is set to false, the values MUST NOT have a timezone component (tcre:unexpectedTimeZone).

If timeZone is absent, the presence or absence of a timezone component is unconstrained.

4.5.7 Period type

If the periodType property is specified, type MUST be period (tcme:illegalPeriodType).

The periodType property takes one of the following values (tcme:unknownPeriodType), with noted implications for constraint subject value validation (tcre:invalidPeriodType):

"tc:constraints": {
    "type": "period"
    "periodType": "year"
}
value 2024 must be accepted, value 2024H1 must result in tcre:invalidPeriodType.

Other examples for periodType:
'half':     accepted 2024H1, rejected 2024
'quarter':  accepted 2024Q1, rejected 2024Q0
'month':    accepted 2024-12, rejected 202410
'week':     accepted 2024W29, rejected 2024
'day':      accepted 2024-12-31, rejected 2024-31-12
'instant':  accepted 2024Q1@end, rejected 2024W29
'P2M':      accepted 2024-01-01..2024-02-29, rejected 2024-01-01..2024-02-28

4.5.8 Duration type

If the durationType property is specified, the type MUST be xs:duration (tcme:illegalDurationType).

The durationType property takes one of the following values (tcme:unknownDurationType), with noted implications for constraint subject value validation (tcre:invalidDurationType):

4.5.9 Value constraint linting

The type associated with a constraint subject in the taxonomy is known as the associated taxonomy type.

When a constraint subject has an associated taxonomy type, it MUST be equal to or derived from type (tcl:typeMismatch).

Furthermore, every value in allowedValues (if present) MUST be valid against the associated taxonomy type (tcl:invalidAllowedValue).

4.6 Keys

Constraints accross multiple rows may be enforced by placing a tc:keys property in the additional properties of a table template object.

The value of the tc:keys property is a keys object. It has the following properties:

primary (object)
(optional) a primary key object
unique (array)
(optional) a set of unique key objects
reference (array)
(optional) a set of reference key objects

At least one property MUST be specified (tcme:missingKeyProperty).

Each of the key objects has a name property subject to the following constraints:

4.6.1 primary

A primary key object establishes the primary unique index for a table.

It has the following properties:

name (string)
(required) Name of the primary key.
fields (array)
(required) an ordered set of strings identifying columns or parameters.
sortedColumns (boolean)
(optional) Specifies whether columns are sorted. Defaults to true.
sortedRows (boolean)
(optional) Specifies whether rows are sorted. Defaults to true.

4.6.1.1 Primary key fields

Each item in the fields object MUST correspond to a constrained column or a defined parameter in the current table template (tcme:illegalPrimaryKeyField).

Note that most SQL databases require all database columns making up the primary key to be mandatory columns. This specification does not set the same requirement as it increases the cases where the primary key features of sorting and subtypes can be used.

4.6.1.2 Primary key enforcement

The ordered subset of fields that correspond to columns are known as primary key columns.

The ordered subset of fields that correspond to parameters are known as primary key parameters

The content columns in the table template that are not among the primary key columns are known as non-key columns

Table Constraint report validators MUST raise tcre:primaryKeyViolation if the same combination of values for the primary key fields is used for more than one row, according to each field's type (using XML Schema equality semantics), across all tables for the table template.

Table Constraint report validators MUST raise tcre:primaryKeyNilViolation if all values for the primary key fields are nil.

4.6.1.3 Column ordering

If sortedColumns is true, the columns MUST be ordered as follows (tcre:invalidColumnOrder):

4.6.1.4 Row sorting

When sortedRows is set to true, primary key enforcement can be optimised by checking that each table for the table template is primary key sorted, and that no two tables for the table template have the same combination of values for the primary key parameters (or if they do, the ranges for primary key columns are disjoint, such that these tables could be combined by concatenation into a single table that is primary key sorted).

A table is primary key sorted if its rows are sorted in ascending order according to the rules described in this section.

To establish row ordering, values from the primary key columns are compared in turn:

Values are compared according to their type:

To avoid the possibility of tcre:incomparableDurations and tcre:incomparablePeriods errors, template authors are advised to apply timeZone, periodType and durationType constraints.

4.6.1.5 Multiple templates with the same primary key

When two or more templates have a primary key with the same name, all properties of those primary keys must be the same as well (tcme:inconsistentPrimaryKeyDefinition).

In addition, the values provided for these primary keys must be unique across all tables that are part of these templates (tcre:nonUniqueValuesSharedPrimaryKey).

Shared primary keys fulfills the subtype table requirement in a simplified way.

An example of shared primary key is splitting customer into two distinct groups, each having attributes only relevant for that group. Group 1 contains the natural person customers each having an id, a name and a birth date. Group 2 contains the legal entity customers each having an id, a name, a date of incorporation and optionally the VAT rules that apply.

The id is the primary key for both groups. The ids must be unique across both groups.

4.6.2 unique

A unique key object establishes an auxiliary unique index for a tableTemplate.

It has the following properties:

name (string)
(required) Name for the key
fields (array)
(required) an ordered set of strings identifying columns or parameters.

name MUST be an identifier (xbrlce:invalidIdentifier).

Each entry in the fields object MUST correspond to a constrained column or a defined parameter in the current table template (tcme:illegalUniqueKeyField).

Whereas the primary key is typically used for dimensions that qualify all facts in a table, and may include dimensions specified through parameters, unique keys typically involve fact columns and cannot apply to parameters. Another difference is that all of the fields in a primary key are required, while unique keys can include optional columns.

Processors MUST raise tcre:uniqueKeyViolation if the same combination of values for the unique key columns is used for more than one row, according each field's type (using XML Schema equality semantics), across all tables for the table template. For the purposes of this check, two absent values are considered equal to each other.

4.6.3 reference

A reference key checks the values in a column (or combination of columns) against an index corresponding to another key.

It is common for references to apply across tables (hence the database term "foreign key"), but reference keys can also refer to an index defined within the same table template (a "self-referential foreign key").

A reference key is defined using a reference key object. It has the following properties:

name (string)
(required) Name for the key.
fields (array)
(required) an ordered set of strings identifying columns or parameters.
referencedKeyName (string)
(required) the name of the key in which corresponding values are sought.This key MUST exist as a primary or unique key in at least one template in the xBRL-CSV effective metadata (tcme:invalidKeyIdentifier).
negate (boolean)
(optional) if true, the constraint is inverted so that it passes if and only if a match is NOT found in the referenced index. Defaults to false.
skipNils (boolean)
(optional) if true, values that are nil are NOT checked for existance in the key referenced. Defaults to false.

name MUST be an identifier (xbrlce:invalidIdentifier).

Each entry in the fields object MUST correspond to a constrained column or a defined parameter in the current table template (tcme:illegalReferenceKeyField).

The fields object MUST have the same number of items as the fields object of the key specified in referencedKeyName (tcme:invalidReferenceKey).

The index of values corresponding to the key specified in referencedKeyName is known as the target index. When that name is found in multiple templates, the values from all templates must be combined.

The ordered list of values for the parameters and columns in fields, in a given row, is known as the local value list.

Reference key validation proceeds as follows for each row in the table template in which at least one of the columns or parameters in the fields object has a value (tcre:referenceKeyViolation):

As usual, comparisons are made according to the equality definitions for the type. In order to be considered a match, any field that is absent in the local value list must also be absent in the target index, and vice versa.

To illustrate:

If C and D both don't have a value for a row in BB, no check is done. If C has the value 123 and D has no value, then a check is made to verify that there is a line in table AA with A equal to 123 and B also no value.

4.7 Examples

4.7.1 Keys example

This example shows the metadata for a set of CSV files capturing customer data. Every customer must be either a natural person or a legal entity. All natural persons and legal entities must be a customer. If a legal entity customer has country specific VAT rules, the country code provided must exist in countries table.

{
    "documentInfo": {
        "documentType": "https://xbrl.org/2021/xbrl-csv",
        "namespaces": {
            "eg": "http://example.com/xbrl-csv/taxonomy-tc",
            "lei": "http://standards.iso.org/iso/17442",
            "iso4217": "http://www.xbrl.org/2003/iso4217",
            "xs": "http://www.w3.org/2001/XMLSchema",
            "tc": "https://xbrl.org/PWD/2025-04-01/tc"
        },
        "taxonomy": [
            "taxonomy-tc.xsd"
        ]
    },
    "tableTemplates": {
        "naturalPersonCustomers": {
            "columns": {
                "customer_id":{
                    "tc:constraints": {
                        "type": "xs:int"
                    }
                },
                "name": {
                    "dimensions": {
                        "concept": "eg:Name"
                    },
            "birthDate": {
                    "dimensions": {
                        "concept": "eg:birthDate"
                    }
                }
            },
            "dimensions": {
                "eg:CustomerId": "$customer_id"
            },
            "tc:keys": {
                "primary": {
                    "name": "customerPK",
                    "fields": [ "customer_id" ]
                    }
                }
            }
        },
        "legalEntityCustomers": {
                "columns": {
                    "customer_id": {
                        "tc:constraints": {
                            "type": "xs:int"
                        }
                    },
                    "name": {
                        "dimensions": {
                            "concept": "eg:Name"
                        },
                    },
                    "incorporationDate": {
                        "dimensions": {
                            "concept": "eg:incorporationDate"
                        }
                    },
                    "CountryCodeVAT": {
                        "dimensions": {
                            "concept": "eg:countryCode"
                        },
                        "tc:constraints": {
                            "optional": true
                        }
                    }
                },
                "dimensions": {
                    "eg:CustomerId": "$customer_id"
                },
                "tc:keys": {
                    "primary": {
                        "name": "customerPK",
                        "fields": [ "customer_id" ]
                        },
                    "reference": [
                        {
                            "name": "LegalEntityCountryToCountriesFK",
                            "fields": [ "countryCodeVAT"],
                            "referencedKeyName": "countriesUK",
                            "skipNils": true
                        }
                    ]
                }
            },
        "countries": {
            "columns": {
                "country_id": {
                    "tc:constraints": {
                        "type": "xs:int"
                    }
                },
                "countryCode": {
                    "dimensions": {
                        "concept": "eg:countryCode"
                    },
                    "tc:constraints": {
                        "type": "xs:string"
                    }

                },
                "VATrules": {
                    "dimensions": {
                        "concept": "eg:VATrules"
                    }
                }
            },
            "dimensions": {
                "eg:countryID": "country_id"
            },
            "tc:keys":{
                "primary":{
                    "name": "countriesPK",
                    "fields": ["country_id"]
                },
                "unique": [
                    {
                        "name": "countriesUK",
                        "fields": ["countryCode"]
                    }
                ]
            }
        },
    "tables": {
        "natural_persons_data": {
            "template": "naturalPersonCustomers",
            "url": "natural-person-data.csv"
        },
        "legal_entity_data": {
            "template": "legalEntityCustomers",
            "url": "legal-entity-data.csv"
        },
        "country_data": {
            "template": "countries",
            "url": "country-data.csv"
        }
    }
}

4.7.2 Parameter example

This example shows how parameters can be constrained and used in keys. In the sales table template, the parameter calendar_month, which is used for the period dimension, must be present. Its type is period, which restricts the syntax to values accepted for the period dimension in xBRL-CSV. Additionally, it must be a period covering a single calendar month, using the yyyy-mm shorthand format.

The primary key for the sales table consists of the calendar_month parameter and the product_id column.

{
    "documentInfo": {
        "documentType": "https://xbrl.org/2021/xbrl-csv",
        "namespaces": {
            "eg": "http://example.com/xbrl-csv/taxonomy-tc",
            "lei": "http://standards.iso.org/iso/17442",
            "iso4217": "http://www.xbrl.org/2003/iso4217",
            "xs": "http://www.w3.org/2001/XMLSchema"
        },
        "taxonomy": [
            "taxonomy-tc.xsd"
        ]
    },
    "tableTemplates": {
        "sales": {
            "columns": {
                "product_id": {
                    "tc:constraints": {
                        "type": "xs:token",
                        "nillable": false
                    }
                },
                "sales": {
                    "dimensions": {
                        "concept": "eg:Sales"
                    }
                },
                "dimensions": {
                    "period": "$calendar_month",
                    "unit": "iso4217:EUR",
                    "eg:ProductId": "$product_id"
                }
            },
            "tc:parameters": {
                "calendar_month": {
                    "type": "period",
                    "periodType": "month"
                }
            },
            "tc:keys": {
                "primary": {
                    "fields": [ "calendar_month", "product_id " ]
            }
        }
    },
    "tables": {
        "salesJan24": {
            "url": "salesJan24.csv",
            "template": "sales",
            "parameters": {
                "calendar_month": "2024-01"
            }
        },
        "salesFeb24": {
            "url": "salesFeb24.csv",
            "template": "sales",
            "parameters": {
                "calendar_month": "2024-02"
            }
        },
        "salesMar24": {
            "url": "salesMar24.csv",
            "template": "sales",
            "parameters": {
                "calendar_month": "2024-03"
            }
        }
    }
}

Appendix A Intellectual property status (non-normative)

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to XBRL International or XBRL organizations, except as required to translate it into languages other than English. Members of XBRL International agree to grant certain licenses under the XBRL International Intellectual Property Policy (https://www.xbrl.org/legal).

This document and the information contained herein is provided on an "AS IS" basis and XBRL INTERNATIONAL DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

The attention of users of this document is directed to the possibility that compliance with or adoption of XBRL International specifications may require use of an invention covered by patent rights. XBRL International shall not be responsible for identifying patents for which a license may be required by any XBRL International specification, or for conducting legal inquiries into the legal validity or scope of those patents that are brought to its attention. XBRL International specifications are prospective and advisory only. Prospective users are responsible for protecting themselves against liability for infringement of patents. XBRL International takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Members of XBRL International agree to grant certain licenses under the XBRL International Intellectual Property Policy (https://www.xbrl.org/legal).