Skip to content

Commit f976f36

Browse files
authored
Remove error on non existent subdoc exists (#444)
1 parent 43cf66a commit f976f36

6 files changed

+73
-3
lines changed

core/impl/lookup_in_all_replicas.cxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ initiate_lookup_in_all_replicas_operation(std::shared_ptr<cluster> core,
113113
lookup_in_entry.value = field.value;
114114
lookup_in_entry.exists = field.exists;
115115
lookup_in_entry.original_index = field.original_index;
116+
lookup_in_entry.ec = field.ec;
117+
if (field.opcode == protocol::subdoc_opcode::exists && field.ec == errc::key_value::path_not_found) {
118+
lookup_in_entry.ec.clear();
119+
}
116120
entries.emplace_back(lookup_in_entry);
117121
}
118122
ctx->result_.emplace_back(lookup_in_replica_result{ resp.cas, entries, resp.deleted, true /* replica */ });
@@ -155,6 +159,10 @@ initiate_lookup_in_all_replicas_operation(std::shared_ptr<cluster> core,
155159
lookup_in_entry.value = field.value;
156160
lookup_in_entry.exists = field.exists;
157161
lookup_in_entry.original_index = field.original_index;
162+
lookup_in_entry.ec = field.ec;
163+
if (field.opcode == protocol::subdoc_opcode::exists && field.ec == errc::key_value::path_not_found) {
164+
lookup_in_entry.ec.clear();
165+
}
158166
entries.emplace_back(lookup_in_entry);
159167
}
160168
ctx->result_.emplace_back(lookup_in_replica_result{ resp.cas, entries, resp.deleted, false /* active */ });

core/impl/lookup_in_any_replica.cxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ initiate_lookup_in_any_replica_operation(std::shared_ptr<cluster> core,
118118
entry.original_index = field.original_index;
119119
entry.exists = field.exists;
120120
entry.value = field.value;
121+
entry.ec = field.ec;
122+
if (field.opcode == protocol::subdoc_opcode::exists &&
123+
field.ec == errc::key_value::path_not_found) {
124+
entry.ec.clear();
125+
}
121126
entries.emplace_back(entry);
122127
}
123128
return local_handler(std::move(resp.ctx),
@@ -156,6 +161,10 @@ initiate_lookup_in_any_replica_operation(std::shared_ptr<cluster> core,
156161
entry.original_index = field.original_index;
157162
entry.exists = field.exists;
158163
entry.value = field.value;
164+
entry.ec = field.ec;
165+
if (field.opcode == protocol::subdoc_opcode::exists && field.ec == errc::key_value::path_not_found) {
166+
entry.ec.clear();
167+
}
159168
entries.emplace_back(entry);
160169
}
161170
return local_handler(std::move(resp.ctx),

core/operations/document_lookup_in.cxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ lookup_in_request::make_response(key_value_error_context&& ctx, const encoded_re
7070
fields[i].status = res_entry.status;
7171
fields[i].ec =
7272
protocol::map_status_code(protocol::client_opcode::subdoc_multi_mutation, static_cast<std::uint16_t>(res_entry.status));
73+
if (fields[i].opcode == protocol::subdoc_opcode::exists && fields[i].ec == errc::key_value::path_not_found) {
74+
fields[i].ec.clear();
75+
}
7376
if (!fields[i].ec && !ctx.ec()) {
7477
ec = fields[i].ec;
7578
}

core/operations/document_lookup_in_all_replicas.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ struct lookup_in_all_replicas_request {
127127
lookup_in_entry.exists = field.exists;
128128
lookup_in_entry.original_index = field.original_index;
129129
lookup_in_entry.opcode = field.opcode;
130+
if (lookup_in_entry.opcode == protocol::subdoc_opcode::exists &&
131+
lookup_in_entry.ec == errc::key_value::path_not_found) {
132+
lookup_in_entry.ec.clear();
133+
}
130134
top_entry.fields.emplace_back(lookup_in_entry);
131135
}
132136
ctx->result_.emplace_back(lookup_in_all_replicas_response::entry{ top_entry });
@@ -169,6 +173,10 @@ struct lookup_in_all_replicas_request {
169173
lookup_in_entry.exists = field.exists;
170174
lookup_in_entry.original_index = field.original_index;
171175
lookup_in_entry.opcode = field.opcode;
176+
if (lookup_in_entry.opcode == protocol::subdoc_opcode::exists &&
177+
lookup_in_entry.ec == errc::key_value::path_not_found) {
178+
lookup_in_entry.ec.clear();
179+
}
172180
top_entry.fields.emplace_back(lookup_in_entry);
173181
}
174182
ctx->result_.emplace_back(lookup_in_all_replicas_response::entry{ top_entry });

core/operations/document_lookup_in_any_replica.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ struct lookup_in_any_replica_request {
133133
lookup_in_entry.exists = field.exists;
134134
lookup_in_entry.original_index = field.original_index;
135135
lookup_in_entry.opcode = field.opcode;
136+
if (lookup_in_entry.opcode == protocol::subdoc_opcode::exists &&
137+
lookup_in_entry.ec == errc::key_value::path_not_found) {
138+
lookup_in_entry.ec.clear();
139+
}
136140
res.fields.emplace_back(lookup_in_entry);
137141
}
138142
return local_handler(res);
@@ -173,6 +177,10 @@ struct lookup_in_any_replica_request {
173177
lookup_in_entry.exists = field.exists;
174178
lookup_in_entry.original_index = field.original_index;
175179
lookup_in_entry.opcode = field.opcode;
180+
if (lookup_in_entry.opcode == protocol::subdoc_opcode::exists &&
181+
lookup_in_entry.ec == errc::key_value::path_not_found) {
182+
lookup_in_entry.ec.clear();
183+
}
176184
res.fields.emplace_back(lookup_in_entry);
177185
}
178186
return local_handler(res);

test/test_integration_subdoc.cxx

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ TEST_CASE("integration: subdoc get & exists", "[integration]")
252252
id,
253253
couchbase::lookup_in_specs::exists("non-exist"),
254254
couchbase::key_value_status_code::subdoc_path_not_found,
255-
couchbase::errc::key_value::path_not_found);
255+
std::error_code{});
256256
}
257257

258258
SECTION("non existent doc")
@@ -1153,7 +1153,7 @@ TEST_CASE("integration: subdoc all replica reads", "[integration]")
11531153
id,
11541154
couchbase::lookup_in_specs::exists("non-exist"),
11551155
couchbase::key_value_status_code::subdoc_path_not_found,
1156-
couchbase::errc::key_value::path_not_found);
1156+
std::error_code{});
11571157
}
11581158

