in backend/schema/validators/column_validator.cc [212:300]
absl::Status ColumnValidator::Validate(const Column* column,
SchemaValidationContext* context) {
ZETASQL_RET_CHECK_NE(column->table_, nullptr);
ZETASQL_RET_CHECK(!column->name_.empty());
ZETASQL_RET_CHECK(!column->id_.empty());
ZETASQL_RET_CHECK(column->type_ != nullptr && IsSupportedColumnType(column->type_));
const zetasql::Type* base_type = BaseType(column->type_);
ZETASQL_RET_CHECK(!column->declared_max_length_.has_value() ||
base_type->IsString() || base_type->IsBytes());
if (column->name_.length() > limits::kMaxSchemaIdentifierLength) {
return error::InvalidSchemaName("Column", column->Name());
}
if (column->source_column_) {
ZETASQL_RET_CHECK(column->type_->Equals(column->source_column_->type_));
ZETASQL_RET_CHECK(column->declared_max_length_ ==
column->source_column_->declared_max_length_);
}
if (column->declared_max_length_.has_value()) {
if (base_type->IsString() && (column->declared_max_length_.value() == 0 ||
column->declared_max_length_.value() >
limits::kMaxStringColumnLength)) {
return error::InvalidColumnLength(column->FullName(),
column->declared_max_length_.value(), 1,
limits::kMaxStringColumnLength);
}
if (base_type->IsBytes() && (column->declared_max_length_.value() == 0 ||
column->declared_max_length_.value() >
limits::kMaxBytesColumnLength)) {
return error::InvalidColumnLength(column->FullName(),
column->declared_max_length_.value(), 1,
limits::kMaxBytesColumnLength);
}
}
if (column->has_vector_length()) {
if (!column->type_->IsArray() ||
(column->type_->IsArray() && !base_type->IsFloat() &&
!base_type->IsDouble())) {
return error::InvalidTypeForVectorLength(column->FullName());
} else if (column->is_generated() || column->has_default_value()) {
return error::VectorLengthOnGeneratedOrDefaultColumn(column->FullName());
}
}
if (base_type->IsProto() || base_type->IsEnum()) {
ZETASQL_RETURN_IF_ERROR(ValidateTypeExistsInProtoBundle(
base_type, context->proto_bundle(), column->FullName()));
}
if (column->has_allows_commit_timestamp() && !column->type_->IsTimestamp()) {
return error::UnallowedCommitTimestampOption(column->FullName());
}
if (column->has_default_value()) {
if (column->allows_commit_timestamp()) {
return error::CannotUseCommitTimestampWithColumnDefaultValue(
column->Name());
}
if (context->is_postgresql_dialect()) {
ZETASQL_RET_CHECK(column->postgresql_oid().has_value());
} else {
ZETASQL_RET_CHECK(!column->postgresql_oid().has_value());
}
}
if (column->is_generated()) {
if (context->is_postgresql_dialect()) {
ZETASQL_RET_CHECK(column->postgresql_oid().has_value());
} else {
ZETASQL_RET_CHECK(!column->postgresql_oid().has_value());
}
if (!EmulatorFeatureFlags::instance().flags().enable_generated_pk &&
column->table()->FindKeyColumn(column->Name())) {
return error::CannotUseGeneratedColumnInPrimaryKey(
column->table()->Name(), column->Name());
}
for (const Column* dep : column->dependent_columns()) {
if (dep->allows_commit_timestamp()) {
return error::CannotUseCommitTimestampOnGeneratedColumnDependency(
dep->Name());
}
}
}
return absl::OkStatus();
}