feature/qnode
This commit is contained in:
parent
7c1e4d319d
commit
8f7b375b54
|
@ -29,6 +29,7 @@ typedef struct SFilterInfo SFilterInfo;
|
|||
int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes);
|
||||
int32_t scalarCalculate(SNode *pNode, SSDataBlock *pSrc, SScalarParam *pDst);
|
||||
int32_t scalarGetOperatorParamNum(EOperatorType type);
|
||||
int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type);
|
||||
|
||||
int32_t vectorGetConvertType(int32_t type1, int32_t type2);
|
||||
int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut);
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct SBuiltinFuncDefinition {
|
|||
FExecGetEnv getEnvFunc;
|
||||
FExecInit initFunc;
|
||||
FExecProcess processFunc;
|
||||
FScalarExecProcess sprocessFunc;
|
||||
FExecFinalize finalizeFunc;
|
||||
} SBuiltinFuncDefinition;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.checkFunc = stubCheckAndGetResultType,
|
||||
.getEnvFunc = NULL,
|
||||
.initFunc = NULL,
|
||||
.processFunc = NULL,
|
||||
.sprocessFunc = NULL,
|
||||
.finalizeFunc = NULL
|
||||
}
|
||||
};
|
||||
|
|
|
@ -71,6 +71,14 @@ int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet) {
|
||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
pFpSet->process = funcMgtBuiltins[funcId].sprocessFunc;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool fmIsAggFunc(int32_t funcId) {
|
||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||
return false;
|
||||
|
|
|
@ -28,6 +28,8 @@ typedef struct SScalarCtx {
|
|||
SHashObj *pRes; /* element is SScalarParam */
|
||||
} SScalarCtx;
|
||||
|
||||
|
||||
#define SCL_DATA_TYPE_DUMMY_HASH 9000
|
||||
#define SCL_DEFAULT_OP_NUM 10
|
||||
|
||||
#define sclFatal(...) qFatal(__VA_ARGS__)
|
||||
|
|
|
@ -1706,69 +1706,6 @@ int32_t filterHandleValueExtInfo(SFilterUnit* unit, char extInfo) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t fltGenerateSetFromList(void **data, void *pNode, uint32_t type) {
|
||||
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
|
||||
if (NULL == pObj) {
|
||||
fltError("taosHashInit failed, size:%d", 256);
|
||||
FLT_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(type));
|
||||
|
||||
int32_t code = 0;
|
||||
SNodeListNode *nodeList = (SNodeListNode *)pNode;
|
||||
SListCell *cell = nodeList->pNodeList->pHead;
|
||||
SScalarParam in = {.num = 1}, out = {.num = 1, .type = type};
|
||||
int8_t dummy = 0;
|
||||
int32_t bufLen = 60;
|
||||
out.data = malloc(bufLen);
|
||||
int32_t len = 0;
|
||||
void *buf = NULL;
|
||||
|
||||
for (int32_t i = 0; i < nodeList->pNodeList->length; ++i) {
|
||||
SValueNode *valueNode = (SValueNode *)cell->pNode;
|
||||
|
||||
if (valueNode->node.resType.type != type) {
|
||||
in.type = valueNode->node.resType.type;
|
||||
in.bytes = valueNode->node.resType.bytes;
|
||||
in.data = nodesGetValueFromNode(valueNode);
|
||||
|
||||
code = vectorConvertImpl(&in, &out);
|
||||
if (code) {
|
||||
fltError("convert from %d to %d failed", in.type, out.type);
|
||||
FLT_ERR_JRET(code);
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(type)) {
|
||||
len = varDataLen(out.data);
|
||||
} else {
|
||||
len = tDataTypes[type].bytes;
|
||||
}
|
||||
|
||||
buf = out.data;
|
||||
} else {
|
||||
buf = nodesGetValueFromNode(valueNode);
|
||||
len = valueNode->node.resType.bytes;
|
||||
}
|
||||
|
||||
if (taosHashPut(pObj, buf, (size_t)len, &dummy, sizeof(dummy))) {
|
||||
fltError("taosHashPut failed");
|
||||
FLT_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(out.data);
|
||||
*data = pObj;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(out.data);
|
||||
taosHashCleanup(pObj);
|
||||
|
||||
FLT_RET(code);
|
||||
}
|
||||
|
||||
int32_t fltInitValFieldData(SFilterInfo *info) {
|
||||
for (uint32_t i = 0; i < info->unitNum; ++i) {
|
||||
|
@ -1793,7 +1730,7 @@ int32_t fltInitValFieldData(SFilterInfo *info) {
|
|||
}
|
||||
|
||||
if (unit->compare.optr == TSDB_RELATION_IN) {
|
||||
FLT_ERR_RET(fltGenerateSetFromList((void **)&fi->data, fi->desc, type));
|
||||
FLT_ERR_RET(scalarGenerateSetFromList((void **)&fi->data, fi->desc, type));
|
||||
if (fi->data == NULL) {
|
||||
fltError("failed to convert in param");
|
||||
FLT_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
|
|
|
@ -7,13 +7,79 @@
|
|||
#include "sclInt.h"
|
||||
|
||||
int32_t scalarGetOperatorParamNum(EOperatorType type) {
|
||||
if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == type) {
|
||||
if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == type || OP_TYPE_IS_TRUE == type || OP_TYPE_IS_NOT_TRUE == type
|
||||
|| OP_TYPE_IS_FALSE == type || OP_TYPE_IS_NOT_FALSE == type || OP_TYPE_IS_UNKNOWN == type || OP_TYPE_IS_NOT_UNKNOWN == type) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
|
||||
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
|
||||
if (NULL == pObj) {
|
||||
sclError("taosHashInit failed, size:%d", 256);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(type));
|
||||
|
||||
int32_t code = 0;
|
||||
SNodeListNode *nodeList = (SNodeListNode *)pNode;
|
||||
SListCell *cell = nodeList->pNodeList->pHead;
|
||||
SScalarParam in = {.num = 1}, out = {.num = 1, .type = type};
|
||||
int8_t dummy = 0;
|
||||
int32_t bufLen = 60;
|
||||
out.data = malloc(bufLen);
|
||||
int32_t len = 0;
|
||||
void *buf = NULL;
|
||||
|
||||
for (int32_t i = 0; i < nodeList->pNodeList->length; ++i) {
|
||||
SValueNode *valueNode = (SValueNode *)cell->pNode;
|
||||
|
||||
if (valueNode->node.resType.type != type) {
|
||||
in.type = valueNode->node.resType.type;
|
||||
in.bytes = valueNode->node.resType.bytes;
|
||||
in.data = nodesGetValueFromNode(valueNode);
|
||||
|
||||
code = vectorConvertImpl(&in, &out);
|
||||
if (code) {
|
||||
sclError("convert from %d to %d failed", in.type, out.type);
|
||||
SCL_ERR_JRET(code);
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(type)) {
|
||||
len = varDataLen(out.data);
|
||||
} else {
|
||||
len = tDataTypes[type].bytes;
|
||||
}
|
||||
|
||||
buf = out.data;
|
||||
} else {
|
||||
buf = nodesGetValueFromNode(valueNode);
|
||||
len = valueNode->node.resType.bytes;
|
||||
}
|
||||
|
||||
if (taosHashPut(pObj, buf, (size_t)len, &dummy, sizeof(dummy))) {
|
||||
sclError("taosHashPut failed");
|
||||
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(out.data);
|
||||
*data = pObj;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(out.data);
|
||||
taosHashCleanup(pObj);
|
||||
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
|
||||
void sclFreeRes(SHashObj *res) {
|
||||
SScalarParam *p = NULL;
|
||||
void *pIter = taosHashIterate(res, NULL);
|
||||
|
@ -47,7 +113,15 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t
|
|||
}
|
||||
case QUERY_NODE_NODE_LIST: {
|
||||
SNodeListNode *nodeList = (SNodeListNode *)node;
|
||||
//TODO BUILD HASH
|
||||
if (nodeList->pNodeList->length <= 0) {
|
||||
sclError("invalid length in nodeList, length:%d", nodeList->pNodeList->length);
|
||||
SCL_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SCL_ERR_RET(scalarGenerateSetFromList(¶m->data, node, nodeList->dataType.type));
|
||||
param->num = 1;
|
||||
param->type = SCL_DATA_TYPE_DUMMY_HASH;
|
||||
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_COLUMN_REF: {
|
||||
|
@ -291,6 +365,7 @@ int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *outp
|
|||
SCL_ERR_RET(sclInitOperatorParams(¶ms, node, ctx, &rowNum));
|
||||
|
||||
output->type = node->node.resType.type;
|
||||
output->num = rowNum;
|
||||
output->data = calloc(rowNum, tDataTypes[output->type].bytes);
|
||||
if (NULL == output->data) {
|
||||
sclError("calloc %d failed", (int32_t)rowNum * tDataTypes[output->type].bytes);
|
||||
|
@ -303,17 +378,21 @@ int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *outp
|
|||
SScalarParam* pLeft = ¶ms[0];
|
||||
SScalarParam* pRight = paramNum > 1 ? ¶ms[1] : NULL;
|
||||
|
||||
void *data = output->data;
|
||||
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
|
||||
OperatorFn(pLeft, pRight, output->data, TSDB_ORDER_ASC);
|
||||
|
||||
sclParamMoveNext(output, 1);
|
||||
sclParamMoveNext(output, 1);
|
||||
sclParamMoveNext(pLeft, 1);
|
||||
if (pRight) {
|
||||
sclParamMoveNext(pRight, 1);
|
||||
}
|
||||
}
|
||||
|
||||
output->data = data;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
|
|
@ -258,31 +258,7 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
|
||||
switch (outType) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
if (inType == TSDB_DATA_TYPE_BINARY) {
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
GET_TYPED_DATA(*(bool *)output, bool, TSDB_DATA_TYPE_USMALLINT, &varDataLen(input));
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += sizeof(bool);
|
||||
}
|
||||
} else if (inType == TSDB_DATA_TYPE_NCHAR) {
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
GET_TYPED_DATA(*(bool *)output, bool, TSDB_DATA_TYPE_USMALLINT, &varDataLen(input));
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += tDataTypes[outType].bytes;
|
||||
}
|
||||
} else {
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
uint64_t value = 0;
|
||||
GET_TYPED_DATA(value, uint64_t, inType, input);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
|
||||
input += tDataTypes[inType].bytes;
|
||||
output += tDataTypes[outType].bytes;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
|
@ -295,17 +271,21 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
if (varDataLen(input) >= bufSize) {
|
||||
bufSize = varDataLen(input) + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
if (varDataLen(input) >= bufSize) {
|
||||
bufSize = varDataLen(input) + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||
tmp[varDataLen(input)] = 0;
|
||||
|
||||
int64_t value = strtoll(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||
tmp[varDataLen(input)] = 0;
|
||||
|
||||
int64_t value = strtoll(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += tDataTypes[outType].bytes;
|
||||
}
|
||||
|
@ -319,21 +299,25 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||
if (len < 0){
|
||||
qError("castConvert taosUcs4ToMbs error 1");
|
||||
tfree(tmp);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
tmp[len] = 0;
|
||||
int64_t value = strtoll(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||
if (len < 0){
|
||||
qError("castConvert taosUcs4ToMbs error 1");
|
||||
tfree(tmp);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
tmp[len] = 0;
|
||||
int64_t value = strtoll(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += tDataTypes[outType].bytes;
|
||||
|
@ -351,6 +335,7 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
|
@ -362,16 +347,20 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
if (varDataLen(input) >= bufSize) {
|
||||
bufSize = varDataLen(input) + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
if (varDataLen(input) >= bufSize) {
|
||||
bufSize = varDataLen(input) + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||
tmp[varDataLen(input)] = 0;
|
||||
uint64_t value = strtoull(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||
tmp[varDataLen(input)] = 0;
|
||||
uint64_t value = strtoull(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += tDataTypes[outType].bytes;
|
||||
}
|
||||
|
@ -385,21 +374,25 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||
if (len < 0){
|
||||
qError("castConvert taosUcs4ToMbs error 1");
|
||||
tfree(tmp);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
tmp[len] = 0;
|
||||
uint64_t value = strtoull(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||
if (len < 0){
|
||||
qError("castConvert taosUcs4ToMbs error 1");
|
||||
tfree(tmp);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
tmp[len] = 0;
|
||||
uint64_t value = strtoull(tmp, NULL, 10);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += tDataTypes[outType].bytes;
|
||||
|
@ -408,9 +401,13 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
tfree(tmp);
|
||||
} else {
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
uint64_t value = 0;
|
||||
GET_TYPED_DATA(value, uint64_t, inType, input);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
uint64_t value = 0;
|
||||
GET_TYPED_DATA(value, uint64_t, inType, input);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
input += tDataTypes[inType].bytes;
|
||||
output += tDataTypes[outType].bytes;
|
||||
|
@ -427,17 +424,21 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
if (varDataLen(input) >= bufSize) {
|
||||
bufSize = varDataLen(input) + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
if (varDataLen(input) >= bufSize) {
|
||||
bufSize = varDataLen(input) + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||
tmp[varDataLen(input)] = 0;
|
||||
|
||||
double value = strtod(tmp, NULL);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||
tmp[varDataLen(input)] = 0;
|
||||
|
||||
double value = strtod(tmp, NULL);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += tDataTypes[outType].bytes;
|
||||
}
|
||||
|
@ -451,21 +452,25 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||
if (len < 0){
|
||||
qError("castConvert taosUcs4ToMbs error 1");
|
||||
tfree(tmp);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||
tmp = realloc(tmp, bufSize);
|
||||
}
|
||||
|
||||
tmp[len] = 0;
|
||||
double value = strtod(tmp, NULL);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||
if (len < 0){
|
||||
qError("castConvert taosUcs4ToMbs error 1");
|
||||
tfree(tmp);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
tmp[len] = 0;
|
||||
double value = strtod(tmp, NULL);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||
output += tDataTypes[outType].bytes;
|
||||
|
@ -474,9 +479,13 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
|||
tfree(tmp);
|
||||
} else {
|
||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||
int64_t value = 0;
|
||||
GET_TYPED_DATA(value, int64_t, inType, input);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
if (isNull(input, inType)) {
|
||||
assignVal(output, getNullValue(outType), 0, outType);
|
||||
} else {
|
||||
int64_t value = 0;
|
||||
GET_TYPED_DATA(value, int64_t, inType, input);
|
||||
SET_TYPED_DATA(output, outType, value);
|
||||
}
|
||||
|
||||
input += tDataTypes[inType].bytes;
|
||||
output += tDataTypes[outType].bytes;
|
||||
|
@ -1121,6 +1130,12 @@ void vectorNotNull(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
|||
}
|
||||
}
|
||||
|
||||
void vectorIsTrue(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||
SScalarParam output = {.data = out, .num = pLeft->num, .type = TSDB_DATA_TYPE_BOOL};
|
||||
|
||||
vectorConvertImpl(pLeft, &output);
|
||||
}
|
||||
|
||||
|
||||
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
|
||||
switch (binFunctionId) {
|
||||
|
@ -1166,6 +1181,8 @@ _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
|
|||
return vectorBitAnd;
|
||||
case OP_TYPE_BIT_OR:
|
||||
return vectorBitOr;
|
||||
case OP_TYPE_IS_TRUE:
|
||||
return vectorIsTrue;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
|
|
|
@ -8,7 +8,7 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
|||
ADD_EXECUTABLE(scalarTest ${SOURCE_LIST})
|
||||
TARGET_LINK_LIBRARIES(
|
||||
scalarTest
|
||||
PUBLIC os util common gtest qcom function nodes
|
||||
PUBLIC os util common gtest qcom function nodes scalar
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(
|
||||
|
|
|
@ -36,15 +36,220 @@
|
|||
#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(scalarTest, func) {
|
||||
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
Loading…
Reference in New Issue