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;
};
}
|