absl::StatusOr RewriteColumnValue()

in backend/schema/backfills/column_value_backfill.cc [42:106]


absl::StatusOr<zetasql::Value> RewriteColumnValue(
    const zetasql::Type* old_column_type,
    const zetasql::Type* new_column_type, const zetasql::Value& value) {
  ZETASQL_RET_CHECK(old_column_type != nullptr && new_column_type != nullptr);

  if (!value.is_valid()) {
    return value;
  }

  if (value.is_null()) {
    return zetasql::Value::Null(new_column_type);
  }

  if (old_column_type->IsArray()) {
    ZETASQL_RET_CHECK(new_column_type->IsArray());
    const auto* old_elem_type = BaseType(old_column_type);
    const auto* new_elem_type = BaseType(new_column_type);
    std::vector<zetasql::Value> array_elements;
    array_elements.reserve(value.elements().size());
    for (const auto& element : value.elements()) {
      ZETASQL_ASSIGN_OR_RETURN(
          auto new_element,
          RewriteColumnValue(old_elem_type, new_elem_type, element));
      array_elements.push_back(new_element);
    }
    return zetasql::Value::Array(new_column_type->AsArray(), array_elements);
  }

  if (old_column_type->IsString() && new_column_type->IsBytes()) {
    return zetasql::Value::Bytes(value.string_value());
  }

  if (old_column_type->IsBytes() && new_column_type->IsString()) {
    return zetasql::Value::String(value.bytes_value());
  }

  if (old_column_type->IsProto() && new_column_type->IsBytes()) {
    return zetasql::Value::Bytes(value.proto_value());
  }

  if (old_column_type->IsProto() && new_column_type->IsProto()) {
    return zetasql::Value::Proto(new_column_type->AsProto(),
                                   value.proto_value());
  }

  if (old_column_type->IsBytes() && new_column_type->IsProto()) {
    return zetasql::Value::Proto(new_column_type->AsProto(),
                                   absl::Cord(value.bytes_value()));
  }

  if (old_column_type->IsEnum() && new_column_type->IsInt64()) {
    return zetasql::Value::Int64(value.enum_value());
  }

  if (old_column_type->IsInt64() && new_column_type->IsEnum()) {
    return zetasql::Value::Enum(new_column_type->AsEnum(),
                                  value.int64_value());
  }

  if (old_column_type->IsEnum() && new_column_type->IsEnum()) {
    return zetasql::Value::Enum(new_column_type->AsEnum(), value.enum_value(),
                                  true /*allow_unknown_enum_values=*/);
  }
  return absl::InternalError("Invalid type conversion");
}