8000 make unary minus and plus being executed in native C++ · lethalbrains/arangodb@d2c1d75 · GitHub
[go: up one dir, main page]

Skip to content

Commit d2c1d75

Browse files
committed
make unary minus and plus being executed in native C++
1 parent 2780f1e commit d2c1d75

File tree

4 files changed

+101
-3
lines changed

4 files changed

+101
-3
lines changed

arangod/Aql/AqlValue.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,21 @@ struct AqlValue final {
132132
memcpy(_data.internal, slice.begin(), static_cast<size_t>(slice.byteSize()));
133133
setType(AqlValueType::VPACK_INLINE);
134134
}
135+
136+
// construct from a double value
137+
explicit AqlValue(double value) {
138+
_data.internal[0] = 0x1b;
139+
uint64_t dv;
140+
memcpy(&dv, &value, sizeof(double));
141+
VPackValueLength vSize = sizeof(double);
142+
int i = 1;
143+
for (uint64_t x = dv; vSize > 0; vSize--) {
144+
_data.internal[i] = x & 0xff;
145+
x >>= 8;
146+
++i;
147+
}
148+
setType(AqlValueType::VPACK_INLINE);
149+
}
135150

136151
// construct from char* and length, copying the string
137152
AqlValue(char const* value, size_t length) {

arangod/Aql/AstNode.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1719,7 +1719,8 @@ bool AstNode::isSimple() const {
17191719
}
17201720

17211721
if (type == NODE_TYPE_OBJECT_ELEMENT || type == NODE_TYPE_ATTRIBUTE_ACCESS ||
1722-
type == NODE_TYPE_OPERATOR_UNARY_NOT) {
1722+
type == NODE_TYPE_OPERATOR_UNARY_NOT || type == NODE_TYPE_OPERATOR_UNARY_PLUS ||
1723+
type == NODE_TYPE_OPERATOR_UNARY_MINUS) {
17231724
TRI_ASSERT(numMembers() == 1);
17241725

17251726
if (!getMember(0)->isSimple()) {

arangod/Aql/Expression.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,12 @@ AqlValue Expression::executeSimpleExpression(
444444
regs, mustDestroy);
445445
case NODE_TYPE_OPERATOR_UNARY_NOT:
446446
return executeSimpleExpressionNot(node, trx, argv, startPos, vars, regs, mustDestroy);
447+
448+
case NODE_TYPE_OPERATOR_UNARY_PLUS:
449+
return executeSimpleExpressionPlus(node, trx, argv, startPos, vars, regs, mustDestroy);
450+
451+
case NODE_TYPE_OPERATOR_UNARY_MINUS:
452+
return executeSimpleExpressionMinus(node, trx, argv, startPos, vars, regs, mustDestroy);
447453

448454
case NODE_TYPE_OPERATOR_BINARY_AND:
449455
case NODE_TYPE_OPERATOR_BINARY_OR:
@@ -947,6 +953,70 @@ AqlValue Expression::executeSimpleExpressionNot(
947953
return AqlValue(!operandIsTrue);
948954
}
949955

956+
/// @brief execute an expression of type SIMPLE with +
957+
AqlValue Expression::executeSimpleExpressionPlus(
958+
AstNode const* node, arangodb::AqlTransaction* trx,
959+
AqlItemBlock const* argv, size_t startPos,
960+
std::vector<Variable const*> const& vars,
961+
std::vector<RegisterId> const& regs, bool& mustDestroy) {
962+
963+
mustDestroy = false;
964+
AqlValue operand =
965+
executeSimpleExpression(node->getMember(0), trx, argv,
966+
startPos, vars, regs, mustDestroy, false);
967+
968+
AqlValueGuard guard(operand, mustDestroy);
969+
970+
bool failed = false;
971+
double value = operand.toDouble(trx, failed);
972+
973+
if (failed) {
974+
value = 0.0;
975+
}
976+
977+
double result = +value;
978+
if (std::isnan(result) || !std::isfinite(result) || result == HUGE_VAL || result == -HUGE_VAL) {
979+
return AqlValue(VelocyPackHelper::NullValue());
980+
}
981+
982+
TransactionBuilderLeaser builder(trx);
983+
mustDestroy = true; // builder = dynamic data
984+
builder->add(VPackValue(result));
985+
return AqlValue(*builder.get());
986+
}
987+
988+
/// @brief execute an expression of type SIMPLE with -
989+
AqlValue Expression::executeSimpleExpressionMinus(
990+
AstNode const* node, arangodb::AqlTransaction* trx,
991+
AqlItemBlock const* argv, size_t startPos,
992+
std::vector<Variable const*> const& vars,
993+
std::vector<RegisterId> const& regs, bool& mustDestroy) {
994+
995+
mustDestroy = false;
996+
AqlValue operand =
997+
executeSimpleExpression(node->getMember(0), trx, argv,
998+
startPos, vars, regs, mustDestroy, false);
999+
1000+
AqlValueGuard guard(operand, mustDestroy);
1001+
1002+
bool failed = false;
1003+
double value = operand.toDouble(trx, failed);
1004+
1005+
if (failed) {
1006+
value = 0.0;
1007+
}
1008+
1009+
double result = -value;
1010+
if (std::isnan(result) || !std::isfinite(result) || result == HUGE_VAL || result == -HUGE_VAL) {
1011+
return AqlValue(VelocyPackHelper::NullValue());
1012+
}
1013+
1014+
TransactionBuilderLeaser builder(trx);
1015+
mustDestroy = true; // builder = dynamic data
1016+
builder->add(VPackValue(result));
1017+
return AqlValue(*builder.get());
1018+
}
1019+
9501020
/// @brief execute an expression of type SIMPLE with AND or OR
9511021
AqlValue Expression::executeSimpleExpressionAndOr(
9521022
AstNode const* node, arangodb::AqlTransaction* trx,

arangod/Aql/Expression.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
#include <velocypack/Builder.h>
3535
#include <velocypack/Slice.h>
3636

37-
struct TRI_json_t;
38-
3937
namespace arangodb {
4038
class AqlTransaction;
4139

@@ -293,6 +291,20 @@ class Expression {
293291
std::vector<Variable const*> const&,
294292
std::vector<RegisterId> const&,
295293
bool& mustDestroy);
294+
295+
/// @brief execute an expression of type SIMPLE with +
296+
AqlValue executeSimpleExpressionPlus(AstNode const*, arangodb::AqlTransaction*,
297+
AqlItemBlock const*, size_t,
298+
std::vector<Variable const*> const&,
299+
std::vector<RegisterId> const&,
300+
bool& mustDestroy);
301+
302+
/// @brief execute an expression of type SIMPLE with -
303+
AqlValue executeSimpleExpressionMinus(AstNode const*, arangodb::AqlTransaction*,
304+
AqlItemBlock const*, size_t,
305+
std::vector<Variable const*> const&,
306+
std::vector<RegisterId> const&,
307+
bool& mustDestroy);
296308

297309
/// @brief execute an expression of type SIMPLE with AND or OR
298310
AqlValue executeSimpleExpressionAndOr(AstNode const*,

0 commit comments

Comments
 (0)
0