/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #include #include #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wwrite-strings" #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wsign-compare" #pragma GCC diagnostic ignored "-Wformat" #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" #pragma GCC diagnostic ignored "-Wpointer-arith" #include "os.h" #include "taos.h" #include "tdef.h" #include "tvariant.h" #include "tep.h" #include "stub.h" #include "addr_any.h" #include "scalar.h" #include "nodes.h" namespace { int64_t scltLeftV = 21, scltRightV = 10; double scltLeftVd = 21.0, scltRightVd = 10.0; void scltMakeValueNode(SNode **pNode, int32_t dataType, void *value) { SNode *node = nodesMakeNode(QUERY_NODE_VALUE); SValueNode *vnode = (SValueNode *)node; vnode->node.resType.type = dataType; if (IS_VAR_DATA_TYPE(dataType)) { vnode->datum.p = (char *)malloc(varDataTLen(value)); varDataCopy(vnode->datum.p, value); vnode->node.resType.bytes = varDataLen(value); } else { vnode->node.resType.bytes = tDataTypes[dataType].bytes; assignVal((char *)nodesGetValueFromNode(vnode), (const char *)value, 0, dataType); } *pNode = (SNode *)vnode; } void scltMakeOpNode(SNode **pNode, EOperatorType opType, int32_t resType, SNode *pLeft, SNode *pRight) { SNode *node = nodesMakeNode(QUERY_NODE_OPERATOR); SOperatorNode *onode = (SOperatorNode *)node; onode->node.resType.type = resType; onode->node.resType.bytes = tDataTypes[resType].bytes; onode->opType = opType; onode->pLeft = pLeft; onode->pRight = pRight; *pNode = (SNode *)onode; } void scltMakeListNode(SNode **pNode, SNodeList *list, int32_t resType) { SNode *node = nodesMakeNode(QUERY_NODE_NODE_LIST); SNodeListNode *lnode = (SNodeListNode *)node; lnode->dataType.type = resType; lnode->pNodeList = list; *pNode = (SNode *)lnode; } } TEST(constantTest, bigint_add_bigint) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_BIGINT, &scltLeftV); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_BIGINT, &scltRightV); scltMakeOpNode(&opNode, OP_TYPE_ADD, TSDB_DATA_TYPE_DOUBLE, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_DOUBLE); ASSERT_EQ(v->datum.d, (scltLeftV + scltRightV)); } TEST(constantTest, double_sub_bigint) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_DOUBLE, &scltLeftVd); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_BIGINT, &scltRightV); scltMakeOpNode(&opNode, OP_TYPE_SUB, TSDB_DATA_TYPE_DOUBLE, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_DOUBLE); ASSERT_EQ(v->datum.d, (scltLeftVd - scltRightV)); } TEST(constantTest, tinyint_and_smallint) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_TINYINT, &scltLeftV); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_SMALLINT, &scltRightV); scltMakeOpNode(&opNode, OP_TYPE_BIT_AND, TSDB_DATA_TYPE_BIGINT, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BIGINT); ASSERT_EQ(v->datum.i, (int64_t)scltLeftV & (int64_t)scltRightV); } TEST(constantTest, bigint_or_double) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_BIGINT, &scltLeftV); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_DOUBLE, &scltRightVd); scltMakeOpNode(&opNode, OP_TYPE_BIT_OR, TSDB_DATA_TYPE_BIGINT, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BIGINT); ASSERT_EQ(v->datum.i, (int64_t)scltLeftV | (int64_t)scltRightVd); } TEST(constantTest, int_greater_double) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_INT, &scltLeftV); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_DOUBLE, &scltRightVd); scltMakeOpNode(&opNode, OP_TYPE_GREATER_THAN, TSDB_DATA_TYPE_BOOL, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL); ASSERT_EQ(v->datum.b, scltLeftV > scltRightVd); } TEST(constantTest, int_greater_equal_binary) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; char binaryStr[64] = {0}; sprintf(&binaryStr[2], "%d", scltRightV); varDataSetLen(binaryStr, strlen(&binaryStr[2])); scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_INT, &scltLeftV); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_BINARY, binaryStr); scltMakeOpNode(&opNode, OP_TYPE_GREATER_THAN, TSDB_DATA_TYPE_BOOL, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL); ASSERT_EQ(v->datum.b, scltLeftV > scltRightVd); } TEST(constantTest, tinyint_lower_ubigint) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_TINYINT, &scltLeftV); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_UBIGINT, &scltRightV); scltMakeOpNode(&opNode, OP_TYPE_LOWER_THAN, TSDB_DATA_TYPE_BOOL, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL); ASSERT_EQ(v->datum.b, scltLeftV < scltRightV); } TEST(constantTest, usmallint_lower_equal_ubigint) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; int32_t leftv = 1, rightv = 1; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_USMALLINT, &leftv); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_UBIGINT, &rightv); scltMakeOpNode(&opNode, OP_TYPE_LOWER_EQUAL, TSDB_DATA_TYPE_BOOL, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL); ASSERT_EQ(v->datum.b, leftv <= rightv); } TEST(constantTest, int_equal_smallint) { SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL, *res = NULL; int32_t leftv = 1, rightv = 1; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_INT, &leftv); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_SMALLINT, &rightv); scltMakeOpNode(&opNode, OP_TYPE_EQUAL, TSDB_DATA_TYPE_BOOL, pLeft, pRight); int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL); ASSERT_EQ(v->datum.b, leftv == rightv); } TEST(constantTest, int_in_smallint) { SNode *pLeft = NULL, *pRight = NULL, *listNode = NULL, *res = NULL, *opNode = NULL; int32_t leftv = 1, rightv1 = 1,rightv2 = 2,rightv3 = 3; scltMakeValueNode(&pLeft, TSDB_DATA_TYPE_INT, &leftv); SNodeList* list = nodesMakeList(); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_SMALLINT, &rightv1); nodesListAppend(list, pRight); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_SMALLINT, &rightv2); nodesListAppend(list, pRight); scltMakeValueNode(&pRight, TSDB_DATA_TYPE_SMALLINT, &rightv3); nodesListAppend(list, pRight); scltMakeListNode(&listNode,list, TSDB_DATA_TYPE_SMALLINT); scltMakeOpNode(opNode, OP_TYPE_IN, TSDB_DATA_TYPE_BOOL, pLeft, listNode) int32_t code = scalarCalculateConstants(opNode, &res); ASSERT_EQ(code, 0); ASSERT_TRUE(res); ASSERT_EQ(nodeType(res), QUERY_NODE_VALUE); SValueNode *v = (SValueNode *)res; ASSERT_EQ(v->node.resType.type, TSDB_DATA_TYPE_BOOL); ASSERT_EQ(v->datum.b, true); } int main(int argc, char** argv) { srand(time(NULL)); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } #pragma GCC diagnostic pop