-
Type: Improvement
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: Aggregation Framework
-
None
Observed behavior: A $and/$or expression with a single constant is not optimized as well as a similar expression with two constants.
Expected behavior: An expression with one constant should be optimized the same way as a similar expression with two constants.
ExpressionAnd::optimize() and ExpressionOr::optimize() expect that any constant will appear in the last operand, but ExpressionNary::optimize() does not guarantee placement of a constant in the last operand if there was only one constant to begin with.
/* If there's no more than one constant, then we can't do any constant folding, so don't bother going any further. */ if (constCount <= 1) return intrusive_ptr<Expression>(this);
Test:
c = db.c; c.drop(); c.save( { x:true } ); // This expression is left as is. printjson( c.runCommand( 'aggregate', { pipeline:[ { $project:{ a:{ $and:[ 0, '$x' ] } }\ } ], explain:true } ) ); // This expression is optimized to 'false', eliminating the need to read field 'x', due to the existence of two constant operands. printjson( c.runCommand( 'aggregate', { pipeline:[ { $project:{ a:{ $and:[ 0, 1, '$x' ] \ } } } ], explain:true } ) ); // This expression is left as is. printjson( c.runCommand( 'aggregate', { pipeline:[ { $project:{ a:{ $or:[ 1, '$x' ] } } \ } ], explain:true } ) ); // This expression is optimized to 'true', eliminating the need to read field 'x', due to the existence of two constant operands. printjson( c.runCommand( 'aggregate', { pipeline:[ { $project:{ a:{ $or:[ 1, 0, '$x' ] }\ } } ], explain:true } ) );
- is related to
-
SERVER-6193 string constants prevent optimization of non string sensitive operators
- Closed