11591159
SECTION("non existent doc")
@@ -1295,6 +1295,19 @@ TEST_CASE("integration: subdoc all replica reads", "[integration]")
12951295
REQUIRE(ctx.ec() == couchbase::errc::key_value::document_not_found);
12961296
REQUIRE(result.empty());
12971297
}
1298+
1299+
SECTION("non existent path exists")
1300+
{
1301+
auto specs = couchbase::lookup_in_specs{
1302+
couchbase::lookup_in_specs::exists("non-exists"),
1303+
};
1304+
auto [ctx, result] = collection.lookup_in_all_replicas(key, specs).get();
1305+
REQUIRE_SUCCESS(ctx.ec());
1306+
for (auto& res : result) {
1307+
REQUIRE(!res.cas().empty());
1308+
REQUIRE(!res.exists(0));
1309+
}
1310+
}
12981311
}
12991312
}
13001313

@@ -1376,7 +1389,7 @@ TEST_CASE("integration: subdoc any replica reads", "[integration]")
13761389
id,
13771390
couchbase::lookup_in_specs::exists("non-exist"),
13781391
couchbase::key_value_status_code::subdoc_path_not_found,
1379-
couchbase::errc::key_value::path_not_found);
1392+
std::error_code{});
13801393
}
13811394

13821395
SECTION("non existent doc")
@@ -1540,6 +1553,16 @@ TEST_CASE("integration: subdoc any replica reads", "[integration]")
15401553
REQUIRE(ctx.ec() == couchbase::errc::common::invalid_argument);
15411554
REQUIRE(result.cas().empty());
15421555
}
1556+
1557+
SECTION("non existent path exists")
1558+
{
1559+
auto specs = couchbase::lookup_in_specs{
1560+
couchbase::lookup_in_specs::exists("non-exists"),
1561+
};
1562+
auto [ctx, result] = collection.lookup_in_any_replica(key, specs).get();
1563+
REQUIRE_SUCCESS(ctx.ec());
1564+
REQUIRE(!result.exists(0));
1565+
}
15431566
}
15441567
}
15451568

@@ -1627,4 +1650,15 @@ TEST_CASE("integration: public API lookup in per-spec errors", "[integration]")
16271650
}
16281651
REQUIRE_SUCCESS(ec);
16291652
}
1653+
1654+
SECTION("non existent path exists")
1655+
{
1656+
auto specs = couchbase::lookup_in_specs{
1657+
couchbase::lookup_in_specs::exists("dictkey2"),
1658+
};
1659+
auto [ctx, result] = collection.lookup_in(key, specs).get();
1660+
1661+
REQUIRE_SUCCESS(ctx.ec());
1662+
REQUIRE(!result.exists(0));
1663+
}
16301664
}

0 commit comments

Comments
 (0)