in backend/query/information_schema_catalog.cc [1488:1695]
void InformationSchemaCatalog::FillTableConstraintsTable() {
auto table_constraints =
tables_by_name_.at(GetNameForDialect(kTableConstraints)).get();
std::vector<std::vector<zetasql::Value>> rows;
// Add the user table constraints.
for (const auto* table : default_schema_->tables()) {
const auto& [table_schema_part, table_name_part] =
GetSchemaAndNameForInformationSchema(table->Name());
// Add the primary key.
rows.push_back({
// constraint_catalog
DialectTableCatalog(),
// constraint_schema
String(table_schema_part),
// constraint_name
String(PrimaryKeyName(table)),
// table_catalog
DialectTableCatalog(),
// table_schema
String(table_schema_part),
// table_name
String(table_name_part),
// constraint_type,
String(kPrimaryKey),
// is_deferrable,
String(kNo),
// initially_deferred,
String(kNo),
// enforced,
String(kYes),
});
// Add the NOT NULL check constraints.
for (const auto* column : table->columns()) {
if (column->is_nullable()) {
continue;
}
rows.push_back({
// constraint_catalog
DialectTableCatalog(),
// constraint_schema
String(table_schema_part),
// constraint_name
String(CheckNotNullName(table, column)),
// table_catalog
DialectTableCatalog(),
// table_schema
String(table_schema_part),
// table_name
String(table_name_part),
// constraint_type,
String(kCheck),
// is_deferrable,
String(kNo),
// initially_deferred,
String(kNo),
// enforced,
String(kYes),
});
}
// Add the check constraints defined by the ZETASQL_VLOG keyword.
for (const auto* check_constraint : table->check_constraints()) {
rows.push_back({
// constraint_catalog
DialectTableCatalog(),
// constraint_schema
String(table_schema_part),
// constraint_name
String(check_constraint->Name()),
// table_catalog
DialectTableCatalog(),
// table_schema
String(table_schema_part),
// table_name
String(table_name_part),
// constraint_type,
String(kCheck),
// is_deferrable,
String(kNo),
// initially_deferred,
String(kNo),
// enforced,
String(kYes),
});
}
// Add the foreign keys.
for (const auto* foreign_key : table->foreign_keys()) {
rows.push_back({
// constraint_catalog
DialectTableCatalog(),
// constraint_schema
String(table_schema_part),
// constraint_name
String(SDLObjectName::GetInSchemaName(foreign_key->Name())),
// table_catalog
DialectTableCatalog(),
// table_schema
String(table_schema_part),
// table_name
String(table_name_part),
// constraint_type,
String(kForeignKey),
// is_deferrable,
String(kNo),
// initially_deferred,
String(kNo),
// enforced,
String(kYes),
});
// Add the foreign key's unique backing index as a unique constraint.
const auto& [referenced_table_schema_part, referenced_table_name_part] =
GetSchemaAndNameForInformationSchema(
foreign_key->referenced_table()->Name());
if (foreign_key->referenced_index()) {
rows.push_back({
// constraint_catalog
DialectTableCatalog(),
// constraint_schema
DialectDefaultSchema(),
// constraint_name
String(foreign_key->referenced_index()->Name()),
// table_catalog
DialectTableCatalog(),
// table_schema
String(referenced_table_schema_part),
// table_name
String(referenced_table_name_part),
// constraint_type,
String(kUnique),
// is_deferrable,
String(kNo),
// initially_deferred,
String(kNo),
// enforced,
String(kYes),
});
}
}
}
// Production doesn't add check constraints for the information schema so we
// also don't add it in the emulator.
if (dialect_ != DatabaseDialect::POSTGRESQL) {
// Add the information schema constraints.
for (const auto* table : this->tables()) {
// Add the primary key.
rows.push_back({
// constraint_catalog
DialectTableCatalog(),
// constraint_schema
String(kInformationSchema),
// constraint_name
String(PrimaryKeyName(table)),
// table_catalog
DialectTableCatalog(),
// table_schema
String(kInformationSchema),
// table_name
String(table->Name()),
// constraint_type
String(kPrimaryKey),
// is_deferrable,
String(kNo),
// initially_deferred
String(kNo),
// enforced
String(kYes),
});
// Add the NOT NULL check constraints.
for (int i = 0; i < table->NumColumns(); ++i) {
const auto* column = table->GetColumn(i);
const auto& metadata = GetColumnMetadata(dialect_, table, column);
if (IsNullable(metadata)) {
continue;
}
rows.push_back({
// constraint_catalog
DialectTableCatalog(),
// constraint_schema
String(kInformationSchema),
// constraint_name
String(CheckNotNullName(table, column)),
// table_catalog
DialectTableCatalog(),
// table_schema
String(kInformationSchema),
// table_name
String(table->Name()),
// constraint_type,
String(kCheck),
// is_deferrable,
String(kNo),
// initially_deferred,
String(kNo),
// enforced,
String(kYes),
});
}
}
}
table_constraints->SetContents(rows);
}