* Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
* Description: ...
*/
#include <string>
#include <vector>
#include "gtest/gtest.h"
#include "test/util/test_util.h"
#include "operator/projection/projection.h"
using namespace omniruntime::op;
using namespace omniruntime::vec;
using namespace omniruntime::expressions;
using namespace std;
namespace ParserTest {
void testCmpBinaryExpressions(std::vector<Expr *> result, omniruntime::expressions::Operator op, const int projectCount,
bool isBoolResult = false)
{
std::vector<DataTypeId> dataTypes = { OMNI_INT, OMNI_LONG, OMNI_DOUBLE, OMNI_DECIMAL128, OMNI_VARCHAR, OMNI_CHAR };
for (int i = 0; i < projectCount; i++) {
BinaryExpr *binaryExpr = static_cast<BinaryExpr *>(result.at(i));
if (isBoolResult) {
EXPECT_EQ(binaryExpr->GetReturnTypeId(), OMNI_BOOLEAN);
} else {
EXPECT_EQ(binaryExpr->GetReturnTypeId(), dataTypes[i]);
}
EXPECT_EQ(binaryExpr->op, op);
FieldExpr *left = static_cast<FieldExpr *>(binaryExpr->left);
EXPECT_EQ(left->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(left->colVal, i);
LiteralExpr *right = static_cast<LiteralExpr *>(binaryExpr->right);
EXPECT_EQ(right->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
if (i == 3) {
EXPECT_EQ(right->GetReturnTypeId(), OMNI_DECIMAL128);
} else if (i == 5) {
EXPECT_EQ(right->GetReturnTypeId(), OMNI_CHAR);
} else {
EXPECT_EQ(right->GetReturnTypeId(), dataTypes[i]);
}
if (i == 0)
EXPECT_EQ(right->intVal, i);
else if (i == 1)
EXPECT_EQ(right->longVal, i);
else if (i == 2)
EXPECT_EQ(right->doubleVal, i);
else if (i == 3)
ASSERT_EQ(stol(*right->stringVal), i);
else if (i == 4 || i == 5)
ASSERT_STREQ(right->stringVal->c_str(), "hello");
else {
}
if (i == 5) {
EXPECT_EQ(static_cast<VarcharDataType &>(*(right->dataType)).GetWidth(), 6);
}
}
}
void testArithmeticBinaryExpressions(std::vector<Expr *> result, omniruntime::expressions::Operator op,
const int projectCount)
{
std::vector<DataTypeId> dataTypes = { OMNI_INT, OMNI_LONG, OMNI_DOUBLE, OMNI_DECIMAL128 };
for (int i = 0; i < projectCount; i++) {
BinaryExpr *binaryExpr = static_cast<BinaryExpr *>(result.at(i));
EXPECT_EQ(binaryExpr->GetReturnTypeId(), dataTypes[i]);
EXPECT_EQ(binaryExpr->op, op);
FieldExpr *left = static_cast<FieldExpr *>(binaryExpr->left);
EXPECT_EQ(left->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(left->colVal, i);
LiteralExpr *right = static_cast<LiteralExpr *>(binaryExpr->right);
EXPECT_EQ(right->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
if (i == 3) {
EXPECT_EQ(right->GetReturnTypeId(), OMNI_DECIMAL128);
} else {
EXPECT_EQ(right->GetReturnTypeId(), dataTypes[i]);
}
if (i == 0)
EXPECT_EQ(right->intVal, i);
else if (i == 1)
EXPECT_EQ(right->longVal, i);
else if (i == 2)
EXPECT_EQ(right->doubleVal, i);
else if (i == 3)
EXPECT_EQ(stol(*right->stringVal), i);
else {
};
}
}
TEST(ParseTest, parseNotOperation)
{
int vecTypeCount = 1;
string expr = "$operator$NOT:4(#0)";
std::vector<DataTypePtr> vecOfTypes = { BooleanType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_BOOLEAN);
UnaryExpr *notExpr = static_cast<UnaryExpr *>(result);
EXPECT_EQ(notExpr->op, omniruntime::expressions::Operator::NOT);
FieldExpr *colExpr = static_cast<FieldExpr *>(notExpr->exp);
EXPECT_EQ(colExpr->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(colExpr->colVal, 0);
delete result;
}
TEST(ParseTest, parseAddOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$ADD:1(#0, 0:1)", "$operator$ADD:2(#1, 1:2)",
"$operator$ADD:3(#2, 2:3)", "$operator$ADD:7(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testArithmeticBinaryExpressions(result, omniruntime::expressions::Operator::ADD, projectCount);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseSubtractOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$SUBTRACT:1(#0, 0:1)", "$operator$SUBTRACT:2(#1, 1:2)",
"$operator$SUBTRACT:3(#2, 2:3)", "$operator$SUBTRACT:7(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testArithmeticBinaryExpressions(result, omniruntime::expressions::Operator::SUB, projectCount);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseMultiplyOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$MULTIPLY:1(#0, 0:1)", "$operator$MULTIPLY:2(#1, 1:2)",
"$operator$MULTIPLY:3(#2, 2:3)", "$operator$MULTIPLY:7(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testArithmeticBinaryExpressions(result, omniruntime::expressions::Operator::MUL, projectCount);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseDivideOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$DIVIDE:1(#0, 0:1)", "$operator$DIVIDE:2(#1, 1:2)",
"$operator$DIVIDE:3(#2, 2:3)", "$operator$DIVIDE:7(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testArithmeticBinaryExpressions(result, omniruntime::expressions::Operator::DIV, projectCount);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseModulusOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$MODULUS:1(#0, 0:1)", "$operator$MODULUS:2(#1, 1:2)",
"$operator$MODULUS:3(#2, 2:3)", "$operator$MODULUS:7(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testArithmeticBinaryExpressions(result, omniruntime::expressions::Operator::MOD, projectCount);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseLTOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$LESS_THAN:4(#0, 0:1)", "$operator$LESS_THAN:4(#1, 1:2)",
"$operator$LESS_THAN:4(#2, 2:3)", "$operator$LESS_THAN:4(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testCmpBinaryExpressions(result, omniruntime::expressions::Operator::LT, projectCount, true);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseLTEOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$LESS_THAN_OR_EQUAL:4(#0, 0:1)",
"$operator$LESS_THAN_OR_EQUAL:4(#1, 1:2)",
"$operator$LESS_THAN_OR_EQUAL:4(#2, 2:3)",
"$operator$LESS_THAN_OR_EQUAL:4(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testCmpBinaryExpressions(result, omniruntime::expressions::Operator::LTE, projectCount, true);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseGTOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$GREATER_THAN:4(#0, 0:1)", "$operator$GREATER_THAN:4(#1, 1:2)",
"$operator$GREATER_THAN:4(#2, 2:3)", "$operator$GREATER_THAN:4(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testCmpBinaryExpressions(result, omniruntime::expressions::Operator::GT, projectCount, true);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseGTEOperation)
{
const int projectCount = 4;
string exprs[projectCount] = {"$operator$GREATER_THAN_OR_EQUAL:4(#0, 0:1)",
"$operator$GREATER_THAN_OR_EQUAL:4(#1, 1:2)",
"$operator$GREATER_THAN_OR_EQUAL:4(#2, 2:3)",
"$operator$GREATER_THAN_OR_EQUAL:4(#3, 3:7)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(), Decimal128Type() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testCmpBinaryExpressions(result, omniruntime::expressions::Operator::GTE, projectCount, true);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseEQOperation)
{
const int projectCount = 6;
string exprs[projectCount] = {"$operator$EQUAL:4(#0, 0:1)", "$operator$EQUAL:4(#1, 1:2)",
"$operator$EQUAL:4(#2, 2:3)", "$operator$EQUAL:4(#3, 3:7)",
"$operator$EQUAL:4(#4, 'hello':15)", "$operator$EQUAL:4(#5, 'hello':16[6])"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(),
Decimal128Type(), VarcharType(), CharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testCmpBinaryExpressions(result, omniruntime::expressions::Operator::EQ, projectCount, true);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseNEQOperation)
{
const int projectCount = 6;
string exprs[projectCount] = {"$operator$NOT_EQUAL:4(#0, 0:1)", "$operator$NOT_EQUAL:4(#1, 1:2)",
"$operator$NOT_EQUAL:4(#2, 2:3)", "$operator$NOT_EQUAL:4(#3, 3:7)",
"$operator$NOT_EQUAL:4(#4, 'hello':15)",
"$operator$NOT_EQUAL:4(#5, 'hello':16[6])"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType(), DoubleType(),
Decimal128Type(), VarcharType(), CharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
testCmpBinaryExpressions(result, omniruntime::expressions::Operator::NEQ, projectCount, true);
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseLogicOperations)
{
const int projectCount = 2;
string exprs[projectCount] = {"$operator$AND:4(#0, true:4)", "$operator$OR:4(#1, false:4)"};
std::vector<DataTypePtr> vecOfTypes = { BooleanType(), BooleanType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, projectCount, inputTypes);
EXPECT_EQ(result.size(), projectCount);
for (int i = 0; i < projectCount; i++) {
BinaryExpr *logExpr = static_cast<BinaryExpr *>(result.at(i));
EXPECT_EQ(logExpr->GetReturnTypeId(), OMNI_BOOLEAN);
FieldExpr *logLeft = static_cast<FieldExpr *>(logExpr->left);
LiteralExpr *logRight = static_cast<LiteralExpr *>(logExpr->right);
EXPECT_EQ(logLeft->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(logLeft->colVal, i);
EXPECT_EQ(logRight->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
if (i == 0) {
EXPECT_TRUE(logRight->boolVal);
EXPECT_EQ(logExpr->op, omniruntime::expressions::Operator::AND);
}
if (i == 1) {
EXPECT_FALSE(logRight->boolVal);
EXPECT_EQ(logExpr->op, omniruntime::expressions::Operator::OR);
}
}
for (int i = 0; i < projectCount; i++) {
delete result.at(i);
}
}
TEST(ParseTest, parseBetweenOperation)
{
int vecTypeCount = 3;
string expr = "$operator$BETWEEN:4(#1, #0, #2)";
std::vector<DataTypePtr> vecOfTypes = { IntType(), DoubleType(), LongType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_BOOLEAN);
BetweenExpr *betweenExpr = static_cast<BetweenExpr *>(result);
FieldExpr *valueExpr = static_cast<FieldExpr *>(betweenExpr->value);
FieldExpr *lowerExpr = static_cast<FieldExpr *>(betweenExpr->lowerBound);
FieldExpr *upperExpr = static_cast<FieldExpr *>(betweenExpr->upperBound);
EXPECT_EQ(valueExpr->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(valueExpr->colVal, 1);
EXPECT_EQ(valueExpr->GetReturnTypeId(), OMNI_DOUBLE);
EXPECT_EQ(lowerExpr->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(lowerExpr->colVal, 0);
EXPECT_EQ(lowerExpr->GetReturnTypeId(), OMNI_INT);
EXPECT_EQ(upperExpr->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(upperExpr->colVal, 2);
EXPECT_EQ(upperExpr->GetReturnTypeId(), OMNI_LONG);
delete result;
}
TEST(ParseTest, parseInOperation)
{
int vecTypeCount = 3;
string expr = "$operator$IN:4(#1, #0, #2)";
std::vector<DataTypePtr> vecOfTypes = { IntType(), DoubleType(), LongType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_BOOLEAN);
InExpr *inExpr = static_cast<InExpr *>(result);
auto args = inExpr->arguments;
FieldExpr *arg0 = static_cast<FieldExpr *>(args[0]);
FieldExpr *arg1 = static_cast<FieldExpr *>(args[1]);
FieldExpr *arg2 = static_cast<FieldExpr *>(args[2]);
EXPECT_EQ(arg0->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(arg0->colVal, 1);
EXPECT_EQ(arg0->GetReturnTypeId(), OMNI_DOUBLE);
EXPECT_EQ(arg1->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(arg1->colVal, 0);
EXPECT_EQ(arg1->GetReturnTypeId(), OMNI_INT);
EXPECT_EQ(arg2->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(arg2->colVal, 2);
EXPECT_EQ(arg2->GetReturnTypeId(), OMNI_LONG);
delete result;
}
TEST(ParseTest, parseCoalesceOperation)
{
int vecTypeCount = 3;
string expr = "COALESCE:1(#1, #0)";
std::vector<DataTypePtr> vecOfTypes = { IntType(), IntType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_INT);
CoalesceExpr *coalesceExpr = static_cast<CoalesceExpr *>(result);
FieldExpr *value1 = static_cast<FieldExpr *>(coalesceExpr->value1);
FieldExpr *value2 = static_cast<FieldExpr *>(coalesceExpr->value2);
EXPECT_EQ(value1->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value1->colVal, 1);
EXPECT_EQ(value1->GetReturnTypeId(), OMNI_INT);
EXPECT_EQ(value2->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value2->colVal, 0);
EXPECT_EQ(value2->GetReturnTypeId(), OMNI_INT);
delete result;
}
TEST(ParseTest, parseIfOperation)
{
int vecTypeCount = 1;
string expr = "IF:15(true:4, #0, 'hello':15)";
std::vector<DataTypePtr> vecOfTypes = { VarcharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_VARCHAR);
IfExpr *ifExpr = static_cast<IfExpr *>(result);
LiteralExpr *condition = static_cast<LiteralExpr *>(ifExpr->condition);
FieldExpr *tExpr = static_cast<FieldExpr *>(ifExpr->trueExpr);
LiteralExpr *fExpr = static_cast<LiteralExpr *>(ifExpr->falseExpr);
EXPECT_EQ(condition->GetReturnTypeId(), OMNI_BOOLEAN);
EXPECT_EQ(condition->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(condition->boolVal, true);
EXPECT_EQ(tExpr->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(tExpr->colVal, 0);
EXPECT_EQ(tExpr->GetReturnTypeId(), OMNI_VARCHAR);
EXPECT_EQ(fExpr->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_STREQ(fExpr->stringVal->c_str(), "hello");
delete result;
}
TEST(ParseTest, parseIsNullOperation)
{
int vecTypeCount = 1;
string expr = "IS_NULL:4(#0)";
std::vector<DataTypePtr> vecOfTypes = { CharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_BOOLEAN);
IsNullExpr *isNullExpr = static_cast<IsNullExpr *>(result);
FieldExpr *value = static_cast<FieldExpr *>(isNullExpr->value);
EXPECT_EQ(value->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value->colVal, 0);
EXPECT_EQ(value->GetReturnTypeId(), OMNI_CHAR);
delete result;
}
TEST(ParseTest, parseIsNotNullOperation)
{
int vecTypeCount = 1;
string expr = "IS_NOT_NULL:4(#0)";
std::vector<DataTypePtr> vecOfTypes = { CharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_BOOLEAN);
UnaryExpr *unaryExpr = static_cast<UnaryExpr *>(result);
EXPECT_EQ(unaryExpr->op, omniruntime::expressions::Operator::NOT);
IsNullExpr *isNullExpr = static_cast<IsNullExpr *>(unaryExpr->exp);
FieldExpr *value = static_cast<FieldExpr *>(isNullExpr->value);
EXPECT_EQ(value->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value->colVal, 0);
EXPECT_EQ(value->GetReturnTypeId(), OMNI_CHAR);
delete result;
}
TEST(ParseTest, parseCastOperation)
{
int vecTypeCount = 1;
string expr = "CAST:2(#0)";
std::vector<DataTypePtr> vecOfTypes = { IntType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_LONG);
FuncExpr *castExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(castExpr->funcName.c_str(), "CAST");
auto args = castExpr->arguments;
FieldExpr *arg0 = static_cast<FieldExpr *>(args[0]);
EXPECT_EQ(arg0->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(arg0->colVal, 0);
EXPECT_EQ(arg0->GetReturnTypeId(), OMNI_INT);
delete result;
}
TEST(ParseTest, parseAbsOperation)
{
int vecTypeCount = 1;
string expr = "abs:3(#0)";
std::vector<DataTypePtr> vecOfTypes = { DoubleType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_DOUBLE);
FuncExpr *absExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(absExpr->funcName.c_str(), "abs");
auto args = absExpr->arguments;
FieldExpr *arg0 = static_cast<FieldExpr *>(args[0]);
EXPECT_EQ(arg0->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(arg0->colVal, 0);
EXPECT_EQ(arg0->GetReturnTypeId(), OMNI_DOUBLE);
delete result;
}
TEST(ParseTest, parseSubstrOperation)
{
int vecTypeCount = 1;
string expr = "substr:15(#0, 1:1, 6:1)";
std::vector<DataTypePtr> vecOfTypes = { VarcharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_VARCHAR);
FuncExpr *absExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(absExpr->funcName.c_str(), "substr");
auto args = absExpr->arguments;
FieldExpr *value = static_cast<FieldExpr *>(args[0]);
LiteralExpr *index = static_cast<LiteralExpr *>(args[1]);
LiteralExpr *length = static_cast<LiteralExpr *>(args[2]);
EXPECT_EQ(value->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value->colVal, 0);
EXPECT_EQ(value->GetReturnTypeId(), OMNI_VARCHAR);
EXPECT_EQ(index->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(index->intVal, 1);
EXPECT_EQ(index->GetReturnTypeId(), OMNI_INT);
EXPECT_EQ(length->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(length->intVal, 6);
EXPECT_EQ(length->GetReturnTypeId(), OMNI_INT);
delete result;
}
TEST(ParseTest, parseConcatOperation)
{
int vecTypeCount = 1;
string expr = "concat:15(#0, 'hello':15)";
std::vector<DataTypePtr> vecOfTypes = { VarcharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_VARCHAR);
FuncExpr *absExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(absExpr->funcName.c_str(), "concat");
auto args = absExpr->arguments;
FieldExpr *value1 = static_cast<FieldExpr *>(args[0]);
LiteralExpr *value2 = static_cast<LiteralExpr *>(args[1]);
EXPECT_EQ(value1->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value1->colVal, 0);
EXPECT_EQ(value1->GetReturnTypeId(), OMNI_VARCHAR);
EXPECT_EQ(value2->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_STREQ(value2->stringVal->c_str(), "hello");
EXPECT_EQ(value2->GetReturnTypeId(), OMNI_VARCHAR);
delete result;
}
TEST(ParseTest, parseLikeOperation)
{
int vecTypeCount = 1;
string expr = "LIKE:4(#0, '%hello':15)";
std::vector<DataTypePtr> vecOfTypes = { VarcharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_BOOLEAN);
FuncExpr *absExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(absExpr->funcName.c_str(), "LIKE");
auto args = absExpr->arguments;
FieldExpr *value = static_cast<FieldExpr *>(args[0]);
LiteralExpr *index = static_cast<LiteralExpr *>(args[1]);
EXPECT_EQ(value->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value->colVal, 0);
EXPECT_EQ(value->GetReturnTypeId(), OMNI_VARCHAR);
EXPECT_EQ(index->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_STREQ(index->stringVal->c_str(), ".*hello");
EXPECT_EQ(index->GetReturnTypeId(), OMNI_VARCHAR);
delete result;
}
TEST(ParseTest, parseMM3HashOperation)
{
int vecTypeCount = 1;
string expr = "mm3hash:1(#0, 2:1)";
std::vector<DataTypePtr> vecOfTypes = { VarcharType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_INT);
FuncExpr *absExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(absExpr->funcName.c_str(), "mm3hash");
auto args = absExpr->arguments;
FieldExpr *value = static_cast<FieldExpr *>(args[0]);
LiteralExpr *index = static_cast<LiteralExpr *>(args[1]);
EXPECT_EQ(value->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value->colVal, 0);
EXPECT_EQ(value->GetReturnTypeId(), OMNI_VARCHAR);
EXPECT_EQ(index->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(index->intVal, 2);
EXPECT_EQ(index->GetReturnTypeId(), OMNI_INT);
delete result;
}
TEST(ParseTest, parseCombineHashOperation)
{
int vecTypeCount = 1;
string expr = "combine_hash:2(#0, 2:2)";
std::vector<DataTypePtr> vecOfTypes = { LongType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_LONG);
FuncExpr *absExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(absExpr->funcName.c_str(), "combine_hash");
auto args = absExpr->arguments;
FieldExpr *value = static_cast<FieldExpr *>(args[0]);
LiteralExpr *index = static_cast<LiteralExpr *>(args[1]);
EXPECT_EQ(value->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value->colVal, 0);
EXPECT_EQ(value->GetReturnTypeId(), OMNI_LONG);
EXPECT_EQ(index->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(index->longVal, 2);
EXPECT_EQ(index->GetReturnTypeId(), OMNI_LONG);
delete result;
}
TEST(ParseTest, parsePmodOperation)
{
int vecTypeCount = 1;
string expr = "pmod:1(#0, 5:1)";
std::vector<DataTypePtr> vecOfTypes = { IntType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result->GetReturnTypeId(), OMNI_INT);
FuncExpr *absExpr = static_cast<FuncExpr *>(result);
EXPECT_STREQ(absExpr->funcName.c_str(), "pmod");
auto args = absExpr->arguments;
FieldExpr *value = static_cast<FieldExpr *>(args[0]);
LiteralExpr *index = static_cast<LiteralExpr *>(args[1]);
EXPECT_EQ(value->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(value->colVal, 0);
EXPECT_EQ(value->GetReturnTypeId(), OMNI_INT);
EXPECT_EQ(index->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(index->intVal, 5);
EXPECT_EQ(index->GetReturnTypeId(), OMNI_INT);
delete result;
}
TEST(ParseTest, parseNullExprOperation)
{
int vecTypeCount = 0;
string expr = "abs:1(2)";
std::vector<DataTypePtr> vecOfTypes = {};
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
EXPECT_EQ(result, nullptr);
delete result;
}
TEST(ParseTest, parseNullStringOperation)
{
int vecTypeCount = 0;
string expr = "null:0";
std::vector<DataTypePtr> vecOfTypes = {};
DataTypes inputTypes(vecOfTypes);
Parser parser;
Expr *result = parser.ParseRowExpression(expr, inputTypes, vecTypeCount);
FieldExpr *nullExpr = static_cast<FieldExpr *>(result);
EXPECT_TRUE(nullExpr->isNull);
delete result;
}
TEST(ParseTest, ParseExpressions)
{
string exprs[2] = {"$operator$SUBTRACT:1(#0, 10:1)", "$operator$ADD:2(#1, 1:2)"};
std::vector<DataTypePtr> vecOfTypes = { IntType(), LongType() };
DataTypes inputTypes(vecOfTypes);
Parser parser;
std::vector<Expr *> result = parser.ParseExpressions(exprs, 2, inputTypes);
EXPECT_EQ(result.at(0)->GetType(), omniruntime::expressions::ExprType::BINARY_E);
BinaryExpr *subtractExpr = static_cast<BinaryExpr *>(result.at(0));
EXPECT_EQ(subtractExpr->op, omniruntime::expressions::Operator::SUB);
FieldExpr *subtractLeft = static_cast<FieldExpr *>(subtractExpr->left);
LiteralExpr *subtractRight = static_cast<LiteralExpr *>(subtractExpr->right);
EXPECT_EQ(subtractLeft->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(subtractLeft->colVal, 0);
EXPECT_EQ(subtractRight->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(subtractRight->intVal, 10);
EXPECT_EQ(result.at(1)->GetType(), omniruntime::expressions::ExprType::BINARY_E);
BinaryExpr *addExpr = static_cast<BinaryExpr *>(result.at(1));
EXPECT_EQ(addExpr->op, omniruntime::expressions::Operator::ADD);
FieldExpr *addLeft = static_cast<FieldExpr *>(addExpr->left);
LiteralExpr *addRight = static_cast<LiteralExpr *>(addExpr->right);
EXPECT_EQ(addLeft->GetType(), omniruntime::expressions::ExprType::FIELD_E);
EXPECT_EQ(addLeft->colVal, 1);
EXPECT_EQ(addRight->GetType(), omniruntime::expressions::ExprType::LITERAL_E);
EXPECT_EQ(addRight->longVal, 1);
for (auto i = 0; i < 2; i++) {
delete result.at(i);
}
}
}