Skip to content

Commit 085dccd

Browse files
committed
fixed predicate chaining bug
1 parent 07de248 commit 085dccd

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

include/query_predicates.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ namespace sqlite_reflection {
4040
/// Returns a textual representation of the predicate, ready to be consumed by the SELECT query
4141
virtual std::string Evaluate() const = 0;
4242

43+
/// Creates a clone for compounding predicates
44+
virtual QueryPredicateBase* Clone() const = 0;
45+
4346
/// Returns a compound predicate, which requires that both the current
4447
/// and the other predicate are valid at the same time
4548
AndPredicate And(const QueryPredicateBase& other) const;
@@ -56,11 +59,13 @@ namespace sqlite_reflection {
5659
{
5760
public:
5861
std::string Evaluate() const override;
62+
QueryPredicateBase* Clone() const override;
5963

6064
protected:
6165
template <typename T, typename R>
62-
QueryPredicate(R T::* fn, R value, const std::string& symbol, std::function<std::string(void*, SqliteStorageClass)> value_retrieval) {
63-
symbol_ = symbol;
66+
QueryPredicate(R T::* fn, R value, const std::string& symbol, std::function<std::string(void*, SqliteStorageClass)> value_retrieval)
67+
: symbol_(symbol)
68+
{
6469
auto record = GetRecordFromTypeId(typeid(T).name());
6570
auto offset = OffsetFromStart(fn);
6671
for (auto i = 0; i < record.member_metadata.size(); ++i) {
@@ -78,6 +83,9 @@ namespace sqlite_reflection {
7883
return GetStringForValue(v, storage_class);
7984
}) {}
8085

86+
QueryPredicate(const std::string& symbol, const std::string& member_name, const std::string& value)
87+
: symbol_(symbol), member_name_(member_name), value_(value) {}
88+
8189
/// Returns a textual representation of the value used for the current query, against which the
8290
/// struct member (defined from the pointer-to-member function) will be compared. The value needs
8391
/// to be type-erased, so that the header file is not bloated with unnecessary implementation details
@@ -100,6 +108,7 @@ namespace sqlite_reflection {
100108
{
101109
public:
102110
std::string Evaluate() const override;
111+
QueryPredicateBase* Clone() const override;
103112
};
104113

105114
/// A wrapper for an equality predicate, for which the value of the
@@ -204,8 +213,8 @@ namespace sqlite_reflection {
204213
protected:
205214
BinaryPredicate(const QueryPredicateBase& left, const QueryPredicateBase& right, const std::string& symbol);
206215

207-
const QueryPredicateBase* left_;
208-
const QueryPredicateBase* right_;
216+
std::unique_ptr<QueryPredicateBase> left_;
217+
std::unique_ptr<QueryPredicateBase> right_;
209218
std::string symbol_;
210219
};
211220

@@ -214,12 +223,14 @@ namespace sqlite_reflection {
214223
{
215224
public:
216225
AndPredicate(const QueryPredicateBase& left, const QueryPredicateBase& right);
226+
QueryPredicateBase* Clone() const override;
217227
};
218228

219229
/// A compound predicate, which requires that either predicate is valid
220230
class REFLECTION_EXPORT OrPredicate final : public BinaryPredicate
221231
{
222232
public:
223233
OrPredicate(const QueryPredicateBase& left, const QueryPredicateBase& right);
234+
QueryPredicateBase* Clone() const override;
224235
};
225236
}

src/query_predicates.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,18 @@ const std::string single_quote("'");
2929
const std::string space(" ");
3030
const std::string percent("%");
3131

32+
QueryPredicateBase* QueryPredicate::Clone() const {
33+
return new QueryPredicate(symbol_, member_name_, value_);
34+
}
35+
3236
std::string EmptyPredicate::Evaluate() const {
3337
return "";
3438
}
3539

40+
QueryPredicateBase* EmptyPredicate::Clone() const {
41+
return new EmptyPredicate();
42+
}
43+
3644
AndPredicate QueryPredicateBase::And(const QueryPredicateBase& other) const {
3745
return AndPredicate(*this, other);
3846
}
@@ -89,7 +97,7 @@ std::string Like::Remove(const std::string& source, const std::string& substring
8997
}
9098

9199
BinaryPredicate::BinaryPredicate(const QueryPredicateBase& left, const QueryPredicateBase& right, const std::string& symbol)
92-
: left_(&left), right_(&right), symbol_(symbol) {}
100+
: left_(left.Clone()), right_(right.Clone()), symbol_(symbol) {}
93101

94102
std::string BinaryPredicate::Evaluate() const {
95103
return "(" + left_->Evaluate() + space + symbol_ + space + right_->Evaluate() + ")";
@@ -98,5 +106,13 @@ std::string BinaryPredicate::Evaluate() const {
98106
AndPredicate::AndPredicate(const QueryPredicateBase& left, const QueryPredicateBase& right)
99107
: BinaryPredicate(left, right, "AND") {}
100108

109+
QueryPredicateBase* AndPredicate::Clone() const {
110+
return new AndPredicate(*left_.get(), *right_.get());
111+
}
112+
101113
OrPredicate::OrPredicate(const QueryPredicateBase& left, const QueryPredicateBase& right)
102114
: BinaryPredicate(left, right, "OR") {}
115+
116+
QueryPredicateBase* OrPredicate::Clone() const {
117+
return new OrPredicate(*left_.get(), *right_.get());
118+
}

0 commit comments

Comments
 (0)