aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/expression/attributenode.h
blob: 683f20228c393552d41ba57acea3f2137746731b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "currentindex.h"
#include "functionnode.h"
#include "attributeresult.h"
#include "current_index_setup.h"
#include <vespa/vespalib/objects/objectoperation.h>
#include <vespa/vespalib/objects/objectpredicate.h>

namespace search::attribute { class IAttributeContext; }

namespace search::expression {

class AttributeNode : public FunctionNode
{
    using BufferRef = vespalib::BufferRef;
    using ConstBufferRef = vespalib::ConstBufferRef;
public:
    DECLARE_NBO_SERIALIZE;
    class Configure : public vespalib::ObjectOperation, public vespalib::ObjectPredicate
    {
    public:
        Configure(const attribute::IAttributeContext & attrCtx) : _attrCtx(attrCtx) { }
    private:
        void execute(vespalib::Identifiable &obj) override {
            static_cast<ExpressionNode &>(obj).wireAttributes(_attrCtx);
            obj.selectMembers(*this, *this);
        }
        bool check(const vespalib::Identifiable &obj) const override {
            return obj.inherits(ExpressionNode::classId);
        }
        const attribute::IAttributeContext & _attrCtx;
    };

    class CleanupAttributeReferences : public vespalib::ObjectOperation, public vespalib::ObjectPredicate
    {
    private:
        void execute(vespalib::Identifiable &obj) override { static_cast<AttributeNode &>(obj).cleanup(); }
        bool check(const vespalib::Identifiable &obj) const override { return obj.inherits(AttributeNode::classId); }
    };

    void visitMembers(vespalib::ObjectVisitor &visitor) const override;
    DECLARE_EXPRESSIONNODE(AttributeNode);
    AttributeNode();
    AttributeNode(vespalib::stringref name);
    AttributeNode(const attribute::IAttributeVector & attribute);
    AttributeNode(const AttributeNode & attribute);
    AttributeNode & operator = (const AttributeNode & attribute);
    ~AttributeNode() override;
    void setDocId(DocId docId);
    const CurrentIndex *getCurrentIndex() { return _index; }
    void setCurrentIndex(const CurrentIndex * index) { _index = index; }
    const attribute::IAttributeVector *getAttribute() const {
        return _scratchResult ? _scratchResult->getAttribute() : nullptr;
    }
    const vespalib::string & getAttributeName() const noexcept { return _attributeName; }

    void enableEnumOptimization(bool enable) noexcept { _useEnumOptimization = enable; }
public:
    class Handler
    {
    public:
        virtual ~Handler() = default;
        virtual void handle(const AttributeResult & r) = 0;
    };
private:
    virtual std::pair<std::unique_ptr<ResultNode>, std::unique_ptr<Handler>>
    createResultHandler(bool preserveAccurateType, const attribute::IAttributeVector & attribute) const;
    template <typename V> class IntegerHandler;
    class FloatHandler;
    class StringHandler;
    class EnumHandler;
    void wireAttributes(const attribute::IAttributeContext & attrCtx) override;
    void onPrepare(bool preserveAccurateTypes) final;

    std::unique_ptr<AttributeResult>  _scratchResult;
    const CurrentIndex               *_index;
    std::unique_ptr<ResultNodeVector> _keepAliveForIndexLookups;
    bool                              _hasMultiValue;
    bool                              _useEnumOptimization;
    mutable bool                      _needExecute;
    std::unique_ptr<Handler>          _handler;
protected:
    void setHasMultiValue(bool has) noexcept { _hasMultiValue = has; }
    [[nodiscard]] bool useEnumOptimization() const noexcept { return _useEnumOptimization; }
    [[nodiscard]] bool hasMultiValue() const noexcept { return _hasMultiValue; }

    void setScratchResult(std::unique_ptr<AttributeResult> result) noexcept {
        _scratchResult = std::move(result);
    }
    virtual void cleanup();
    bool onExecute() const override;
    vespalib::string                  _attributeName;
};

}