in backend/query/pg_catalog.cc [1402:1652]
void PGCatalog::FillPGConstraintTable() {
auto pg_constraint = tables_by_name_.at(kPGConstraint).get();
std::vector<std::vector<zetasql::Value>> rows;
for (const Table* table : default_schema_->tables()) {
if (!table->postgresql_oid().has_value()) {
ZETASQL_VLOG(1) << "Table " << table->Name()
<< " does not have a PostgreSQL OID.";
continue;
}
const auto& [table_schema, _] = GetSchemaAndNameForPGCatalog(table->Name());
int namespace_oid = 0;
if (kHardCodedNamedSchemaOid.contains(table_schema)) {
namespace_oid = kHardCodedNamedSchemaOid.at(table_schema);
} else {
const NamedSchema* named_schema =
default_schema_->FindNamedSchema(table_schema);
if (!named_schema->postgresql_oid().has_value()) {
ZETASQL_VLOG(1) << "Named schema " << table_schema
<< " does not have a PostgreSQL OID.";
continue;
}
namespace_oid = named_schema->postgresql_oid().value();
}
int ordinal_position = 1;
std::map<std::string, int> column_name_to_index;
for (const Column* column : table->columns()) {
column_name_to_index[column->Name()] = ordinal_position++;
}
for (const CheckConstraint* check_constraint : table->check_constraints()) {
if (!check_constraint->postgresql_oid().has_value()) {
ZETASQL_VLOG(1) << "Check constraint " << check_constraint->Name()
<< " does not have a PostgreSQL OID.";
continue;
}
std::vector<int64_t> key_attnums;
for (const Column* column : check_constraint->dependent_columns()) {
key_attnums.push_back(column_name_to_index[column->Name()]);
}
rows.push_back({
// oid
CreatePgOidValue(check_constraint->postgresql_oid().value()).value(),
// conname
String(check_constraint->Name()),
// connamespace
CreatePgOidValue(namespace_oid).value(),
// contype
String("c"),
// condeferrable
NullBool(),
// condeferred
NullBool(),
// convalidated
Bool(true),
// conrelid
CreatePgOidValue(table->postgresql_oid().value()).value(),
// contypid
NullPgOid(),
// conindid
NullPgOid(),
// conparentid
NullPgOid(),
// confrelid
CreatePgOidValue(0).value(),
// confupdtype
String(" "),
// confdeltype
String(" "),
// confmatchtype
NullString(),
// conislocal
NullBool(),
// coninhcount
NullInt64(),
// connoinherit
NullBool(),
// conkey
Int64Array(key_attnums),
// confkey
Null(Int64ArrayType()),
// conpfeqop
Null(GetPgOidArrayType()),
// conppeqop
Null(GetPgOidArrayType()),
// conffeqop
Null(GetPgOidArrayType()),
// conexclop
Null(GetPgOidArrayType()),
// conbin
NullString(),
});
}
for (const ForeignKey* foreign_key : table->foreign_keys()) {
if (!foreign_key->postgresql_oid().has_value()) {
ZETASQL_VLOG(1) << "Foreign key " << foreign_key->Name()
<< " does not have a PostgreSQL OID.";
continue;
}
if (!foreign_key->referencing_table()->postgresql_oid().has_value()) {
ZETASQL_VLOG(1) << "Referencing table " <<
foreign_key->referencing_table()->Name() << "of foreign key "
<< foreign_key->Name() << " does not have a PostgreSQL OID.";
continue;
}
std::string on_delete_action;
switch (foreign_key->on_delete_action()) {
case ForeignKey::Action::kNoAction:
on_delete_action = "a";
break;
case ForeignKey::Action::kCascade:
on_delete_action = "c";
break;
default:
on_delete_action = " ";
}
std::vector<int64_t> key_attnums;
for (const Column* column : foreign_key->referencing_columns()) {
key_attnums.push_back(column_name_to_index[column->Name()]);
}
int ordinal_position = 1;
std::map<std::string, int> foreign_column_name_to_index;
for (const Column* column : foreign_key->referenced_table()->columns()) {
foreign_column_name_to_index[column->Name()] = ordinal_position++;
}
std::vector<int64_t> confkey_attnums;
for (const Column* column : foreign_key->referenced_columns()) {
confkey_attnums.push_back(foreign_column_name_to_index[column->Name()]);
}
rows.push_back({
// oid
CreatePgOidValue(foreign_key->postgresql_oid().value()).value(),
// conname
String(foreign_key->Name()),
// connamespace
CreatePgOidValue(namespace_oid).value(),
// contype
String("f"),
// condeferrable
NullBool(),
// condeferred
NullBool(),
// convalidated
Bool(true),
// conrelid
CreatePgOidValue(
foreign_key->referencing_table()->postgresql_oid().value())
.value(),
// contypid
NullPgOid(),
// conindid
NullPgOid(),
// conparentid
NullPgOid(),
// confrelid
CreatePgOidValue(
foreign_key->referenced_table()->postgresql_oid().value())
.value(),
// confupdtype
String(" "), // For update is not yet supported in the emulator.
// confdeltype
String(on_delete_action),
// confmatchtype
NullString(),
// conislocal
NullBool(),
// coninhcount
NullInt64(),
// connoinherit
NullBool(),
// conkey
Int64Array(key_attnums),
// confkey
Int64Array(confkey_attnums),
// conpfeqop
Null(GetPgOidArrayType()),
// conppeqop
Null(GetPgOidArrayType()),
// conffeqop
Null(GetPgOidArrayType()),
// conexclop
Null(GetPgOidArrayType()),
// conbin
NullString(),
});
}
if (!table->primary_key()[0]->postgresql_oid().has_value()) {
ZETASQL_VLOG(1) << "Primary key constraint for table " << table->Name()
<< " does not have a PostgreSQL OID.";
continue;
}
std::vector<int64_t> key_attnums;
for (const KeyColumn* key_column : table->primary_key()) {
key_attnums.push_back(column_name_to_index[key_column->column()->Name()]);
}
// Primary key constraint.
rows.push_back({
// oid
CreatePgOidValue(table->primary_key()[0]->postgresql_oid().value())
.value(),
// conname
String(PrimaryKeyName(table)),
// connamespace
CreatePgOidValue(namespace_oid).value(),
// contype
String("p"),
// condeferrable
NullBool(),
// condeferred
NullBool(),
// convalidated
Bool(true),
// conrelid
CreatePgOidValue(table->postgresql_oid().value()).value(),
// contypid
NullPgOid(),
// conindid
NullPgOid(),
// conparentid
NullPgOid(),
// confrelid
CreatePgOidValue(0).value(),
// confupdtype
String(" "),
// confdeltype
String(" "),
// confmatchtype
NullString(),
// conislocal
NullBool(),
// coninhcount
NullInt64(),
// connoinherit
NullBool(),
// conkey
Int64Array(key_attnums),
// confkey
Null(Int64ArrayType()),
// conpfeqop
Null(GetPgOidArrayType()),
// conppeqop
Null(GetPgOidArrayType()),
// conffeqop
Null(GetPgOidArrayType()),
// conexclop
Null(GetPgOidArrayType()),
// conbin
NullString(),
});
}
pg_constraint->SetContents(rows);
}