in backend/schema/validators/udf_validator.cc [97:181]
absl::Status UdfValidator::ValidateUpdate(const Udf* udf, const Udf* old_udf,
SchemaValidationContext* context) {
// During a REPLACE, the udf name's case can change.
if (context->IsModifiedNode(udf)) {
ZETASQL_RET_CHECK(absl::EqualsIgnoreCase(udf->Name(), old_udf->Name()));
} else {
ZETASQL_RET_CHECK_EQ(udf->Name(), old_udf->Name());
}
if (udf->is_deleted()) {
context->global_names()->RemoveName(udf->Name());
return absl::OkStatus();
}
if (context->is_postgresql_dialect()) {
ZETASQL_RET_CHECK(udf->postgresql_oid().has_value());
ZETASQL_RET_CHECK(old_udf->postgresql_oid().has_value());
ZETASQL_RET_CHECK_EQ(udf->postgresql_oid().value(),
old_udf->postgresql_oid().value());
} else {
ZETASQL_RET_CHECK(!udf->postgresql_oid().has_value());
ZETASQL_RET_CHECK(!old_udf->postgresql_oid().has_value());
}
for (const SchemaNode* dependency : udf->dependencies()) {
// Cannot drop dependencies of the udf.
if (dependency->is_deleted()) {
// If the deleted dependency is a column that was marked as deleted
// as a result of a table drop, then we use the table to report the error
// message.
if (auto dep_column = dependency->As<const Column>();
dep_column != nullptr) {
const Table* dep_table = dep_column->table();
if (dep_table->is_deleted()) {
dependency = dep_table;
}
}
const auto& dep_info = dependency->GetSchemaNameInfo();
std::string dependency_type =
(dep_info->global ? absl::AsciiStrToUpper(dep_info->kind)
: absl::AsciiStrToLower(dep_info->kind));
return error::InvalidDropDependentFunction(dependency_type,
dep_info->name, udf->Name());
}
// If a dependency was updated during the schema change then we need to
// re-analyze *this.
if (context->IsModifiedNode(dependency)) {
const auto& dep_info = dependency->GetSchemaNameInfo();
std::string dependency_type =
(dep_info->global ? absl::AsciiStrToUpper(dep_info->kind)
: absl::AsciiStrToLower(dep_info->kind));
std::string modify_action = absl::StrCat("alter ", dependency_type);
std::string dependency_name;
if (auto dep_view = dependency->As<const View>(); dep_view != nullptr) {
dependency_name = dep_view->Name();
}
if (auto dep_table = dependency->As<const Table>();
dep_table != nullptr) {
dependency_name = dep_table->Name();
}
if (auto dep_column = dependency->As<const Column>();
dep_column != nullptr) {
dependency_name = dep_column->FullName();
}
if (auto dep_udf = dependency->As<const Udf>(); dep_udf != nullptr) {
dependency_name = dep_udf->Name();
}
// No need to check modifications on index dependencies as indexes
// cannot currently be altered.
std::string param_list = "";
auto args = udf->signature()->arguments();
for (int i = 0; i < args.size(); i++) {
const auto& param = args[i];
param_list += param.argument_name() + " " +
param.type()->TypeName(zetasql::PRODUCT_EXTERNAL);
if (i < args.size() - 1) {
param_list += ", ";
}
}
ZETASQL_RETURN_IF_ERROR(ValidateUdfSignatureChange(
modify_action, dependency_name, param_list, udf,
context->tmp_new_schema(), context->type_factory()));
}
}
return absl::OkStatus();
}