import "jstests/libs/query/sbe_assert_error_override.js"; import {executeAggregationTestCase} from "jstests/libs/query/aggregation_pipeline_utils.js"; const coll = db.regex_error_cases; coll.drop(); function assertFails(parameters, errorCode, allowNullResponse = false) { // Check constant parameters. let inputDocument = {text: "ABCD"}; const constantParameters = Object.assign({input: "$text"}, parameters); const regexMatchTest = Object.assign( {inputDocuments: inputDocument, expectedErrorCode: errorCode}, allowNullResponse ? {expectedResults: [{"result": false}]} : {}, ); const regexFindTest = Object.assign( {inputDocuments: inputDocument, expectedErrorCode: errorCode}, allowNullResponse ? {expectedResults: [{"result": null}]} : {}, ); const regexFindAllTest = Object.assign( {inputDocuments: inputDocument, expectedErrorCode: errorCode}, allowNullResponse ? {expectedResults: [{"result": []}]} : {}, ); executeAggregationTestCase( coll, Object.assign( {pipeline: [{$project: {"_id": 0, result: {"$regexMatch": constantParameters}}}]}, regexMatchTest, ), ); executeAggregationTestCase( coll, Object.assign({pipeline: [{$project: {"_id": 0, result: {"$regexFind": constantParameters}}}]}, regexFindTest), ); executeAggregationTestCase( coll, Object.assign( {pipeline: [{$project: {"_id": 0, result: {"$regexFindAll": constantParameters}}}]}, regexFindAllTest, ), ); // Check constant parameters, but without optimization phase. try { assert.commandWorked( db.adminCommand({"configureFailPoint": "disablePipelineOptimization", "mode": "alwaysOn"}), ); executeAggregationTestCase( coll, Object.assign( {pipeline: [{$project: {"_id": 0, result: {"$regexMatch": constantParameters}}}]}, regexMatchTest, ), ); executeAggregationTestCase( coll, Object.assign( {pipeline: [{$project: {"_id": 0, result: {"$regexFind": constantParameters}}}]}, regexFindTest, ), ); executeAggregationTestCase( coll, Object.assign( {pipeline: [{$project: {"_id": 0, result: {"$regexFindAll": constantParameters}}}]}, regexFindAllTest, ), ); } finally { assert.commandWorked(db.adminCommand({"configureFailPoint": "disablePipelineOptimization", "mode": "off"})); } // Check parameters pulled from collection. inputDocument = Object.assign(inputDocument, parameters); const dynamicParameters = {input: "$text"}; if ("regex" in parameters) { dynamicParameters.regex = "$regex"; } if ("options" in parameters) { dynamicParameters.options = "$options"; } executeAggregationTestCase( coll, Object.assign({pipeline: [{$project: {"_id": 0, result: {"$regexMatch": dynamicParameters}}}]}, regexMatchTest), ); executeAggregationTestCase( coll, Object.assign({pipeline: [{$project: {"_id": 0, result: {"$regexFind": dynamicParameters}}}]}, regexFindTest), ); executeAggregationTestCase( coll, Object.assign( {pipeline: [{$project: {"_id": 0, result: {"$regexFindAll": dynamicParameters}}}]}, regexFindAllTest, ), ); } // Regex pattern must be string, BSON RegEx or null. assertFails({regex: 123}, 51105); // Regex flags must be string or null. assertFails({regex: ".*", options: 123}, 51106); // Options cannot be specified both in BSON RegEx and in options field. assertFails({regex: /.*/i, options: "s"}, 51107); // Regex pattern cannot contain null bytes. assertFails({regex: "[a-b]+\0[c-d]+"}, 51109); // Regex flags cannot contain null bytes. assertFails({regex: ".*", options: "i\0s"}, 51110); // If regex pattern is null, the query could either return null or report the 'cannot contain null // bytes' error. assertFails({regex: null, options: "i\0s"}, 51110, true /* allowNullResponse */); // Regex pattern must be a valid regular expression. assertFails({regex: "[a-"}, 51111); // Regex flags must be valid. assertFails({regex: ".*", options: "ish"}, 51108);