Repository: vespa-engine/vespa
File: searchlib/src/vespa/searchlib/expression/attribute_map_lookup_node.cpp (C++)

Code before:
                    return prepareIntValues<int8_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                case BasicType::INT16:
                    return prepareIntValues<int16_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                case BasicType::INT32:
                    return prepareIntValues<int32_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                case BasicType::INT64:
                    return prepareIntValues<int64_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                default:
                    throw std::runtime_error("This is no valid integer attribute " + attribute.getName());
            }
        }
    } else if (attribute.isFloatingPointType()) {
        auto resultNode = std::make_unique<FloatResultNode>();
        switch (basicType) {
            case BasicType::FLOAT:
            {
                auto handler = std::make_unique<FloatValueHandler<float>>(std::move(keyHandler), attribute, *resultNode, getUndefined<double>());
                return { std::move(resultNode), std::move(handler) };
            }
            case BasicType::DOUBLE:
            {
                auto handler = std::make_unique<FloatValueHandler<double>>(std::move(keyHandler), attribute, *resultNode, getUndefined<double>());
                return { std::move(resultNode), std::move(handler) };
            }
            default:
                throw std::runtime_error("This is no valid float attribute " + attribute.getName());
        }
    } else if (attribute.isStringType()) {
        if (useEnumOptimization()) {
            auto resultNode = std::make_unique<EnumResultNode>();
            const StringAttribute & sattr = dynamic_cast<const StringAttribute &>(attribute);
            EnumHandle undefined(0);
            bool found = attribute.findEnum(sattr.defaultValue(), undefined);
            assert(found);
            auto handler = std::make_unique<EnumValueHandler>(std::move(keyHandler), attribute, *resultNode, undefined);
            return { std::move(resultNode), std::move(handler) };
        } else {
            auto resultNode = std::make_unique<StringResultNode>();
            auto handler = std::make_unique<StringValueHandler>(std::move(keyHandler), attribute, *resultNode, "");
            return { std::move(resultNode), std::move(handler) };
        }
    } else {
        throw std::runtime_error(vespalib::make_string("Can not deduce correct resultclass for attribute vector '%s'",
                                                       attribute.getName().c_str()));
    }
}

void
AttributeMapLookupNode::cleanup()
{
    _keyAttribute = nullptr;

Review comment (bug):
Maybe the error messages here could be made more user-friendly (quoting the attribute name, stating the context in which it failed etc.)

Code after:
                    return prepareIntValues<bool, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                case BasicType::INT8:
                    return prepareIntValues<int8_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                case BasicType::INT16:
                    return prepareIntValues<int16_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                case BasicType::INT32:
                    return prepareIntValues<int32_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                case BasicType::INT64:
                    return prepareIntValues<int64_t, Int64ResultNode>(std::move(keyHandler), attribute, undefinedValue);
                default:
                    throw std::runtime_error(std::format("'{}' is not a valid integer attribute",
                                                         " for attribute map lookup result", attribute.getName()));
            }
        }
    } else if (attribute.isFloatingPointType()) {
        auto resultNode = std::make_unique<FloatResultNode>();
        switch (basicType) {
            case BasicType::FLOAT:
            {
                auto handler = std::make_unique<FloatValueHandler<float>>(std::move(keyHandler), attribute, *resultNode, getUndefined<double>());
                return { std::move(resultNode), std::move(handler) };
            }
            case BasicType::DOUBLE:
            {
                auto handler = std::make_unique<FloatValueHandler<double>>(std::move(keyHandler), attribute, *resultNode, getUndefined<double>());
                return { std::move(resultNode), std::move(handler) };
            }
            default:
                throw std::runtime_error(std::format("'{}' is not a valid float attribute"
                                                     " for attribute map lookup result", attribute.getName()));
        }
    } else if (attribute.isStringType()) {
        if (useEnumOptimization()) {
            auto resultNode = std::make_unique<EnumResultNode>();
            const StringAttribute & sattr = dynamic_cast<const StringAttribute &>(attribute);
            EnumHandle undefined(0);
            bool found = attribute.findEnum(sattr.defaultValue(), undefined);
            assert(found);
            auto handler = std::make_unique<EnumValueHandler>(std::move(keyHandler), attribute, *resultNode, undefined);
            return { std::move(resultNode), std::move(handler) };
        } else {
            auto resultNode = std::make_unique<StringResultNode>();
            auto handler = std::make_unique<StringValueHandler>(std::move(keyHandler), attribute, *resultNode, "");
            return { std::move(resultNode), std::move(handler) };
        }
    } else {
        throw std::runtime_error(std::format("Can not deduce correct resultclass for attribute vector '{}'"
                                             " for attribute map lookup result", attribute.getName()));
    }
}