浏览代码

EAGLESIX-812: fixed DepsReturn and got existing pipelineD test cases working

Phil Murray 11 年之前
父节点
当前提交
1ee892580a

+ 8 - 7
lib/pipeline/PipelineD.js

@@ -49,11 +49,12 @@ klass.prepareCursorSource = function prepareCursorSource(pipeline, expCtx){
 
 	// Look for an initial match. This works whether we got an initial query or not.
 	// If not, it results in a "{}" query, which will be what we want in that case.
-	var queryObj = pipeline.getInitialQuery();
+	var queryObj = pipeline.getInitialQuery(),
+		match;
 	if (queryObj && queryObj instanceof Object && Object.keys(queryObj).length) {
 		// This will get built in to the Cursor we'll create, so
 		// remove the match from the pipeline
-		// NOTE: SKIPPED
+		match = sources.shift();
 	}
 
 	// Find the set of fields in the source documents depended on by this pipeline.
@@ -76,17 +77,17 @@ klass.prepareCursorSource = function prepareCursorSource(pipeline, expCtx){
 		sortInRunner = false;
 	if (sources.length) {
 		sortStage = sources[0] instanceof SortDocumentSource ? sources[0] : undefined;
-		
-		//need to check the next source since we are not deleting the initial match in munge
-		if (!sortStage && sources[0] instanceof MatchDocumentSource){
-			sortStage = sources[1] instanceof SortDocumentSource ? sources[1] : undefined;
-		}
 		if (sortStage) {
 			// build the sort key
 			sortObj = sortStage.serializeSortKey(/*explain*/false);
 			sortInRunner = true;
 		}
 	}
+	
+	//munge deviation: the runner is (usually) not actually handling the initial query, so we need to add it back to the pipeline
+	if (match){
+		sources.unshift(match);
+	}
 
 	// Create the Runner.
 	// NOTE: the logic here is simplified for munge

+ 5 - 5
lib/pipeline/documentSources/DocumentSource.js

@@ -152,11 +152,11 @@ proto.optimize = function optimize() {
 };
 
 klass.GetDepsReturn = {
-	NOT_SUPPORTED: "NOT_SUPPORTED", // This means the set should be ignored
-	SEE_NEXT: "SEE_NEXT", // Add the next Source's deps to the set
-	EXHAUSTIVE_FIELDS:"EXHAUSTIVE_FIELDS", // Later stages won"t need more fields from input
-	EXHAUSTIVE_META: "EXHAUSTIVE_META", // Later stages won"t need more metadata from input
-	EXHAUSTIVE_ALL: "EXHAUSTIVE_ALL" // Later stages won"t need either NOTE: This is an | of FIELDS and META in mongo C++
+	NOT_SUPPORTED: 0x0, // The full object and all metadata may be required
+	SEE_NEXT: 0x1, // Later stages could need either fields or metadata
+	EXHAUSTIVE_FIELDS: 0x2, // Later stages won't need more fields from input
+	EXHAUSTIVE_META: 0x4, // Later stages won't need more metadata from input
+	EXHAUSTIVE_ALL: 0x6 // Later stages won't need either
 };
 
 /**

+ 1 - 1
lib/pipeline/documentSources/GroupDocumentSource.js

@@ -369,7 +369,7 @@ proto.getDependencies = function getDependencies(deps) {
 		self.expressions[i].addDependencies(deps);
 	});
 
-	return DocumentSource.GetDepsReturn.EXHAUSTIVE;
+	return DocumentSource.GetDepsReturn.EXHAUSTIVE_ALL;
 };
 
 /**

+ 1 - 1
lib/pipeline/documentSources/OutDocumentSource.js

@@ -55,5 +55,5 @@ klass.needsMongodDocumentSource = true;
 
 proto.getDependencies = function(deps) {
 	deps.needWholeDocument = true;
-	return DocumentSource.GetDepsReturn.EXHAUSTIVE;
+	return DocumentSource.GetDepsReturn.EXHAUSTIVE_ALL;
 };

+ 1 - 1
lib/pipeline/documentSources/ProjectDocumentSource.js

@@ -124,7 +124,7 @@ klass.createFromJson = function(elem, expCtx) {
 proto.getDependencies = function getDependencies(deps) {
 	var path = [];
 	this.OE.addDependencies(deps, path);
-	return base.GetDepsReturn.EXHAUSTIVE;
+	return base.GetDepsReturn.EXHAUSTIVE_FIELDS;
 };
 
 /**

+ 6 - 7
test/lib/pipeline/PipelineD.js

@@ -21,8 +21,8 @@ module.exports = {
 			"should get projection from all sources": function () {
 				var p = Pipeline.parseCommand({pipeline:[{$project:{a:"$x"}}], aggregate:[]}),
 					cs = PipelineD.prepareCursorSource(p, {ns:[1,2,3,4,5]});
-				assert.deepEqual(p.sources[0]._projection, {"x":1});
-				assert.deepEqual(p.sources[0]._dependencies, {}); //TODO: what goes here???
+				assert.deepEqual(p.sources[0]._projection, {x:1, _id:1});
+				assert.deepEqual(p.sources[0]._dependencies, {_fields:{_id:true, x:true}});
 			},
 
 			"should get projection's deps": function () {
@@ -46,10 +46,9 @@ module.exports = {
 				};
 				var p = Pipeline.parseCommand(cmdObj),
 					cs = PipelineD.prepareCursorSource(p, {ns:[1,2,3,4,5]});
-				assert.equal(JSON.stringify(p.sources[0]._projection), JSON.stringify({'a.b.c': 1, d: 1, 'e.f.g': 1, _id: 1}));
-				assert.deepEqual(p.sources[0]._dependencies, {}); //TODO: what goes here???
+				assert.deepEqual(p.sources[0]._projection, {'a.b.c': 1, d: 1, 'e.f.g': 1, _id: 1});
+				assert.deepEqual(p.sources[0]._dependencies, {"_fields":{"_id":true,"a":{"b":{"c":true}},"d":true,"e":{"f":{"g":true}}}});
 			},
-
 			"should get group's deps": function(){
 				var cmdObj = {
 					aggregate: [],
@@ -73,8 +72,8 @@ module.exports = {
 				};
 				var p = Pipeline.parseCommand(cmdObj),
 					cs = PipelineD.prepareCursorSource(p, {ns:[1,2,3,4,5]});
-				assert.equal(JSON.stringify(p.sources[0]._projection), JSON.stringify({ _id: 0, a: 1, b: 1, 'x.y.z': 1 }));
-				assert.deepEqual(p.sources[0]._dependencies, {}); //TODO: what goes here???
+				assert.equal(JSON.stringify(p.sources[0]._projection), JSON.stringify({ a: 1, b: 1, 'x.y.z': 1, _id: 0 }));
+				assert.deepEqual(p.sources[0]._dependencies, {"_fields":{"a":true,"b":true,"x":{"y":{"z":true}}}});
 			},
 			"should set the queryObj on the Cursor": function(){},
 			"should set the sort on the Cursor": function(){},

+ 19 - 5
test/lib/pipeline/documentSources/CursorDocumentSource.js

@@ -5,6 +5,8 @@ var assert = require("assert"),
 	CursorDocumentSource = require("../../../../lib/pipeline/documentSources/CursorDocumentSource"),
 	LimitDocumentSource = require("../../../../lib/pipeline/documentSources/LimitDocumentSource"),
 	SkipDocumentSource = require("../../../../lib/pipeline/documentSources/SkipDocumentSource"),
+	ProjectDocumentSource = require("../../../../lib/pipeline/documentSources/ProjectDocumentSource"),
+	DepsTracker = require("../../../../lib/pipeline/DepsTracker"),
 	ArrayRunner = require("../../../../lib/query/ArrayRunner");
 
 var getCursorDocumentSource = function(values) {
@@ -136,11 +138,23 @@ module.exports = {
 
 		"#setProjection": {
 
-			"should set a projection": function() {
-				var cds = getCursorDocumentSource();
-				cds.setProjection({a:1}, {a:true});
-				assert.deepEqual(cds._projection, {a:1});
-				assert.deepEqual(cds._dependencies, {a:true});
+			"should set a projection": function(next) {
+				var cds = getCursorDocumentSource([{a:1, b:2},{a:2, b:3}]),
+					deps = new DepsTracker(),
+					project = ProjectDocumentSource.createFromJson({"a":1});
+				project.getDependencies(deps);
+				cds.setProjection(deps.toProjection(), deps.toParsedDeps());
+				
+				async.series([
+						cds.getNext.bind(cds),
+						cds.getNext.bind(cds),
+						cds.getNext.bind(cds)
+					],
+					function(err,res) {
+						assert.deepEqual([{a:1},{a:2},null], res);
+						next();
+					}
+				);
 			}
 
 		}

+ 1 - 1
test/lib/pipeline/documentSources/ProjectDocumentSource.js

@@ -261,7 +261,7 @@ module.exports = {
 			};
 			var pds = createProject(input);
 			var dependencies = new DepsTracker();
-			assert.equal(DocumentSource.GetDepsReturn.EXHAUSTIVE, pds.getDependencies(dependencies));
+			assert.equal(DocumentSource.GetDepsReturn.EXHAUSTIVE_FIELDS, pds.getDependencies(dependencies));
 			assert.equal(5, Object.keys(dependencies.fields).length);
 			assert.ok(dependencies.fields._id);
 			assert.ok(dependencies.fields.a);