Skip to content

Commit de423fc

Browse files
fix(clp-s): Handle pure wildcards and unexpected literal types correctly in EvaluateTimestampIndex (fixes #1096). (#1277)
Co-authored-by: kirkrodrigues <[email protected]>
1 parent a8444ff commit de423fc

File tree

7 files changed

+39
-17
lines changed

7 files changed

+39
-17
lines changed

components/core/src/clp_s/search/EvaluateTimestampIndex.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#include "ast/AndExpr.hpp"
44
#include "ast/Expression.hpp"
55
#include "ast/FilterExpr.hpp"
6+
#include "ast/FilterOperation.hpp"
67
#include "ast/Integral.hpp"
78
#include "ast/Literal.hpp"
89
#include "ast/OrExpr.hpp"
910

1011
using clp_s::search::ast::AndExpr;
1112
using clp_s::search::ast::Expression;
1213
using clp_s::search::ast::FilterExpr;
14+
using clp_s::search::ast::FilterOperation;
1315
using clp_s::search::ast::Integral;
1416
using clp_s::search::ast::Integral64;
1517
using clp_s::search::ast::literal_type_bitmask_t;
@@ -63,16 +65,19 @@ EvaluatedValue EvaluateTimestampIndex::run(std::shared_ptr<Expression> const& ex
6365
range_it != m_timestamp_dict->tokenized_column_to_range_end();
6466
range_it++)
6567
{
68+
// Don't attempt to evaluate the timestamp index against columns with wildcard tokens.
69+
if (column->is_unresolved_descriptor()) {
70+
continue;
71+
}
72+
6673
std::vector<std::string> const& tokens = range_it->first;
6774
auto const& descriptors = column->get_descriptor_list();
68-
// TODO: handle wildcard matching; the initial check on timestamp index happens
69-
// before schema matching, so
7075
if (tokens.size() != descriptors.size()) {
7176
continue;
7277
}
7378

7479
bool matched = true;
75-
for (size_t i = 0; i < descriptors.size(); ++i) {
80+
for (size_t i{0ULL}; i < descriptors.size(); ++i) {
7681
if (tokens[i] != descriptors[i].get_token()) {
7782
matched = false;
7883
break;
@@ -82,20 +87,21 @@ EvaluatedValue EvaluateTimestampIndex::run(std::shared_ptr<Expression> const& ex
8287
continue;
8388
}
8489

85-
EvaluatedValue ret;
86-
// this is safe after type narrowing because all DateType literals are either
87-
// Integral or a derived class of Integral
88-
Integral64 literal = std::static_pointer_cast<Integral>(filter->get_operand())->get();
89-
if (std::holds_alternative<int64_t>(literal)) {
90-
ret = range_it->second->evaluate_filter(
91-
filter->get_operation(),
92-
std::get<int64_t>(literal)
93-
);
90+
auto const literal{filter->get_operand()};
91+
if (nullptr == literal) {
92+
return EvaluatedValue::Unknown;
93+
}
94+
95+
EvaluatedValue ret{EvaluatedValue::Unknown};
96+
auto const filter_op{filter->get_operation()};
97+
int64_t int_literal{};
98+
double float_literal{};
99+
if (literal->as_int(int_literal, filter_op)) {
100+
ret = range_it->second->evaluate_filter(filter_op, int_literal);
101+
} else if (literal->as_float(float_literal, filter_op)) {
102+
ret = range_it->second->evaluate_filter(filter_op, float_literal);
94103
} else {
95-
ret = range_it->second->evaluate_filter(
96-
filter->get_operation(),
97-
std::get<double>(literal)
98-
);
104+
return EvaluatedValue::Unknown;
99105
}
100106

101107
if (ret == EvaluatedValue::True) {

components/core/tests/clp_s_test_utils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "clp_s_test_utils.hpp"
22

33
#include <filesystem>
4+
#include <optional>
45
#include <string>
56
#include <vector>
67

@@ -13,6 +14,7 @@
1314
auto compress_archive(
1415
std::string const& file_path,
1516
std::string const& archive_directory,
17+
std::optional<std::string> timestamp_key,
1618
bool single_file_archive,
1719
bool structurize_arrays,
1820
clp_s::FileType file_type
@@ -39,6 +41,9 @@ auto compress_archive(
3941
parser_option.structurize_arrays = structurize_arrays;
4042
parser_option.single_file_archive = single_file_archive;
4143
parser_option.input_file_type = file_type;
44+
if (timestamp_key.has_value()) {
45+
parser_option.timestamp_key = std::move(timestamp_key.value());
46+
}
4247

4348
clp_s::JsonParser parser{parser_option};
4449
std::vector<clp_s::ArchiveStats> archive_stats;

components/core/tests/clp_s_test_utils.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CLP_S_TEST_UTILS_HPP
22
#define CLP_S_TEST_UTILS_HPP
33

4+
#include <optional>
45
#include <string>
56
#include <vector>
67

@@ -22,6 +23,7 @@
2223
[[nodiscard]] auto compress_archive(
2324
std::string const& file_path,
2425
std::string const& archive_directory,
26+
std::optional<std::string> timestamp_key,
2527
bool single_file_archive,
2628
bool structurize_arrays,
2729
clp_s::FileType file_type

components/core/tests/test-clp_s-delta-encode-log-order.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <cstdint>
33
#include <filesystem>
44
#include <memory>
5+
#include <optional>
56
#include <string>
67
#include <string_view>
78
#include <vector>
@@ -68,6 +69,7 @@ TEST_CASE("clp-s-delta-encode-log-order", "[clp-s][delta-encode-log-order]") {
6869
REQUIRE_NOTHROW(compress_archive(
6970
get_test_input_local_path(),
7071
std::string{cTestDeltaEncodeOrderArchiveDirectory},
72+
std::nullopt,
7173
true,
7274
false,
7375
clp_s::FileType::Json

components/core/tests/test-clp_s-end_to_end.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <cstdlib>
44
#include <filesystem>
5+
#include <optional>
56
#include <string>
67
#include <string_view>
78
#include <utility>
@@ -108,6 +109,7 @@ TEST_CASE("clp-s-compress-extract-no-floats", "[clp-s][end-to-end]") {
108109
std::ignore = compress_archive(
109110
get_test_input_local_path(),
110111
std::string{cTestEndToEndArchiveDirectory},
112+
std::nullopt,
111113
single_file_archive,
112114
structurize_arrays,
113115
clp_s::FileType::Json

components/core/tests/test-clp_s-range_index.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <cstdlib>
22
#include <filesystem>
3+
#include <optional>
34
#include <string>
45
#include <string_view>
56

@@ -224,6 +225,7 @@ TEST_CASE("clp-s-range-index", "[clp-s][range-index]") {
224225
archive_stats = compress_archive(
225226
input_file,
226227
std::string{cTestRangeIndexArchiveDirectory},
228+
std::nullopt,
227229
single_file_archive,
228230
false,
229231
input_file_type

components/core/tests/test-clp_s-search.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <exception>
33
#include <filesystem>
44
#include <memory>
5+
#include <optional>
56
#include <set>
67
#include <sstream>
78
#include <string>
@@ -223,7 +224,8 @@ TEST_CASE("clp-s-search", "[clp-s][search]") {
223224
R"aa(idx: 0 OR idx: 1)aa",
224225
{1}},
225226
{R"aa(ambiguous_varstring: "a*e")aa", {10, 11, 12}},
226-
{R"aa(ambiguous_varstring: "a\*e")aa", {12}}
227+
{R"aa(ambiguous_varstring: "a\*e")aa", {12}},
228+
{R"aa(idx: * AND NOT idx: null AND idx: 0)aa", {0}}
227229
};
228230
auto structurize_arrays = GENERATE(true, false);
229231
auto single_file_archive = GENERATE(true, false);
@@ -234,6 +236,7 @@ TEST_CASE("clp-s-search", "[clp-s][search]") {
234236
std::ignore = compress_archive(
235237
get_test_input_local_path(),
236238
std::string{cTestSearchArchiveDirectory},
239+
std::string{cTestIdxKey},
237240
single_file_archive,
238241
structurize_arrays,
239242
clp_s::FileType::Json

0 commit comments

Comments
 (0)