Skip to content

Commit 85ddbd8

Browse files
committed
Fix MongoStatement.getFieldNamesFromProjectStage
1 parent 804af82 commit 85ddbd8

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

Diff for: src/main/java/com/mongodb/hibernate/jdbc/MongoStatement.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ ResultSet executeQueryCommand(BsonDocument command) throws SQLException {
8989
@VisibleForTesting(otherwise = PRIVATE)
9090
static List<String> getFieldNamesFromProjectStage(BsonDocument projectStage) {
9191
var fieldNames = projectStage.entrySet().stream()
92-
.filter(field -> trueOrOne(field.getValue()))
92+
.filter(MongoStatement::isIncludeProjectSpecification)
9393
.map(Map.Entry::getKey)
9494
.collect(toCollection(ArrayList::new));
9595
if (!projectStage.containsKey(ID_FIELD_NAME)) {
@@ -99,9 +99,21 @@ static List<String> getFieldNamesFromProjectStage(BsonDocument projectStage) {
9999
return fieldNames;
100100
}
101101

102-
private static boolean trueOrOne(BsonValue value) {
103-
return (value.isBoolean() && value.asBoolean().getValue())
102+
private static boolean isIncludeProjectSpecification(Map.Entry<String, BsonValue> specification) {
103+
var value = specification.getValue();
104+
if (value.isString() || value.isDocument()) {
105+
throw new RuntimeException(format(
106+
"Expressions are not allowed in `$project` specifications: [%s: %s]",
107+
specification.getKey(), specification.getValue()));
108+
}
109+
var include = (value.isBoolean() && value.asBoolean().getValue())
104110
|| (value.isNumber() && value.asNumber().intValue() == 1);
111+
if (!include && !specification.getKey().equals(ID_FIELD_NAME)) {
112+
throw new RuntimeException(format(
113+
"Exclusions are not allowed in `$project` specifications, except for the [%s] field: [%s, %s]",
114+
ID_FIELD_NAME, specification.getKey(), specification.getValue()));
115+
}
116+
return include;
105117
}
106118

107119
@Override

Diff for: src/test/java/com/mongodb/hibernate/jdbc/MongoStatementTests.java

+15-7
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,23 @@ void testExecuteBatch() throws SQLException {
183183

184184
@Test
185185
void testGetProjectStageFieldNames() {
186-
BiConsumer<String, List<String>> asserter = (projectStage, expectedFieldNames) -> assertEquals(
186+
BiConsumer<String, List<String>> successAsserter = (projectStage, expectedFieldNames) -> assertEquals(
187187
expectedFieldNames, MongoStatement.getFieldNamesFromProjectStage(BsonDocument.parse(projectStage)));
188+
BiConsumer<String, String> failureAsserter = (projectStage, expectedMessageFragment) -> {
189+
Throwable e = assertThrows(
190+
RuntimeException.class,
191+
() -> MongoStatement.getFieldNamesFromProjectStage(BsonDocument.parse(projectStage)));
192+
assertThat(e.getMessage()).contains(expectedMessageFragment);
193+
};
188194
assertAll(
189-
() -> asserter.accept("{title: 1, publishYear: 1}", List.of("title", "publishYear", "_id")),
190-
() -> asserter.accept("{title: 1, publishYear: 0}", List.of("title", "_id")),
191-
() -> asserter.accept("{title: 1, publishYear: false}", List.of("title", "_id")),
192-
() -> asserter.accept("{title: 1, _id: 0}", List.of("title")),
193-
() -> asserter.accept("{title: 1, _id: false}", List.of("title")),
194-
() -> asserter.accept("{_id: 1, title: 1}", List.of("_id", "title")));
195+
() -> successAsserter.accept("{title: 1, publishYear: 1}", List.of("title", "publishYear", "_id")),
196+
() -> successAsserter.accept("{title: 1, _id: 0}", List.of("title")),
197+
() -> successAsserter.accept("{title: 1, _id: false}", List.of("title")),
198+
() -> successAsserter.accept("{_id: 1, title: 1}", List.of("_id", "title")),
199+
() -> failureAsserter.accept("{title: 1, publishYear: 0}", "Exclusions are not allowed"),
200+
() -> failureAsserter.accept("{title: 1, publishYear: false}", "Exclusions are not allowed"),
201+
() -> failureAsserter.accept("{title: '$fieldName'}", "Expressions are not allowed"),
202+
() -> failureAsserter.accept("{title: {fieldName: 'fieldValue'}}", "Expressions are not allowed"));
195203
}
196204

197205
@Nested

0 commit comments

Comments
 (0)