Details
-
Improvement
-
Resolution: Done
-
Major - P3
-
None
-
None
Description
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 } ) );
|
Attachments
Issue Links
- is related to
-
SERVER-6193 string constants prevent optimization of non string sensitive operators
-
- Closed
-