diff --git a/jstests/query_golden/expected_output/renamed_field_as_expression_root b/jstests/query_golden/expected_output/renamed_field_as_expression_root new file mode 100644 index 00000000000..1a2ded167c8 --- /dev/null +++ b/jstests/query_golden/expected_output/renamed_field_as_expression_root @@ -0,0 +1,148 @@ + + +[jsTest] ---- +[jsTest] Inserting docs: +[jsTest] ---- + +{ } +{ "a" : "" } +{ "a" : "A somewhat large string" } +{ "a" : "A" } +{ "a" : "a" } +{ "a" : "😀" } +{ "a" : -1 } +{ "a" : -1.7976931348623157e+308 } +{ "a" : -1.7976931348623157e+308 } +{ "a" : -2 } +{ "a" : -5e-324 } +{ "a" : -Infinity } +{ "a" : /(?:)/ } +{ "a" : /A/ } +{ "a" : /a/ } +{ "a" : /a/i } +{ "a" : 0 } +{ "a" : 0 } +{ "a" : 1 } +{ "a" : 2 } +{ "a" : 5e-324 } +{ "a" : BinData(0,"") } +{ "a" : BinData(0,"asdf") } +{ "a" : ISODate("0000-01-01T00:00:00Z") } +{ "a" : ISODate("1969-12-31T23:59:59.999Z") } +{ "a" : ISODate("1970-01-01T00:00:00Z") } +{ "a" : ISODate("2022-07-14T18:34:28.937Z") } +{ "a" : ISODate("9999-12-31T23:59:59.999Z") } +{ "a" : Infinity } +{ "a" : NaN } +{ "a" : NumberDecimal("-0") } +{ "a" : NumberDecimal("-0.000") } +{ "a" : NumberDecimal("-1") } +{ "a" : NumberDecimal("-1.000") } +{ "a" : NumberDecimal("-1E-6176") } +{ "a" : NumberDecimal("-9.999999999999999999999999999999999E+6144") } +{ "a" : NumberDecimal("-Infinity") } +{ "a" : NumberDecimal("-Infinity") } +{ "a" : NumberDecimal("0") } +{ "a" : NumberDecimal("0.000") } +{ "a" : NumberDecimal("1") } +{ "a" : NumberDecimal("1E-6176") } +{ "a" : NumberDecimal("9.999999999999999999999999999999999E+6144") } +{ "a" : NumberDecimal("NaN") } +{ "a" : NumberInt(-1) } +{ "a" : NumberInt(-2) } +{ "a" : NumberInt(-2147483648) } +{ "a" : NumberInt(0) } +{ "a" : NumberInt(1) } +{ "a" : NumberInt(2) } +{ "a" : NumberInt(2147483647) } +{ "a" : NumberLong("-9223372036854775808") } +{ "a" : NumberLong("9223372036854775807") } +{ "a" : NumberLong(-1) } +{ "a" : NumberLong(-2) } +{ "a" : NumberLong(0) } +{ "a" : NumberLong(1) } +{ "a" : NumberLong(2) } +{ "a" : ObjectId("000000000000000000000000") } +{ "a" : ObjectId("62d05ec744ca83616c92772c") } +{ "a" : ObjectId("62d05fa144ca83616c92772e") } +{ "a" : ObjectId("ffffffffffffffffffffffff") } +{ "a" : UUID("167c25c0-4f45-488a-960a-3171ec07726b") } +{ "a" : UUID("326d92af-2d76-452b-a03f-69f05ab98416") } +{ "a" : [ ] } +{ "a" : false } +{ "a" : function inc(x) { + return x + 1; + } } +{ "a" : null } +{ "a" : true } +{ "a" : undefined } +{ "a" : { } } +{ "a" : { "$maxKey" : 1 } } +{ "a" : { "$minKey" : 1 } } + + +[jsTest] ---- +[jsTest] Result of query: +[jsTest] ---- + +{ "newA" : "" } +{ "newA" : "A somewhat large string" } +{ "newA" : "A" } +{ "newA" : "a" } +{ "newA" : "😀" } +{ "newA" : -1 } +{ "newA" : -1 } +{ "newA" : -1.7976931348623157e+308 } +{ "newA" : -1.7976931348623157e+308 } +{ "newA" : -2 } +{ "newA" : -2 } +{ "newA" : -2147483648 } +{ "newA" : -5e-324 } +{ "newA" : -Infinity } +{ "newA" : /(?:)/ } +{ "newA" : /A/ } +{ "newA" : /a/ } +{ "newA" : /a/i } +{ "newA" : 1 } +{ "newA" : 1 } +{ "newA" : 2 } +{ "newA" : 2 } +{ "newA" : 2147483647 } +{ "newA" : 5e-324 } +{ "newA" : BinData(0,"") } +{ "newA" : BinData(0,"asdf") } +{ "newA" : ISODate("0000-01-01T00:00:00Z") } +{ "newA" : ISODate("1969-12-31T23:59:59.999Z") } +{ "newA" : ISODate("1970-01-01T00:00:00Z") } +{ "newA" : ISODate("2022-07-14T18:34:28.937Z") } +{ "newA" : ISODate("9999-12-31T23:59:59.999Z") } +{ "newA" : Infinity } +{ "newA" : NaN } +{ "newA" : NumberDecimal("-1") } +{ "newA" : NumberDecimal("-1.000") } +{ "newA" : NumberDecimal("-1E-6176") } +{ "newA" : NumberDecimal("-9.999999999999999999999999999999999E+6144") } +{ "newA" : NumberDecimal("-Infinity") } +{ "newA" : NumberDecimal("-Infinity") } +{ "newA" : NumberDecimal("1") } +{ "newA" : NumberDecimal("1E-6176") } +{ "newA" : NumberDecimal("9.999999999999999999999999999999999E+6144") } +{ "newA" : NumberDecimal("NaN") } +{ "newA" : NumberLong("-9223372036854775808") } +{ "newA" : NumberLong("9223372036854775807") } +{ "newA" : NumberLong(-1) } +{ "newA" : NumberLong(-2) } +{ "newA" : NumberLong(1) } +{ "newA" : NumberLong(2) } +{ "newA" : ObjectId("000000000000000000000000") } +{ "newA" : ObjectId("62d05ec744ca83616c92772c") } +{ "newA" : ObjectId("62d05fa144ca83616c92772e") } +{ "newA" : ObjectId("ffffffffffffffffffffffff") } +{ "newA" : UUID("167c25c0-4f45-488a-960a-3171ec07726b") } +{ "newA" : UUID("326d92af-2d76-452b-a03f-69f05ab98416") } +{ "newA" : [ ] } +{ "newA" : true } +{ "newA" : { } } +{ "newA" : { "code" : "function inc(x) {\n return x + 1;\n }" } } +{ "newA" : { "$maxKey" : 1 } } +{ "newA" : { "$minKey" : 1 } } diff --git a/jstests/query_golden/renamed_field_as_expression_root.js b/jstests/query_golden/renamed_field_as_expression_root.js new file mode 100644 index 00000000000..4449fd3a823 --- /dev/null +++ b/jstests/query_golden/renamed_field_as_expression_root.js @@ -0,0 +1,24 @@ +/** + * Tests a query which renames a field and then returns documents where the value of the renamed + * field is either true or "truthy". + * + * This test was originally designed to reproduce SERVER-113319. + */ + +import {show} from "jstests/libs/golden_test.js"; +import {leafs, unaryDocs} from "jstests/query_golden/libs/example_data.js"; + +const docs = unaryDocs("a", leafs()); +// Also include a document where "a" is missing. +docs.push({}); + +const coll = db.renamed_field_as_expression_root; +coll.drop(); + +jsTestLog("Inserting docs:"); +show(docs); +coll.insert(docs); + +let pipeline = [{$project: {_id: 0, newA: "$a"}}, {$match: {$expr: "$newA"}}]; +jsTestLog("Result of query:"); +show(coll.aggregate(pipeline)); diff --git a/src/mongo/db/matcher/expression_expr.h b/src/mongo/db/matcher/expression_expr.h index b056886c8cd..0ee95f34179 100644 --- a/src/mongo/db/matcher/expression_expr.h +++ b/src/mongo/db/matcher/expression_expr.h @@ -155,7 +155,11 @@ public: */ void applyRename(const StringMap& renameList) { SubstituteFieldPathWalker substituteWalker(renameList); - expression_walker::walk(_expression.get(), &substituteWalker); + if (auto newExpr = + expression_walker::walk(_expression.get(), &substituteWalker); + newExpr) { + _expression = newExpr.release(); + } } bool hasRenameablePath(const StringMap& renameList) const {