未验证 提交 9a024590 编写于 作者: D dapan1121 提交者: GitHub

Merge pull request #17321 from taosdata/feat/caseWhen

feat: support case when operator
......@@ -43,7 +43,7 @@ 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(const SScalarParam *pIn, SScalarParam *pOut, int32_t *overflow);
int32_t vectorConvertSingleColImpl(const SScalarParam *pIn, SScalarParam *pOut, int32_t *overflow, int32_t startIndex, int32_t numOfRows);
/* Math functions */
int32_t absFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
......
......@@ -1250,6 +1250,17 @@ void createExprFromOneNode(SExprInfo* pExp, SNode* pNode, int16_t slotId) {
pExp->base.resSchema =
createResSchema(pType->type, pType->bytes, slotId, pType->scale, pType->precision, pOpNode->node.aliasName);
pExp->pExpr->_optrRoot.pRootNode = pNode;
} else if (type == QUERY_NODE_CASE_WHEN) {
pExp->pExpr->nodeType = QUERY_NODE_OPERATOR;
SCaseWhenNode* pCaseNode = (SCaseWhenNode*)pNode;
pExp->base.pParam = taosMemoryCalloc(1, sizeof(SFunctParam));
pExp->base.numOfParams = 1;
SDataType* pType = &pCaseNode->node.resType;
pExp->base.resSchema = createResSchema(pType->type, pType->bytes, slotId, pType->scale,
pType->precision, pCaseNode->node.aliasName);
pExp->pExpr->_optrRoot.pRootNode = pNode;
} else {
ASSERT(0);
}
......
......@@ -131,7 +131,7 @@ static int32_t valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
COPY_SCALAR_FIELD(placeholderNo);
COPY_SCALAR_FIELD(typeData);
COPY_SCALAR_FIELD(unit);
if (!pSrc->translate) {
if (!pSrc->translate || pSrc->isNull) {
return TSDB_CODE_SUCCESS;
}
switch (pSrc->node.resType.type) {
......
......@@ -3011,7 +3011,7 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkValueIsNull, pNode->isNull);
}
if (TSDB_CODE_SUCCESS == code && pNode->translate) {
if (TSDB_CODE_SUCCESS == code && pNode->translate && !pNode->isNull) {
code = datumToJson(pNode, pJson);
}
......@@ -3161,7 +3161,7 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkValueIsNull, &pNode->isNull);
}
if (TSDB_CODE_SUCCESS == code && pNode->translate) {
if (TSDB_CODE_SUCCESS == code && pNode->translate && !pNode->isNull) {
code = jsonToDatum(pJson, pNode);
}
......
......@@ -1604,7 +1604,7 @@ char* nodesGetStrValueFromNode(SValueNode* pNode) {
bool nodesIsExprNode(const SNode* pNode) {
ENodeType type = nodeType(pNode);
return (QUERY_NODE_COLUMN == type || QUERY_NODE_VALUE == type || QUERY_NODE_OPERATOR == type ||
QUERY_NODE_FUNCTION == type || QUERY_NODE_LOGIC_CONDITION == type);
QUERY_NODE_FUNCTION == type || QUERY_NODE_LOGIC_CONDITION == type || QUERY_NODE_CASE_WHEN == type);
}
bool nodesIsUnaryOp(const SOperatorNode* pOp) {
......
......@@ -1888,6 +1888,7 @@ static EDealRes translateCaseWhen(STranslateContext* pCxt, SCaseWhenNode* pCaseW
pWhenThen->pWhen = pIsTrue;
}
if (first) {
first = false;
pCaseWhen->node.resType = ((SExprNode*)pNode)->resType;
} else if (!dataTypeEqual(&pCaseWhen->node.resType, &((SExprNode*)pNode)->resType)) {
SNode* pCastFunc = NULL;
......
......@@ -66,7 +66,8 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
switch (nodeType(*pNode)) {
case QUERY_NODE_OPERATOR:
case QUERY_NODE_LOGIC_CONDITION:
case QUERY_NODE_FUNCTION: {
case QUERY_NODE_FUNCTION:
case QUERY_NODE_CASE_WHEN: {
SRewriteExprCxt* pCxt = (SRewriteExprCxt*)pContext;
SNode* pExpr;
int32_t index = 0;
......@@ -118,6 +119,17 @@ static EDealRes doNameExpr(SNode* pNode, void* pContext) {
return DEAL_RES_CONTINUE;
}
static int32_t rewriteExprForSelect(SNode* pExpr, SSelectStmt* pSelect, ESqlClause clause) {
nodesWalkExpr(pExpr, doNameExpr, NULL);
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = NULL};
cxt.errCode = nodesListMakeAppend(&cxt.pExprs, pExpr);
if (TSDB_CODE_SUCCESS == cxt.errCode) {
nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
nodesClearList(cxt.pExprs);
}
return cxt.errCode;
}
static int32_t rewriteExprsForSelect(SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
nodesWalkExprs(pExprs, doNameExpr, NULL);
SRewriteExprCxt cxt = {.errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs};
......@@ -711,8 +723,13 @@ static int32_t createWindowLogicNodeByState(SLogicPlanContext* pCxt, SStateWindo
nodesDestroyNode((SNode*)pWindow);
return TSDB_CODE_OUT_OF_MEMORY;
}
return createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
// rewrite the expression in subsequent clauses
int32_t code = rewriteExprForSelect(pWindow->pStateExpr, pSelect, SQL_CLAUSE_WINDOW);
if (TSDB_CODE_SUCCESS == code) {
code = createWindowLogicNodeFinalize(pCxt, pSelect, pWindow, pLogicNode);
}
return code;
}
static int32_t createWindowLogicNodeBySession(SLogicPlanContext* pCxt, SSessionWindowNode* pSession,
......
......@@ -761,7 +761,8 @@ static EDealRes doRewritePrecalcExprs(SNode** pNode, void* pContext) {
return collectAndRewrite(pCxt, pNode);
}
case QUERY_NODE_OPERATOR:
case QUERY_NODE_LOGIC_CONDITION: {
case QUERY_NODE_LOGIC_CONDITION:
case QUERY_NODE_CASE_WHEN: {
return collectAndRewrite(pCxt, pNode);
}
case QUERY_NODE_FUNCTION: {
......
......@@ -53,7 +53,8 @@ static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
}
case QUERY_NODE_OPERATOR:
case QUERY_NODE_LOGIC_CONDITION:
case QUERY_NODE_FUNCTION: {
case QUERY_NODE_FUNCTION:
case QUERY_NODE_CASE_WHEN: {
SExprNode* pExpr = (SExprNode*)pNode;
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
if (NULL == pCol) {
......
......@@ -86,7 +86,7 @@ typedef struct SScalarCtx {
} \
} while (0)
int32_t doConvertDataType(SValueNode* pValueNode, SScalarParam* out, int32_t* overflow);
int32_t sclConvertValueToSclParam(SValueNode* pValueNode, SScalarParam* out, int32_t* overflow);
int32_t sclCreateColumnInfoData(SDataType* pType, int32_t numOfRows, SScalarParam* pParam);
int32_t sclConvertToTsValueNode(int8_t precision, SValueNode* valueNode);
......@@ -95,6 +95,11 @@ int32_t sclConvertToTsValueNode(int8_t precision, SValueNode* valueNode);
#define GET_PARAM_PRECISON(_c) ((_c)->columnData->info.precision)
void sclFreeParam(SScalarParam* param);
void doVectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
int32_t _ord, int32_t optr);
void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
int32_t _ord, int32_t optr);
void vectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord, int32_t optr);
#ifdef __cplusplus
}
......
......@@ -20,6 +20,15 @@
extern "C" {
#endif
typedef struct SSclVectorConvCtx {
const SScalarParam* pIn;
SScalarParam* pOut;
int32_t startIndex;
int32_t endIndex;
int16_t inType;
int16_t outType;
} SSclVectorConvCtx;
typedef double (*_getDoubleValue_fn_t)(void *src, int32_t index);
static FORCE_INLINE double getVectorDoubleValue_TINYINT(void *src, int32_t index) {
......
......@@ -1165,7 +1165,7 @@ int32_t fltAddGroupUnitFromNode(SFilterInfo *info, SNode *tree, SArray *group) {
SValueNode *valueNode = (SValueNode *)cell->pNode;
if (valueNode->node.resType.type != type) {
int32_t overflow = 0;
code = doConvertDataType(valueNode, &out, &overflow);
code = sclConvertValueToSclParam(valueNode, &out, &overflow);
if (code) {
// fltError("convert from %d to %d failed", in.type, out.type);
FLT_ERR_RET(code);
......@@ -1973,7 +1973,7 @@ int32_t fltInitValFieldData(SFilterInfo *info) {
}
// todo refactor the convert
int32_t code = doConvertDataType(var, &out, NULL);
int32_t code = sclConvertValueToSclParam(var, &out, NULL);
if (code != TSDB_CODE_SUCCESS) {
qError("convert value to type[%d] failed", type);
return TSDB_CODE_TSC_INVALID_OPERATION;
......@@ -3792,6 +3792,11 @@ EDealRes fltReviseRewriter(SNode **pNode, void *pContext) {
return DEAL_RES_CONTINUE;
}
if (QUERY_NODE_CASE_WHEN == nodeType(*pNode) || QUERY_NODE_WHEN_THEN == nodeType(*pNode)) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
}
if (QUERY_NODE_OPERATOR == nodeType(*pNode)) {
SOperatorNode *node = (SOperatorNode *)*pNode;
if (!FLT_IS_COMPARISON_OPERATOR(node->opType)) {
......
......@@ -61,7 +61,7 @@ int32_t sclCreateColumnInfoData(SDataType *pType, int32_t numOfRows, SScalarPara
return TSDB_CODE_SUCCESS;
}
int32_t doConvertDataType(SValueNode *pValueNode, SScalarParam *out, int32_t *overflow) {
int32_t sclConvertValueToSclParam(SValueNode* pValueNode, SScalarParam* out, int32_t* overflow) {
SScalarParam in = {.numOfRows = 1};
int32_t code = sclCreateColumnInfoData(&pValueNode->node.resType, 1, &in);
if (code != TSDB_CODE_SUCCESS) {
......@@ -71,12 +71,34 @@ int32_t doConvertDataType(SValueNode *pValueNode, SScalarParam *out, int32_t *ov
colDataAppend(in.columnData, 0, nodesGetValueFromNode(pValueNode), false);
colInfoDataEnsureCapacity(out->columnData, 1);
code = vectorConvertImpl(&in, out, overflow);
code = vectorConvertSingleColImpl(&in, out, overflow, -1, -1);
sclFreeParam(&in);
return code;
}
int32_t sclExtendResRows(SScalarParam *pDst, SScalarParam *pSrc, SArray *pBlockList) {
SSDataBlock* pb = taosArrayGetP(pBlockList, 0);
SScalarParam *pLeft = taosMemoryCalloc(1, sizeof(SScalarParam));
if (NULL == pLeft) {
sclError("calloc %d failed", (int32_t)sizeof(SScalarParam));
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
}
pLeft->numOfRows = pb->info.rows;
if (pDst->numOfRows < pb->info.rows) {
colInfoDataEnsureCapacity(pDst->columnData, pb->info.rows);
}
_bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(OP_TYPE_ASSIGN);
OperatorFn(pLeft, pSrc, pDst, TSDB_ORDER_ASC);
taosMemoryFree(pLeft);
return TSDB_CODE_SUCCESS;
}
int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
if (NULL == pObj) {
......@@ -110,7 +132,7 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
}
int32_t overflow = 0;
code = doConvertDataType(valueNode, &out, &overflow);
code = sclConvertValueToSclParam(valueNode, &out, &overflow);
if (code != TSDB_CODE_SUCCESS) {
// sclError("convert data from %d to %d failed", in.type, out.type);
SCL_ERR_JRET(code);
......@@ -178,7 +200,7 @@ void sclFreeRes(SHashObj *res) {
}
void sclFreeParam(SScalarParam *param) {
if (!param->colAlloced) {
if (NULL == param || !param->colAlloced) {
return;
}
......@@ -386,7 +408,8 @@ int32_t sclInitParam(SNode *node, SScalarParam *param, SScalarCtx *ctx, int32_t
}
case QUERY_NODE_FUNCTION:
case QUERY_NODE_OPERATOR:
case QUERY_NODE_LOGIC_CONDITION: {
case QUERY_NODE_LOGIC_CONDITION:
case QUERY_NODE_CASE_WHEN: {
SScalarParam *res = (SScalarParam *)taosHashGet(ctx->pRes, &node, POINTER_BYTES);
if (NULL == res) {
sclError("no result for node, type:%d, node:%p", nodeType(node), node);
......@@ -540,6 +563,135 @@ _return:
SCL_RET(code);
}
int32_t sclGetNodeRes(SNode* node, SScalarCtx *ctx, SScalarParam **res) {
if (NULL == node) {
return TSDB_CODE_SUCCESS;
}
int32_t rowNum = 0;
*res = taosMemoryCalloc(1, sizeof(**res));
if (NULL == *res) {
SCL_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
}
SCL_ERR_RET(sclInitParam(node, *res, ctx, &rowNum));
return TSDB_CODE_SUCCESS;
}
int32_t sclWalkCaseWhenList(SScalarCtx *ctx, SNodeList* pList, struct SListCell* pCell, SScalarParam *pCase, SScalarParam *pElse, SScalarParam *pComp, SScalarParam *output, int32_t rowIdx, int32_t totalRows, bool *complete) {
SNode *node = NULL;
SWhenThenNode* pWhenThen = NULL;
SScalarParam *pWhen = NULL;
SScalarParam *pThen = NULL;
int32_t code = 0;
for (SListCell* cell = pCell; (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext) {
pWhenThen = (SWhenThenNode*)node;
SCL_ERR_RET(sclGetNodeRes(pWhenThen->pWhen, ctx, &pWhen));
SCL_ERR_RET(sclGetNodeRes(pWhenThen->pThen, ctx, &pThen));
vectorCompareImpl(pCase, pWhen, pComp, rowIdx, 1, TSDB_ORDER_ASC, OP_TYPE_EQUAL);
bool *equal = (bool*)colDataGetData(pComp->columnData, rowIdx);
if (*equal) {
colDataAppend(output->columnData, rowIdx, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0)), colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0)));
if (0 == rowIdx && 1 == pCase->numOfRows && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && totalRows > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
*complete = true;
}
goto _return;
}
}
if (pElse) {
colDataAppend(output->columnData, rowIdx, colDataGetData(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0)), colDataIsNull_s(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0)));
if (0 == rowIdx && 1 == pCase->numOfRows && 1 == pElse->numOfRows && totalRows > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
*complete = true;
}
goto _return;
}
colDataAppend(output->columnData, rowIdx, NULL, true);
if (0 == rowIdx && 1 == pCase->numOfRows && totalRows > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
*complete = true;
}
_return:
sclFreeParam(pWhen);
sclFreeParam(pThen);
SCL_RET(code);
}
int32_t sclWalkWhenList(SScalarCtx *ctx, SNodeList* pList, struct SListCell* pCell, SScalarParam *pElse, SScalarParam *output,
int32_t rowIdx, int32_t totalRows, bool *complete, bool preSingle) {
SNode *node = NULL;
SWhenThenNode* pWhenThen = NULL;
SScalarParam *pWhen = NULL;
SScalarParam *pThen = NULL;
int32_t code = 0;
for (SListCell* cell = pCell; (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext) {
pWhenThen = (SWhenThenNode*)node;
pWhen = NULL;
pThen = NULL;
SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pWhen, ctx, &pWhen));
SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pThen, ctx, &pThen));
bool *whenValue = (bool*)colDataGetData(pWhen->columnData, (pWhen->numOfRows > 1 ? rowIdx : 0));
if (*whenValue) {
colDataAppend(output->columnData, rowIdx, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0)), colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? rowIdx : 0)));
if (preSingle && 0 == rowIdx && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && totalRows > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
*complete = true;
}
goto _return;
}
sclFreeParam(pWhen);
sclFreeParam(pThen);
}
if (pElse) {
colDataAppend(output->columnData, rowIdx, colDataGetData(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0)), colDataIsNull_s(pElse->columnData, (pElse->numOfRows > 1 ? rowIdx : 0)));
if (preSingle && 0 == rowIdx && 1 == pElse->numOfRows && totalRows > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
*complete = true;
}
goto _return;
}
colDataAppend(output->columnData, rowIdx, NULL, true);
if (preSingle && 0 == rowIdx && totalRows > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
*complete = true;
}
_return:
sclFreeParam(pWhen);
sclFreeParam(pThen);
SCL_RET(code);
}
int32_t sclExecFunction(SFunctionNode *node, SScalarCtx *ctx, SScalarParam *output) {
SScalarParam *params = NULL;
int32_t rowNum = 0;
......@@ -698,6 +850,101 @@ _return:
SCL_RET(code);
}
int32_t sclExecCaseWhen(SCaseWhenNode *node, SScalarCtx *ctx, SScalarParam *output) {
int32_t code = 0;
SScalarParam *pCase = NULL;
SScalarParam *pElse = NULL;
SScalarParam *pWhen = NULL;
SScalarParam *pThen = NULL;
SScalarParam comp = {0};
int32_t rowNum = 1;
bool complete = false;
if (NULL == node->pWhenThenList || node->pWhenThenList->length <= 0) {
sclError("invalid whenThen list");
SCL_ERR_RET(TSDB_CODE_INVALID_PARA);
}
if (ctx->pBlockList) {
SSDataBlock* pb = taosArrayGetP(ctx->pBlockList, 0);
rowNum = pb->info.rows;
output->numOfRows = pb->info.rows;
}
SCL_ERR_JRET(sclCreateColumnInfoData(&node->node.resType, rowNum, output));
SCL_ERR_JRET(sclGetNodeRes(node->pCase, ctx, &pCase));
SCL_ERR_JRET(sclGetNodeRes(node->pElse, ctx, &pElse));
SDataType compType = {0};
compType.type = TSDB_DATA_TYPE_BOOL;
compType.bytes = tDataTypes[compType.type].bytes;
SCL_ERR_JRET(sclCreateColumnInfoData(&compType, rowNum, &comp));
SNode* tnode = NULL;
SWhenThenNode* pWhenThen = (SWhenThenNode*)node->pWhenThenList->pHead->pNode;
SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pWhen, ctx, &pWhen));
SCL_ERR_JRET(sclGetNodeRes(pWhenThen->pThen, ctx, &pThen));
if (pCase) {
vectorCompare(pCase, pWhen, &comp, TSDB_ORDER_ASC, OP_TYPE_EQUAL);
for (int32_t i = 0; i < rowNum; ++i) {
bool *equal = (bool*)colDataGetData(comp.columnData, (comp.numOfRows > 1 ? i : 0));
if (*equal) {
colDataAppend(output->columnData, i, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)), colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)));
if (0 == i && 1 == pCase->numOfRows && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && rowNum > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
break;
}
} else {
SCL_ERR_JRET(sclWalkCaseWhenList(ctx, node->pWhenThenList, node->pWhenThenList->pHead->pNext, pCase, pElse, &comp, output, i, rowNum, &complete));
if (complete) {
break;
}
}
}
} else {
for (int32_t i = 0; i < rowNum; ++i) {
bool *whenValue = (bool*)colDataGetData(pWhen->columnData, (pWhen->numOfRows > 1 ? i : 0));
if (*whenValue) {
colDataAppend(output->columnData, i, colDataGetData(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)), colDataIsNull_s(pThen->columnData, (pThen->numOfRows > 1 ? i : 0)));
if (0 == i && 1 == pWhen->numOfRows && 1 == pThen->numOfRows && rowNum > 1) {
SCL_ERR_JRET(sclExtendResRows(output, output, ctx->pBlockList));
break;
}
} else {
SCL_ERR_JRET(sclWalkWhenList(ctx, node->pWhenThenList, node->pWhenThenList->pHead->pNext, pElse, output, i, rowNum, &complete, (pWhen->numOfRows == 1 && pThen->numOfRows == 1)));
if (complete) {
break;
}
}
}
}
sclFreeParam(pCase);
sclFreeParam(pElse);
sclFreeParam(&comp);
sclFreeParam(pWhen);
sclFreeParam(pThen);
return TSDB_CODE_SUCCESS;
_return:
sclFreeParam(pCase);
sclFreeParam(pElse);
sclFreeParam(&comp);
sclFreeParam(pWhen);
sclFreeParam(pThen);
sclFreeParam(output);
SCL_RET(code);
}
EDealRes sclRewriteNullInOptr(SNode **pNode, SScalarCtx *ctx, EOperatorType opType) {
if (opType <= OP_TYPE_CALC_MAX) {
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
......@@ -960,9 +1207,66 @@ EDealRes sclRewriteOperator(SNode **pNode, SScalarCtx *ctx) {
return DEAL_RES_CONTINUE;
}
EDealRes sclRewriteCaseWhen(SNode** pNode, SScalarCtx *ctx) {
SCaseWhenNode *node = (SCaseWhenNode *)*pNode;
if ((!SCL_IS_CONST_NODE(node->pCase)) || (!SCL_IS_CONST_NODE(node->pElse))) {
return DEAL_RES_CONTINUE;
}
SNode* tnode = NULL;
FOREACH(tnode, node->pWhenThenList) {
SWhenThenNode* pWhenThen = (SWhenThenNode*)tnode;
if (!SCL_IS_CONST_NODE(pWhenThen->pWhen) || !SCL_IS_CONST_NODE(pWhenThen->pThen)) {
return DEAL_RES_CONTINUE;
}
}
SScalarParam output = {0};
ctx->code = sclExecCaseWhen(node, ctx, &output);
if (ctx->code) {
return DEAL_RES_ERROR;
}
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
if (NULL == res) {
sclError("make value node failed");
sclFreeParam(&output);
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
return DEAL_RES_ERROR;
}
res->translate = true;
res->node.resType = node->node.resType;
if (colDataIsNull_s(output.columnData, 0)) {
res->isNull = true;
res->node.resType = node->node.resType;
} else {
int32_t type = output.columnData->info.type;
if (IS_VAR_DATA_TYPE(type)) { // todo refactor
res->datum.p = output.columnData->pData;
output.columnData->pData = NULL;
} else {
nodesSetValueNodeValue(res, output.columnData->pData);
}
}
nodesDestroyNode(*pNode);
*pNode = (SNode*)res;
sclFreeParam(&output);
return DEAL_RES_CONTINUE;
}
EDealRes sclConstantsRewriter(SNode **pNode, void *pContext) {
SScalarCtx *ctx = (SScalarCtx *)pContext;
if (QUERY_NODE_OPERATOR == nodeType(*pNode)) {
return sclRewriteOperator(pNode, ctx);
}
if (QUERY_NODE_FUNCTION == nodeType(*pNode)) {
return sclRewriteFunction(pNode, ctx);
}
......@@ -971,8 +1275,8 @@ EDealRes sclConstantsRewriter(SNode **pNode, void *pContext) {
return sclRewriteLogic(pNode, ctx);
}
if (QUERY_NODE_OPERATOR == nodeType(*pNode)) {
return sclRewriteOperator(pNode, ctx);
if (QUERY_NODE_CASE_WHEN == nodeType(*pNode)) {
return sclRewriteCaseWhen(pNode, ctx);
}
return DEAL_RES_CONTINUE;
......@@ -1082,13 +1386,36 @@ EDealRes sclWalkTarget(SNode *pNode, SScalarCtx *ctx) {
return DEAL_RES_CONTINUE;
}
EDealRes sclWalkCaseWhen(SNode* pNode, SScalarCtx *ctx) {
SCaseWhenNode *node = (SCaseWhenNode *)pNode;
SScalarParam output = {0};
ctx->code = sclExecCaseWhen(node, ctx, &output);
if (ctx->code) {
return DEAL_RES_ERROR;
}
if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
return DEAL_RES_ERROR;
}
return DEAL_RES_CONTINUE;
}
EDealRes sclCalcWalker(SNode *pNode, void *pContext) {
if (QUERY_NODE_VALUE == nodeType(pNode) || QUERY_NODE_NODE_LIST == nodeType(pNode) ||
QUERY_NODE_COLUMN == nodeType(pNode) || QUERY_NODE_LEFT_VALUE == nodeType(pNode)) {
if (QUERY_NODE_VALUE == nodeType(pNode) || QUERY_NODE_NODE_LIST == nodeType(pNode)
|| QUERY_NODE_COLUMN == nodeType(pNode) || QUERY_NODE_LEFT_VALUE == nodeType(pNode)
|| QUERY_NODE_WHEN_THEN == nodeType(pNode)) {
return DEAL_RES_CONTINUE;
}
SScalarCtx *ctx = (SScalarCtx *)pContext;
if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
return sclWalkOperator(pNode, ctx);
}
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
return sclWalkFunction(pNode, ctx);
}
......@@ -1097,38 +1424,19 @@ EDealRes sclCalcWalker(SNode *pNode, void *pContext) {
return sclWalkLogic(pNode, ctx);
}
if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
return sclWalkOperator(pNode, ctx);
}
if (QUERY_NODE_TARGET == nodeType(pNode)) {
return sclWalkTarget(pNode, ctx);
}
if (QUERY_NODE_CASE_WHEN == nodeType(pNode)) {
return sclWalkCaseWhen(pNode, ctx);
}
sclError("invalid node type for scalar calculating, type:%d", nodeType(pNode));
ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
return DEAL_RES_ERROR;
}
int32_t sclExtendResRows(SScalarParam *pDst, SScalarParam *pSrc, SArray *pBlockList) {
SSDataBlock *pb = taosArrayGetP(pBlockList, 0);
SScalarParam *pLeft = taosMemoryCalloc(1, sizeof(SScalarParam));
if (NULL == pLeft) {
sclError("calloc %d failed", (int32_t)sizeof(SScalarParam));
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
}
pLeft->numOfRows = pb->info.rows;
colInfoDataEnsureCapacity(pDst->columnData, pb->info.rows);
_bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(OP_TYPE_ASSIGN);
OperatorFn(pLeft, pSrc, pDst, TSDB_ORDER_ASC);
taosMemoryFree(pLeft);
return TSDB_CODE_SUCCESS;
}
int32_t sclCalcConstants(SNode *pNode, bool dual, SNode **pRes) {
if (NULL == pNode) {
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
......
......@@ -367,46 +367,45 @@ static FORCE_INLINE void ncharToVar(char *buf, SScalarParam *pOut, int32_t rowIn
taosMemoryFree(t);
}
// TODO opt performance, tmp is not needed.
int32_t vectorConvertFromVarData(const SScalarParam *pIn, SScalarParam *pOut, int32_t inType, int32_t outType,
int32_t *overflow) {
//TODO opt performance, tmp is not needed.
int32_t vectorConvertFromVarData(SSclVectorConvCtx *pCtx, int32_t* overflow) {
bool vton = false;
_bufConverteFunc func = NULL;
if (TSDB_DATA_TYPE_BOOL == outType) {
if (TSDB_DATA_TYPE_BOOL == pCtx->outType) {
func = varToBool;
} else if (IS_SIGNED_NUMERIC_TYPE(outType)) {
} else if (IS_SIGNED_NUMERIC_TYPE(pCtx->outType)) {
func = varToSigned;
} else if (IS_UNSIGNED_NUMERIC_TYPE(outType)) {
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->outType)) {
func = varToUnsigned;
} else if (IS_FLOAT_TYPE(outType)) {
} else if (IS_FLOAT_TYPE(pCtx->outType)) {
func = varToFloat;
} else if (outType == TSDB_DATA_TYPE_BINARY) { // nchar -> binary
ASSERT(inType == TSDB_DATA_TYPE_NCHAR);
} else if (pCtx->outType == TSDB_DATA_TYPE_BINARY) { // nchar -> binary
ASSERT(pCtx->inType == TSDB_DATA_TYPE_NCHAR);
func = ncharToVar;
vton = true;
} else if (outType == TSDB_DATA_TYPE_NCHAR) { // binary -> nchar
ASSERT(inType == TSDB_DATA_TYPE_VARCHAR);
} else if (pCtx->outType == TSDB_DATA_TYPE_NCHAR) { // binary -> nchar
ASSERT(pCtx->inType == TSDB_DATA_TYPE_VARCHAR);
func = varToNchar;
vton = true;
} else if (TSDB_DATA_TYPE_TIMESTAMP == outType) {
} else if (TSDB_DATA_TYPE_TIMESTAMP == pCtx->outType) {
func = varToTimestamp;
} else {
sclError("invalid convert outType:%d", outType);
sclError("invalid convert outType:%d", pCtx->outType);
return TSDB_CODE_QRY_APP_ERROR;
}
pOut->numOfRows = pIn->numOfRows;
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
if (IS_HELPER_NULL(pIn->columnData, i)) {
colDataAppendNULL(pOut->columnData, i);
pCtx->pOut->numOfRows = pCtx->pIn->numOfRows;
for (int32_t i = pCtx->startIndex; i <= pCtx->endIndex; ++i) {
if (IS_HELPER_NULL(pCtx->pIn->columnData, i)) {
colDataAppendNULL(pCtx->pOut->columnData, i);
continue;
}
char *data = colDataGetVarData(pIn->columnData, i);
int32_t convertType = inType;
if (inType == TSDB_DATA_TYPE_JSON) {
if (*data == TSDB_DATA_TYPE_NULL) {
char* data = colDataGetVarData(pCtx->pIn->columnData, i);
int32_t convertType = pCtx->inType;
if(pCtx->inType == TSDB_DATA_TYPE_JSON){
if(*data == TSDB_DATA_TYPE_NULL) {
ASSERT(0);
} else if (*data == TSDB_DATA_TYPE_NCHAR) {
data += CHAR_BYTES;
......@@ -415,13 +414,13 @@ int32_t vectorConvertFromVarData(const SScalarParam *pIn, SScalarParam *pOut, in
terrno = TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR;
return terrno;
} else {
convertNumberToNumber(data + CHAR_BYTES, colDataGetNumData(pOut->columnData, i), *data, outType);
convertNumberToNumber(data+CHAR_BYTES, colDataGetNumData(pCtx->pOut->columnData, i), *data, pCtx->outType);
continue;
}
}
int32_t bufSize = pIn->columnData->info.bytes;
char *tmp = taosMemoryMalloc(varDataTLen(data));
if (!tmp) {
int32_t bufSize = pCtx->pIn->columnData->info.bytes;
char *tmp = taosMemoryMalloc(varDataTLen(data));
if(!tmp){
sclError("out of memory in vectorConvertFromVarData");
return TSDB_CODE_OUT_OF_MEMORY;
}
......@@ -444,8 +443,8 @@ int32_t vectorConvertFromVarData(const SScalarParam *pIn, SScalarParam *pOut, in
tmp[len] = 0;
}
}
(*func)(tmp, pOut, i, overflow);
(*func)(tmp, pCtx->pOut, i, overflow);
taosMemoryFreeClear(tmp);
}
......@@ -581,64 +580,64 @@ bool convertJsonValue(__compar_fn_t *fp, int32_t optr, int8_t typeLeft, int8_t t
return true;
}
int32_t vectorConvertToVarData(const SScalarParam *pIn, SScalarParam *pOut, int16_t inType, int16_t outType) {
SColumnInfoData *pInputCol = pIn->columnData;
SColumnInfoData *pOutputCol = pOut->columnData;
char tmp[128] = {0};
int32_t vectorConvertToVarData(SSclVectorConvCtx *pCtx) {
SColumnInfoData* pInputCol = pCtx->pIn->columnData;
SColumnInfoData* pOutputCol = pCtx->pOut->columnData;
char tmp[128] = {0};
if (IS_SIGNED_NUMERIC_TYPE(inType) || inType == TSDB_DATA_TYPE_BOOL || inType == TSDB_DATA_TYPE_TIMESTAMP) {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inType) || pCtx->inType == TSDB_DATA_TYPE_BOOL || pCtx->inType == TSDB_DATA_TYPE_TIMESTAMP) {
for (int32_t i = pCtx->startIndex; i <= pCtx->endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
int64_t value = 0;
GET_TYPED_DATA(value, int64_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, int64_t, pCtx->inType, colDataGetData(pInputCol, i));
int32_t len = sprintf(varDataVal(tmp), "%" PRId64, value);
varDataLen(tmp) = len;
if (outType == TSDB_DATA_TYPE_NCHAR) {
varToNchar(tmp, pOut, i, NULL);
if (pCtx->outType == TSDB_DATA_TYPE_NCHAR) {
varToNchar(tmp, pCtx->pOut, i, NULL);
} else {
colDataAppend(pOutputCol, i, (char *)tmp, false);
}
}
} else if (IS_UNSIGNED_NUMERIC_TYPE(inType)) {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inType)) {
for (int32_t i = pCtx->startIndex; i <= pCtx->endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
uint64_t value = 0;
GET_TYPED_DATA(value, uint64_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, uint64_t, pCtx->inType, colDataGetData(pInputCol, i));
int32_t len = sprintf(varDataVal(tmp), "%" PRIu64, value);
varDataLen(tmp) = len;
if (outType == TSDB_DATA_TYPE_NCHAR) {
varToNchar(tmp, pOut, i, NULL);
if (pCtx->outType == TSDB_DATA_TYPE_NCHAR) {
varToNchar(tmp, pCtx->pOut, i, NULL);
} else {
colDataAppend(pOutputCol, i, (char *)tmp, false);
}
}
} else if (IS_FLOAT_TYPE(inType)) {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
} else if (IS_FLOAT_TYPE(pCtx->inType)) {
for (int32_t i = pCtx->startIndex; i <= pCtx->endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
double value = 0;
GET_TYPED_DATA(value, double, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, double, pCtx->inType, colDataGetData(pInputCol, i));
int32_t len = sprintf(varDataVal(tmp), "%lf", value);
varDataLen(tmp) = len;
if (outType == TSDB_DATA_TYPE_NCHAR) {
varToNchar(tmp, pOut, i, NULL);
if (pCtx->outType == TSDB_DATA_TYPE_NCHAR) {
varToNchar(tmp, pCtx->pOut, i, NULL);
} else {
colDataAppend(pOutputCol, i, (char *)tmp, false);
}
}
} else {
sclError("not supported input type:%d", inType);
sclError("not supported input type:%d", pCtx->inType);
return TSDB_CODE_QRY_APP_ERROR;
}
......@@ -646,34 +645,35 @@ int32_t vectorConvertToVarData(const SScalarParam *pIn, SScalarParam *pOut, int1
}
// TODO opt performance
int32_t vectorConvertImpl(const SScalarParam *pIn, SScalarParam *pOut, int32_t *overflow) {
SColumnInfoData *pInputCol = pIn->columnData;
SColumnInfoData *pOutputCol = pOut->columnData;
int32_t vectorConvertSingleColImpl(const SScalarParam* pIn, SScalarParam* pOut, int32_t* overflow, int32_t startIndex, int32_t numOfRows) {
SColumnInfoData* pInputCol = pIn->columnData;
SColumnInfoData* pOutputCol = pOut->columnData;
if (NULL == pInputCol) {
sclError("input column is NULL, hashFilter %p", pIn->pHashFilter);
return TSDB_CODE_APP_ERROR;
}
int16_t inType = pInputCol->info.type;
int16_t outType = pOutputCol->info.type;
int32_t rstart = startIndex >= 0 ? startIndex : 0;
int32_t rend = numOfRows > 0 ? rstart + numOfRows - 1 : rstart + pIn->numOfRows - 1;
SSclVectorConvCtx cCtx = {pIn, pOut, rstart, rend, pInputCol->info.type, pOutputCol->info.type};
if (IS_VAR_DATA_TYPE(inType)) {
return vectorConvertFromVarData(pIn, pOut, inType, outType, overflow);
if (IS_VAR_DATA_TYPE(cCtx.inType)) {
return vectorConvertFromVarData(&cCtx, overflow);
}
if (overflow) {
ASSERT(1 == pIn->numOfRows);
pOut->numOfRows = 0;
if (IS_SIGNED_NUMERIC_TYPE(outType)) {
int64_t minValue = tDataTypes[outType].minValue;
int64_t maxValue = tDataTypes[outType].maxValue;
if (IS_SIGNED_NUMERIC_TYPE(cCtx.outType)) {
int64_t minValue = tDataTypes[cCtx.outType].minValue;
int64_t maxValue = tDataTypes[cCtx.outType].maxValue;
double value = 0;
GET_TYPED_DATA(value, double, inType, colDataGetData(pInputCol, 0));
GET_TYPED_DATA(value, double, cCtx.inType, colDataGetData(pInputCol, 0));
if (value > maxValue) {
*overflow = 1;
return TSDB_CODE_SUCCESS;
......@@ -683,13 +683,13 @@ int32_t vectorConvertImpl(const SScalarParam *pIn, SScalarParam *pOut, int32_t *
} else {
*overflow = 0;
}
} else if (IS_UNSIGNED_NUMERIC_TYPE(outType)) {
uint64_t minValue = (uint64_t)tDataTypes[outType].minValue;
uint64_t maxValue = (uint64_t)tDataTypes[outType].maxValue;
} else if (IS_UNSIGNED_NUMERIC_TYPE(cCtx.outType)) {
uint64_t minValue = (uint64_t)tDataTypes[cCtx.outType].minValue;
uint64_t maxValue = (uint64_t)tDataTypes[cCtx.outType].maxValue;
double value = 0;
GET_TYPED_DATA(value, double, inType, colDataGetData(pInputCol, 0));
GET_TYPED_DATA(value, double, cCtx.inType, colDataGetData(pInputCol, 0));
if (value > maxValue) {
*overflow = 1;
return TSDB_CODE_SUCCESS;
......@@ -703,157 +703,157 @@ int32_t vectorConvertImpl(const SScalarParam *pIn, SScalarParam *pOut, int32_t *
}
pOut->numOfRows = pIn->numOfRows;
switch (outType) {
switch (cCtx.outType) {
case TSDB_DATA_TYPE_BOOL: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
bool value = 0;
GET_TYPED_DATA(value, bool, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, bool, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt8(pOutputCol, i, (int8_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_TINYINT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
int8_t value = 0;
GET_TYPED_DATA(value, int8_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, int8_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt8(pOutputCol, i, (int8_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_SMALLINT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
case TSDB_DATA_TYPE_SMALLINT:{
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
int16_t value = 0;
GET_TYPED_DATA(value, int16_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, int16_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt16(pOutputCol, i, (int16_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_INT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
case TSDB_DATA_TYPE_INT:{
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
int32_t value = 0;
GET_TYPED_DATA(value, int32_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, int32_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt32(pOutputCol, i, (int32_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
int64_t value = 0;
GET_TYPED_DATA(value, int64_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, int64_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt64(pOutputCol, i, (int64_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_UTINYINT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
case TSDB_DATA_TYPE_UTINYINT:{
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
uint8_t value = 0;
GET_TYPED_DATA(value, uint8_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, uint8_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt8(pOutputCol, i, (int8_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_USMALLINT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
case TSDB_DATA_TYPE_USMALLINT:{
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
uint16_t value = 0;
GET_TYPED_DATA(value, uint16_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, uint16_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt16(pOutputCol, i, (int16_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_UINT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
case TSDB_DATA_TYPE_UINT:{
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
uint32_t value = 0;
GET_TYPED_DATA(value, uint32_t, inType, colDataGetData(pInputCol, i));
GET_TYPED_DATA(value, uint32_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt32(pOutputCol, i, (int32_t *)&value);
}
break;
}
case TSDB_DATA_TYPE_UBIGINT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
uint64_t value = 0;
GET_TYPED_DATA(value, uint64_t, inType, colDataGetData(pInputCol, i));
colDataAppendInt64(pOutputCol, i, (int64_t *)&value);
GET_TYPED_DATA(value, uint64_t, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendInt64(pOutputCol, i, (int64_t*)&value);
}
break;
}
case TSDB_DATA_TYPE_FLOAT: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
case TSDB_DATA_TYPE_FLOAT:{
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
float value = 0;
GET_TYPED_DATA(value, float, inType, colDataGetData(pInputCol, i));
colDataAppendFloat(pOutputCol, i, (float *)&value);
GET_TYPED_DATA(value, float, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendFloat(pOutputCol, i, (float*)&value);
}
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
for (int32_t i = 0; i < pIn->numOfRows; ++i) {
for (int32_t i = cCtx.startIndex; i <= cCtx.endIndex; ++i) {
if (colDataIsNull_f(pInputCol->nullbitmap, i)) {
colDataAppendNULL(pOutputCol, i);
continue;
}
double value = 0;
GET_TYPED_DATA(value, double, inType, colDataGetData(pInputCol, i));
colDataAppendDouble(pOutputCol, i, (double *)&value);
GET_TYPED_DATA(value, double, cCtx.inType, colDataGetData(pInputCol, i));
colDataAppendDouble(pOutputCol, i, (double*)&value);
}
break;
}
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR: {
return vectorConvertToVarData(pIn, pOut, inType, outType);
return vectorConvertToVarData(&cCtx);
}
default:
sclError("invalid convert output type:%d", outType);
sclError("invalid convert output type:%d", cCtx.outType);
return TSDB_CODE_QRY_APP_ERROR;
}
......@@ -894,7 +894,7 @@ int32_t vectorGetConvertType(int32_t type1, int32_t type2) {
return gConvertTypes[type2][type1];
}
int32_t vectorConvertScalarParam(SScalarParam *input, SScalarParam *output, int32_t type) {
int32_t vectorConvertSingleCol(SScalarParam *input, SScalarParam *output, int32_t type, int32_t startIndex, int32_t numOfRows) {
SDataType t = {.type = type, .bytes = tDataTypes[type].bytes};
output->numOfRows = input->numOfRows;
......@@ -903,17 +903,16 @@ int32_t vectorConvertScalarParam(SScalarParam *input, SScalarParam *output, int3
return TSDB_CODE_OUT_OF_MEMORY;
}
code = vectorConvertImpl(input, output, NULL);
code = vectorConvertSingleColImpl(input, output, NULL, startIndex, numOfRows);
if (code) {
// taosMemoryFreeClear(paramOut1->data);
return code;
}
return TSDB_CODE_SUCCESS;
}
int32_t vectorConvert(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pLeftOut, SScalarParam *pRightOut) {
int32_t leftType = GET_PARAM_TYPE(pLeft);
int32_t vectorConvertCols(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam* pLeftOut, SScalarParam* pRightOut, int32_t startIndex, int32_t numOfRows) {
int32_t leftType = GET_PARAM_TYPE(pLeft);
int32_t rightType = GET_PARAM_TYPE(pRight);
if (leftType == rightType) {
return TSDB_CODE_SUCCESS;
......@@ -941,14 +940,14 @@ int32_t vectorConvert(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p
}
if (type != GET_PARAM_TYPE(param1)) {
code = vectorConvertScalarParam(param1, paramOut1, type);
code = vectorConvertSingleCol(param1, paramOut1, type, startIndex, numOfRows);
if (code) {
return code;
}
}
if (type != GET_PARAM_TYPE(param2)) {
code = vectorConvertScalarParam(param2, paramOut2, type);
code = vectorConvertSingleCol(param2, paramOut2, type, startIndex, numOfRows);
if (code) {
return code;
}
......@@ -962,31 +961,6 @@ enum {
VECTOR_UN_CONVERT = 0x2,
};
static int32_t doConvertHelper(SScalarParam *pDest, int32_t *convert, const SScalarParam *pParam, int32_t type) {
SColumnInfoData *pCol = pParam->columnData;
if (IS_VAR_DATA_TYPE(pCol->info.type) && pCol->info.type != TSDB_DATA_TYPE_JSON) {
pDest->numOfRows = pParam->numOfRows;
SDataType t = {.type = type, .bytes = tDataTypes[type].bytes};
int32_t code = sclCreateColumnInfoData(&t, pParam->numOfRows, pDest);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
code = vectorConvertImpl(pParam, pDest, NULL);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
*convert = VECTOR_DO_CONVERT;
} else {
*convert = VECTOR_UN_CONVERT;
}
return TSDB_CODE_SUCCESS;
}
// TODO not correct for descending order scan
static void vectorMathAddHelper(SColumnInfoData *pLeftCol, SColumnInfoData *pRightCol, SColumnInfoData *pOutputCol,
int32_t numOfRows, int32_t step, int32_t i) {
......@@ -1030,20 +1004,25 @@ static void vectorMathTsAddHelper(SColumnInfoData *pLeftCol, SColumnInfoData *pR
}
}
static SColumnInfoData *doVectorConvert(SScalarParam *pInput, int32_t *doConvert) {
SScalarParam convertParam = {0};
static SColumnInfoData* vectorConvertVarToDouble(SScalarParam* pInput, int32_t* converted) {
SScalarParam output = {0};
SColumnInfoData* pCol = pInput->columnData;
int32_t code = doConvertHelper(&convertParam, doConvert, pInput, TSDB_DATA_TYPE_DOUBLE);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
return NULL;
}
if (IS_VAR_DATA_TYPE(pCol->info.type) && pCol->info.type != TSDB_DATA_TYPE_JSON) {
int32_t code = vectorConvertSingleCol(pInput, &output, TSDB_DATA_TYPE_DOUBLE, -1, -1);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
return NULL;
}
if (*doConvert == VECTOR_DO_CONVERT) {
return convertParam.columnData;
} else {
return pInput->columnData;
*converted = VECTOR_DO_CONVERT;
return output.columnData;
}
*converted = VECTOR_UN_CONVERT;
return pInput->columnData;
}
static void doReleaseVec(SColumnInfoData *pCol, int32_t type) {
......@@ -1061,9 +1040,9 @@ void vectorMathAdd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
SColumnInfoData *pRightCol = doVectorConvert(pRight, &rightConvert);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
SColumnInfoData *pRightCol = vectorConvertVarToDouble(pRight, &rightConvert);
if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pRight))) ||
(GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP && IS_INTEGER_TYPE(GET_PARAM_TYPE(pLeft))) ||
......@@ -1168,9 +1147,9 @@ void vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
SColumnInfoData *pRightCol = doVectorConvert(pRight, &rightConvert);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
SColumnInfoData *pRightCol = vectorConvertVarToDouble(pRight, &rightConvert);
if ((GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP && GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_BIGINT) ||
(GET_PARAM_TYPE(pRight) == TSDB_DATA_TYPE_TIMESTAMP &&
......@@ -1246,9 +1225,9 @@ void vectorMathMultiply(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
SColumnInfoData *pRightCol = doVectorConvert(pRight, &rightConvert);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
SColumnInfoData *pRightCol = vectorConvertVarToDouble(pRight, &rightConvert);
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeftCol->info.type);
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRightCol->info.type);
......@@ -1279,9 +1258,9 @@ void vectorMathDivide(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
SColumnInfoData *pRightCol = doVectorConvert(pRight, &rightConvert);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
SColumnInfoData *pRightCol = vectorConvertVarToDouble(pRight, &rightConvert);
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeftCol->info.type);
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRightCol->info.type);
......@@ -1333,9 +1312,9 @@ void vectorMathRemainder(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
SColumnInfoData *pRightCol = doVectorConvert(pRight, &rightConvert);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
SColumnInfoData *pRightCol = vectorConvertVarToDouble(pRight, &rightConvert);
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeftCol->info.type);
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRightCol->info.type);
......@@ -1412,8 +1391,8 @@ void vectorMathMinus(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pO
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : (pLeft->numOfRows - 1);
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t leftConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
int32_t leftConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeftCol->info.type);
......@@ -1525,9 +1504,9 @@ void vectorBitAnd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut,
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
SColumnInfoData *pRightCol = doVectorConvert(pRight, &rightConvert);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
SColumnInfoData *pRightCol = vectorConvertVarToDouble(pRight, &rightConvert);
_getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeftCol->info.type);
_getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRightCol->info.type);
......@@ -1579,9 +1558,9 @@ void vectorBitOr(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut,
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = doVectorConvert(pLeft, &leftConvert);
SColumnInfoData *pRightCol = doVectorConvert(pRight, &rightConvert);
int32_t leftConvert = 0, rightConvert = 0;
SColumnInfoData *pLeftCol = vectorConvertVarToDouble(pLeft, &leftConvert);
SColumnInfoData *pRightCol = vectorConvertVarToDouble(pRight, &rightConvert);
_getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeftCol->info.type);
_getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRightCol->info.type);
......@@ -1605,8 +1584,8 @@ void vectorBitOr(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut,
doReleaseVec(pRightCol, rightConvert);
}
int32_t doVectorCompareImpl(int32_t numOfRows, SScalarParam *pOut, int32_t startIndex, int32_t step, __compar_fn_t fp,
SScalarParam *pLeft, SScalarParam *pRight, int32_t optr) {
int32_t doVectorCompareImpl(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
int32_t step, __compar_fn_t fp, int32_t optr) {
int32_t num = 0;
for (int32_t i = startIndex; i < numOfRows && i >= 0; i += step) {
......@@ -1659,20 +1638,29 @@ int32_t doVectorCompareImpl(int32_t numOfRows, SScalarParam *pOut, int32_t start
return num;
}
void vectorCompareImpl(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t _ord, int32_t optr) {
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
void doVectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
int32_t _ord, int32_t optr) {
int32_t i = 0;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
int32_t lType = GET_PARAM_TYPE(pLeft);
int32_t rType = GET_PARAM_TYPE(pRight);
__compar_fn_t fp = NULL;
int32_t compRows = 0;
if (lType == rType) {
fp = filterGetCompFunc(lType, optr);
} else {
fp = filterGetCompFuncEx(lType, rType, optr);
}
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
if (startIndex < 0) {
i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->numOfRows, pRight->numOfRows) - 1;
pOut->numOfRows = TMAX(pLeft->numOfRows, pRight->numOfRows);
compRows = pOut->numOfRows;
} else {
compRows = startIndex + numOfRows;
i = startIndex;
}
if (pRight->pHashFilter != NULL) {
for (; i >= 0 && i < pLeft->numOfRows; i += step) {
......@@ -1690,13 +1678,14 @@ void vectorCompareImpl(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *
}
}
} else { // normal compare
pOut->numOfQualified = doVectorCompareImpl(pOut->numOfRows, pOut, i, step, fp, pLeft, pRight, optr);
pOut->numOfQualified = doVectorCompareImpl(pLeft, pRight, pOut, i, compRows, step, fp, optr);
}
}
void vectorCompare(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t _ord, int32_t optr) {
SScalarParam pLeftOut = {0};
SScalarParam pRightOut = {0};
void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t startIndex, int32_t numOfRows,
int32_t _ord, int32_t optr) {
SScalarParam pLeftOut = {0};
SScalarParam pRightOut = {0};
SScalarParam *param1 = NULL;
SScalarParam *param2 = NULL;
......@@ -1704,7 +1693,7 @@ void vectorCompare(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut
param1 = pLeft;
param2 = pRight;
} else {
vectorConvert(pLeft, pRight, &pLeftOut, &pRightOut);
vectorConvertCols(pLeft, pRight, &pLeftOut, &pRightOut, startIndex, numOfRows);
if (pLeftOut.columnData != NULL) {
param1 = &pLeftOut;
......@@ -1719,12 +1708,17 @@ void vectorCompare(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut
}
}
vectorCompareImpl(param1, param2, pOut, _ord, optr);
doVectorCompare(param1, param2, pOut, startIndex, numOfRows, _ord, optr);
sclFreeParam(&pLeftOut);
sclFreeParam(&pRightOut);
}
void vectorGreater(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t _ord) {
void vectorCompare(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord, int32_t optr) {
vectorCompareImpl(pLeft, pRight, pOut, -1, -1, _ord, optr);
}
void vectorGreater(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord) {
vectorCompare(pLeft, pRight, pOut, _ord, OP_TYPE_GREATER_THAN);
}
......@@ -1788,10 +1782,10 @@ void vectorNotNull(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut
pOut->numOfRows = pLeft->numOfRows;
}
void vectorIsTrue(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t _ord) {
vectorConvertImpl(pLeft, pOut, NULL);
for (int32_t i = 0; i < pOut->numOfRows; ++i) {
if (colDataIsNull_s(pOut->columnData, i)) {
void vectorIsTrue(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, int32_t _ord) {
vectorConvertSingleColImpl(pLeft, pOut, NULL, -1, -1);
for(int32_t i = 0; i < pOut->numOfRows; ++i) {
if(colDataIsNull_s(pOut->columnData, i)) {
int8_t v = 0;
colDataAppendInt8(pOut->columnData, i, &v);
colDataSetNotNull_f(pOut->columnData->nullbitmap, i);
......
......@@ -352,6 +352,7 @@
./test.sh -f tsim/scalar/in.sim
./test.sh -f tsim/scalar/scalar.sim
./test.sh -f tsim/scalar/filter.sim
./test.sh -f tsim/scalar/caseWhen.sim
# ---- alter ----
./test.sh -f tsim/alter/cached_schema_after_alter.sim
......
system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
system sh/exec.sh -n dnode1 -s start
sql connect
print ======== prepare data
sql drop database if exists db1;
sql create database db1 vgroups 5;
sql use db1;
sql create stable sta (ts timestamp, f1 int, f2 binary(10), f3 bool) tags(t1 int, t2 bool, t3 binary(10));
sql create table tba1 using sta tags(0, false, '0');
sql create table tba2 using sta tags(1, true, '1');
sql create table tba3 using sta tags(null, null, '');
sql create table tba4 using sta tags(1, false, null);
sql create table tba5 using sta tags(3, true, 'aa');
sql insert into tba1 values ('2022-09-26 15:15:01', 0, "a", false);
sql insert into tba1 values ('2022-09-26 15:15:02', 1, "0", true);
sql insert into tba1 values ('2022-09-26 15:15:03', 5, "5", false);
sql insert into tba1 values ('2022-09-26 15:15:04', null, null, null);
sql insert into tba2 values ('2022-09-27 15:15:01', 0, "a", false);
sql insert into tba2 values ('2022-09-27 15:15:02', 1, "0", true);
sql insert into tba2 values ('2022-09-27 15:15:03', 5, "5", false);
sql insert into tba2 values ('2022-09-27 15:15:04', null, null, null);
sql insert into tba3 values ('2022-09-28 15:15:01', 0, "a", false);
sql insert into tba3 values ('2022-09-28 15:15:02', 1, "0", true);
sql insert into tba3 values ('2022-09-28 15:15:03', 5, "5", false);
sql insert into tba3 values ('2022-09-28 15:15:04', null, null, null);
sql insert into tba4 values ('2022-09-29 15:15:01', 0, "a", false);
sql insert into tba4 values ('2022-09-29 15:15:02', 1, "0", true);
sql insert into tba4 values ('2022-09-29 15:15:03', 5, "5", false);
sql insert into tba4 values ('2022-09-29 15:15:04', null, null, null);
sql insert into tba5 values ('2022-09-30 15:15:01', 0, "a", false);
sql insert into tba5 values ('2022-09-30 15:15:02', 1, "0", true);
sql insert into tba5 values ('2022-09-30 15:15:03', 5, "5", false);
sql insert into tba5 values ('2022-09-30 15:15:04', null, null, null);
print ======== case when xx
sql select case when 3 then 4 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 4 then
return -1
endi
if $data10 != 4 then
return -1
endi
if $data20 != 4 then
return -1
endi
if $data30 != 4 then
return -1
endi
sql select case when 0 then 4 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when null then 4 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when 1 then 4+1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 5.000000000 then
return -1
endi
if $data10 != 5.000000000 then
return -1
endi
if $data20 != 5.000000000 then
return -1
endi
if $data30 != 5.000000000 then
return -1
endi
sql select case when 1-1 then 0 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when 1+1 then 0 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 0 then
return -1
endi
if $data10 != 0 then
return -1
endi
if $data20 != 0 then
return -1
endi
if $data30 != 0 then
return -1
endi
sql select case when 1 then 1-1+2 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 2.000000000 then
return -1
endi
if $data10 != 2.000000000 then
return -1
endi
if $data20 != 2.000000000 then
return -1
endi
if $data30 != 2.000000000 then
return -1
endi
sql select case when 1 > 0 then 1 < 2 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select case when 1 > 2 then 1 < 2 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when abs(3) then abs(-1) end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select case when abs(1+1) then abs(-1)+abs(3) end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 4.000000000 then
return -1
endi
if $data10 != 4.000000000 then
return -1
endi
if $data20 != 4.000000000 then
return -1
endi
if $data30 != 4.000000000 then
return -1
endi
sql select case when 0 then 1 else 3 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 3 then
return -1
endi
if $data10 != 3 then
return -1
endi
if $data20 != 3 then
return -1
endi
if $data30 != 3 then
return -1
endi
sql select case when 0 then 1 when 1 then 0 else 3 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 0 then
return -1
endi
if $data10 != 0 then
return -1
endi
if $data20 != 0 then
return -1
endi
if $data30 != 0 then
return -1
endi
sql select case when 0 then 1 when 1 then 0 when 2 then 3 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 0 then
return -1
endi
if $data10 != 0 then
return -1
endi
if $data20 != 0 then
return -1
endi
if $data30 != 0 then
return -1
endi
sql select case when 'a' then 'b' when null then 0 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when '2' then 'b' when null then 0 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != b then
return -1
endi
if $data10 != b then
return -1
endi
if $data20 != b then
return -1
endi
if $data30 != b then
return -1
endi
sql select case when 0 then 'b' else null end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when 0 then 'b' else 2 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 2 then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != 2 then
return -1
endi
sql select case when sum(2) then sum(2)-sum(1) end from tba1;
if $rows != 1 then
return -1
endi
if $data00 != 4.000000000 then
return -1
endi
sql select case when sum(2) then abs(-2) end from tba1;
if $rows != 1 then
return -1
endi
if $data00 != 2 then
return -1
endi
sql select case when ts then ts end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != @22-09-26 15:15:01.000@ then
return -1
endi
if $data10 != @22-09-26 15:15:02.000@ then
return -1
endi
if $data20 != @22-09-26 15:15:03.000@ then
return -1
endi
if $data30 != @22-09-26 15:15:04.000@ then
return -1
endi
sql select case when f1 then ts end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != @22-09-26 15:15:02.000@ then
return -1
endi
if $data20 != @22-09-26 15:15:03.000@ then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when f1 then f1 when f1 + 1 then f1 + 1 else f1 is null end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 5 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select case when f1 then 3 when ts then ts end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1664176501000 then
return -1
endi
if $data10 != 3 then
return -1
endi
if $data20 != 3 then
return -1
endi
if $data30 != 1664176504000 then
return -1
endi
sql select case when 3 then f1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 0 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 5 then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case when f1 then 3 when 1 then 2 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 3 then
return -1
endi
if $data20 != 3 then
return -1
endi
if $data30 != 2 then
return -1
endi
sql select case when sum(f1) then sum(f1)-abs(-1) end from tba1;
if $rows != 1 then
return -1
endi
if $data00 != 5.000000000 then
return -1
endi
sql select case when sum(f1) then sum(f1)-abs(f1) end from tba1 group by f1 order by f1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != 0.000000000 then
return -1
endi
if $data30 != 0.000000000 then
return -1
endi
sql select case when f1 then sum(f1) when f1 is not null then 9 else 8 end from tba1 group by f1 order by f1;
if $rows != 4 then
return -1
endi
if $data00 != 8 then
return -1
endi
if $data10 != 9 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 5 then
return -1
endi
sql select f1 from tba1 where f1 > case when f1 then 0 else 3 end;
if $rows != 2 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 5 then
return -1
endi
sql select f1 from tba1 where ts > case when ts then ts end;
if $rows != 0 then
return -1
endi
sql select sum(f1),count(f1) from tba1 partition by case when f1 then f1 when 1 then 1 end;
if $rows != 2 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 2 then
return -1
endi
if $data10 != 5 then
return -1
endi
if $data11 != 1 then
return -1
endi
sql select case when f1 < 3 then 1 when f1 >= 3 then 2 else 3 end caseWhen, sum(f1),count(f1) from tba1 group by case when f1 < 3 then 1 when f1 >= 3 then 2 else 3 end order by caseWhen;
if $rows != 3 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 1 then
return -1
endi
if $data02 != 2 then
return -1
endi
if $data10 != 2 then
return -1
endi
if $data11 != 5 then
return -1
endi
if $data12 != 1 then
return -1
endi
if $data20 != 3 then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data22 != 0 then
return -1
endi
sql select f1 from tba1 order by case when f1 <= 0 then 3 when f1 = 1 then 4 when f1 >= 3 then 2 else 1 end desc;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 0 then
return -1
endi
if $data20 != 5 then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select cast(case f1 when f1 then f1 + 1 else f1 is null end as double) from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1.000000000 then
return -1
endi
if $data10 != 2.000000000 then
return -1
endi
if $data20 != 6.000000000 then
return -1
endi
if $data30 != 1.000000000 then
return -1
endi
sql select sum(case f1 when f1 then f1 + 1 else f1 is null end + 1) from tba1;
if $rows != 1 then
return -1
endi
if $data00 != 14.000000000 then
return -1
endi
sql select case when f1 < 3 then 1 when f1 >= 3 then 2 else 3 end,sum(f1),count(f1) from tba1 state_window(case when f1 < 3 then 1 when f1 >= 3 then 2 else 3 end);
if $rows != 3 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 1 then
return -1
endi
if $data02 != 2 then
return -1
endi
if $data10 != 2 then
return -1
endi
if $data11 != 5 then
return -1
endi
if $data12 != 1 then
return -1
endi
if $data20 != 3 then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data22 != 0 then
return -1
endi
sql select f1 from tba1 where case when case when f1 <= 0 then 3 when f1 = 1 then 4 when f1 >= 3 then 2 else 1 end > 2 then 1 else 0 end > 0;
if $rows != 2 then
return -1
endi
if $data00 != 0 then
return -1
endi
if $data10 != 1 then
return -1
endi
sql select case when f1 is not null then case when f1 <= 0 then f1 else f1 * 10 end else -1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 0 then
return -1
endi
if $data10 != 10 then
return -1
endi
if $data20 != 50 then
return -1
endi
if $data30 != -1 then
return -1
endi
print ======== case xx when xx
sql select case 3 when 3 then 4 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 4 then
return -1
endi
if $data10 != 4 then
return -1
endi
if $data20 != 4 then
return -1
endi
if $data30 != 4 then
return -1
endi
sql select case 3 when 1 then 4 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case 3 when 1 then 4 else 2 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 2 then
return -1
endi
if $data10 != 2 then
return -1
endi
if $data20 != 2 then
return -1
endi
if $data30 != 2 then
return -1
endi
sql select case 3 when null then 4 when '3' then 1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select case '3' when null then 4 when 3 then 1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select case null when null then 4 when 3 then 1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != NULL then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case 3.0 when null then 4 when '3' then 1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data30 != 1 then
return -1
endi
sql select case f2 when 'a' then 4 when '0' then 1 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 4 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case f2 when f1 then f1 when f1 - 1 then f1 else 99 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 0 then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data20 != 5 then
return -1
endi
if $data30 != 99 then
return -1
endi
sql select case cast(f2 as int) when 0 then f2 when f1 then 11 else ts end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != a then
return -1
endi
if $data10 != 0 then
return -1
endi
if $data20 != 11 then
return -1
endi
if $data30 != 1664176504 then
return -1
endi
sql select case f1 + 1 when 1 then 1 when 2 then 2 else 3 end from tba1;
if $rows != 4 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data10 != 2 then
return -1
endi
if $data20 != 3 then
return -1
endi
if $data30 != 3 then
return -1
endi
sql select case f1 when sum(f1) then sum(f1)-abs(f1) end from tba1 group by f1 order by f1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != 0.000000000 then
return -1
endi
if $data20 != 0.000000000 then
return -1
endi
if $data30 != 0.000000000 then
return -1
endi
sql select f1, case sum(f1) when 1 then f1 + 99 when f1 then f1 -99 else f1 end from tba1 group by f1 order by f1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data01 != NULL then
return -1
endi
if $data10 != 0 then
return -1
endi
if $data11 != -99.000000000 then
return -1
endi
if $data20 != 1 then
return -1
endi
if $data21 != 100.000000000 then
return -1
endi
if $data30 != 5 then
return -1
endi
if $data31 != -94.000000000 then
return -1
endi
sql select case when 3 then 4 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 0 then 4 end from sta;
if $rows != 20 then
return -1
endi
sql select case when null then 4 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 1 then 4+1 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 1-1 then 0 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 1+1 then 0 end from sta;
if $rows != 20 then
return -1
endi
sql select case when abs(3) then abs(-1) end from sta;
if $rows != 20 then
return -1
endi
sql select case when abs(1+1) then abs(-1)+abs(3) end from sta;
if $rows != 20 then
return -1
endi
sql select case when 0 then 1 else 3 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 0 then 1 when 1 then 0 else 3 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 0 then 1 when 1 then 0 when 2 then 3 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 'a' then 'b' when null then 0 end from sta;
if $rows != 20 then
return -1
endi
sql select case when '2' then 'b' when null then 0 end from sta;
if $rows != 20 then
return -1
endi
sql select case when 0 then 'b' else null end from sta;
if $rows != 20 then
return -1
endi
sql select case when 0 then 'b' else 2+abs(-2) end from sta;
if $rows != 20 then
return -1
endi
sql select case 3 when 3 then 4 end from sta;
if $rows != 20 then
return -1
endi
sql select case 3 when 1 then 4 end from sta;
if $rows != 20 then
return -1
endi
sql select case 3 when 1 then 4 else 2 end from sta;
if $rows != 20 then
return -1
endi
sql select case 3 when null then 4 when '3' then 1 end from sta;
if $rows != 20 then
return -1
endi
sql select case null when null then 4 when 3 then 1 end from sta;
if $rows != 20 then
return -1
endi
sql select case 3.0 when null then 4 when '3' then 1 end from sta;
if $rows != 20 then
return -1
endi
sql select f2,case f2 when 'a' then 4 when '0' then 1 end from sta order by f2;
if $rows != 20 then
return -1
endi
sql select f2,f1,case f2 when f1 then f1 when f1 - 1 then f1 else 99 end from sta order by f2;
if $rows != 20 then
return -1
endi
sql select case cast(f2 as int) when 0 then f2 when f1 then 11 else ts end from sta;
if $rows != 20 then
return -1
endi
sql select f1, case f1 + 1 when 1 then 1 when 2 then 2 else 3 end from sta order by f1;
if $rows != 20 then
return -1
endi
sql select case f1 when sum(f1) then sum(f1)-abs(f1) end from sta group by f1 order by f1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != 0.000000000 then
return -1
endi
if $data20 != NULL then
return -1
endi
if $data30 != NULL then
return -1
endi
sql select case sum(f1) when 1 then f1 + 99 when f1 then f1 -99 else f1 end from sta group by f1 order by f1;
if $rows != 4 then
return -1
endi
if $data00 != NULL then
return -1
endi
if $data10 != -99.000000000 then
return -1
endi
if $data20 != 1.000000000 then
return -1
endi
if $data30 != 5.000000000 then
return -1
endi
sql select distinct tbname, case t1 when t2 then t1 else t1 + 100 end from sta order by tbname;
if $rows != 5 then
return -1
endi
if $data01 != 0 then
return -1
endi
if $data11 != 1 then
return -1
endi
if $data21 != NULL then
return -1
endi
if $data31 != 101 then
return -1
endi
if $data41 != 103 then
return -1
endi
sql_error select case when sum(f1) then sum(f1)-abs(f1) end from tba1;
system sh/exec.sh -n dnode1 -s stop -x SIGINT
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册