mirror of https://gitee.com/bigwinds/arangodb
defer evaluation of logical operators
This commit is contained in:
parent
56054d3e66
commit
8277e7582c
|
@ -1939,28 +1939,30 @@ static void ProcessUnaryPlus (TRI_aql_codegen_js_t* const generator,
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate code for binary and (a && b)
|
||||
/// this passes two functions to the operator for lazy evaluation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void ProcessBinaryAnd (TRI_aql_codegen_js_t* const generator,
|
||||
const TRI_aql_node_t* const node) {
|
||||
ScopeOutput(generator, "aql.LOGICAL_AND(");
|
||||
ScopeOutput(generator, "aql.LOGICAL_AND_FN(function () {\nreturn ");
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
|
||||
ScopeOutput(generator, ", ");
|
||||
ScopeOutput(generator, "}, function () {\nreturn ");
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 1));
|
||||
ScopeOutput(generator, ")");
|
||||
ScopeOutput(generator, "})");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generate code for binary or (a || b)
|
||||
/// this passes two functions to the operator for lazy evaluation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void ProcessBinaryOr (TRI_aql_codegen_js_t* const generator,
|
||||
const TRI_aql_node_t* const node) {
|
||||
ScopeOutput(generator, "aql.LOGICAL_OR(");
|
||||
ScopeOutput(generator, "aql.LOGICAL_OR_FN(function () {\nreturn ");
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
|
||||
ScopeOutput(generator, ", ");
|
||||
ScopeOutput(generator, "}, function () {\nreturn ");
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 1));
|
||||
ScopeOutput(generator, ")");
|
||||
ScopeOutput(generator, "})");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -2125,13 +2127,13 @@ static void ProcessBinaryIn (TRI_aql_codegen_js_t* const generator,
|
|||
|
||||
static void ProcessTernary (TRI_aql_codegen_js_t* const generator,
|
||||
const TRI_aql_node_t* const node) {
|
||||
ScopeOutput(generator, "aql.TERNARY_OPERATOR(");
|
||||
ScopeOutput(generator, "aql.TERNARY_OPERATOR_FN(");
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 0));
|
||||
ScopeOutput(generator, ", ");
|
||||
ScopeOutput(generator, ", function () { \nreturn ");
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 1));
|
||||
ScopeOutput(generator, ", ");
|
||||
ScopeOutput(generator, "}, function () {\nreturn ");
|
||||
ProcessNode(generator, TRI_AQL_NODE_MEMBER(node, 2));
|
||||
ScopeOutput(generator, ")");
|
||||
ScopeOutput(generator, "})");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1064,6 +1064,26 @@ function TERNARY_OPERATOR (condition, truePart, falsePart) {
|
|||
return falsePart;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute ternary operator
|
||||
///
|
||||
/// the condition operand must be a boolean value, returns either the truepart
|
||||
/// or the falsepart
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function TERNARY_OPERATOR_FN (condition, truePart, falsePart) {
|
||||
"use strict";
|
||||
|
||||
if (TYPEWEIGHT(condition) !== TYPEWEIGHT_BOOL) {
|
||||
THROW(INTERNAL.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);
|
||||
}
|
||||
|
||||
if (condition) {
|
||||
return truePart();
|
||||
}
|
||||
return falsePart();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief perform logical and
|
||||
///
|
||||
|
@ -1108,6 +1128,60 @@ function LOGICAL_OR (lhs, rhs) {
|
|||
return rhs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief perform logical and
|
||||
///
|
||||
/// both operands must be boolean values, returns a boolean, uses short-circuit
|
||||
/// evaluation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function LOGICAL_AND_FN (lhs, rhs) {
|
||||
"use strict";
|
||||
|
||||
var l = lhs();
|
||||
if (TYPEWEIGHT(l) !== TYPEWEIGHT_BOOL) {
|
||||
THROW(INTERNAL.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);
|
||||
}
|
||||
|
||||
if (! l) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var r = rhs();
|
||||
if (TYPEWEIGHT(r) !== TYPEWEIGHT_BOOL) {
|
||||
THROW(INTERNAL.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief perform logical or
|
||||
///
|
||||
/// both operands must be boolean values, returns a boolean, uses short-circuit
|
||||
/// evaluation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function LOGICAL_OR_FN (lhs, rhs) {
|
||||
"use strict";
|
||||
|
||||
var l = lhs();
|
||||
if (TYPEWEIGHT(l) !== TYPEWEIGHT_BOOL) {
|
||||
THROW(INTERNAL.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);
|
||||
}
|
||||
|
||||
if (l) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var r = rhs();
|
||||
if (TYPEWEIGHT(r) !== TYPEWEIGHT_BOOL) {
|
||||
THROW(INTERNAL.errors.ERROR_QUERY_INVALID_LOGICAL_VALUE);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief perform logical negation
|
||||
///
|
||||
|
@ -4002,8 +4076,11 @@ exports.GET_DOCUMENTS_SKIPLIST = GET_DOCUMENTS_SKIPLIST;
|
|||
exports.GET_DOCUMENTS_SKIPLIST_LIST = GET_DOCUMENTS_SKIPLIST_LIST;
|
||||
exports.COLLECTIONS = COLLECTIONS;
|
||||
exports.TERNARY_OPERATOR = TERNARY_OPERATOR;
|
||||
exports.TERNARY_OPERATOR_FN = TERNARY_OPERATOR_FN;
|
||||
exports.LOGICAL_AND = LOGICAL_AND;
|
||||
exports.LOGICAL_OR = LOGICAL_OR;
|
||||
exports.LOGICAL_AND_FN = LOGICAL_AND_FN;
|
||||
exports.LOGICAL_OR_FN = LOGICAL_OR_FN;
|
||||
exports.LOGICAL_NOT = LOGICAL_NOT;
|
||||
exports.RELATIONAL_EQUAL = RELATIONAL_EQUAL;
|
||||
exports.RELATIONAL_UNEQUAL = RELATIONAL_UNEQUAL;
|
||||
|
|
|
@ -238,18 +238,35 @@ function ahuacatlLogicalTestSuite () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testBinaryAndShortCircuit1 : function () {
|
||||
// TODO: FIXME
|
||||
// var expected = [ false ];
|
||||
// var actual = getQueryResults("RETURN false && FAIL('this will fail')");
|
||||
//assertEqual(expected, actual);
|
||||
var expected = [ false ];
|
||||
var actual = getQueryResults("RETURN false && FAIL('this will fail')");
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test binary and, short circuit evaluation
|
||||
/// @brief test binary or, short circuit evaluation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testBinaryAndShortCircuit2 : function () {
|
||||
assertException(function() { getQueryResults("RETURN false && FAIL('this will fail')"); });
|
||||
assertException(function() { getQueryResults("RETURN true && FAIL('this will fail')"); });
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test binary or, short circuit evaluation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testBinaryOrShortCircuit1 : function () {
|
||||
var expected = [ true ];
|
||||
var actual = getQueryResults("RETURN true || FAIL('this will fail')");
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test binary or, short circuit evaluation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testBinaryOrShortCircuit2 : function () {
|
||||
assertException(function() { getQueryResults("RETURN false || FAIL('this will fail')"); });
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue