Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enh: cols function #29880

Open
wants to merge 44 commits into
base: 3.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
7964e5e
cols function
facetosea Dec 9, 2024
20f8d17
cols func
facetosea Dec 19, 2024
e26a356
cols function
facetosea Dec 25, 2024
504a8af
fix: select_value function slotid
facetosea Dec 25, 2024
c371fb2
fix: bindTupleFuncindex
facetosea Dec 25, 2024
983431b
cols
facetosea Dec 26, 2024
465f195
fix: cols func
facetosea Dec 27, 2024
de80108
enh: cols func
facetosea Dec 27, 2024
2611eef
fix: mem leak
facetosea Dec 29, 2024
d3fa16b
test
facetosea Dec 29, 2024
d3e86d9
cols
facetosea Dec 30, 2024
772c37b
fix: empty block
facetosea Jan 1, 2025
cb1ed29
error desc in doc
facetosea Jan 2, 2025
9a34af9
build on win
facetosea Jan 2, 2025
908d69f
fxi: alias name is too long
facetosea Jan 3, 2025
8d45b04
test case
facetosea Jan 3, 2025
fa3cd81
parerlog
facetosea Jan 3, 2025
65e0990
merge 3.0
facetosea Jan 23, 2025
b1f1c2e
test case: test cols name
facetosea Jan 23, 2025
7e553f7
fxi: use the same agg func outside of cols
facetosea Jan 23, 2025
fbe345a
fix: cols funcs, sub query
facetosea Feb 5, 2025
b461ec0
fix: ts in subquery
facetosea Feb 5, 2025
6ba3edf
test case
facetosea Feb 6, 2025
3c0121e
unused code
facetosea Feb 11, 2025
fa203ca
cols in stream
facetosea Feb 11, 2025
44f6859
unused code
facetosea Feb 12, 2025
e16b96d
enh: translate cols in clauses
facetosea Feb 13, 2025
a391cc4
cols in order clause
facetosea Feb 13, 2025
26fb867
cols test
facetosea Feb 14, 2025
c4cc51b
cols: use aggfunc
facetosea Feb 15, 2025
9d86f48
fix: select_value node name
facetosea Feb 17, 2025
8a7b633
fix: alias name length
facetosea Feb 17, 2025
00473a9
fix: aliasName too long
facetosea Feb 18, 2025
bd3a36b
rewrite aliasname
facetosea Feb 18, 2025
5c64684
fix: select tbname when use multi select function
facetosea Feb 18, 2025
a29ddcc
fix: rewirte to groupkey func
facetosea Feb 18, 2025
01518aa
fix: result error
facetosea Feb 19, 2025
4a3343a
enh: cols in having clause
facetosea Feb 19, 2025
71bdb6f
nullTuple pos
facetosea Feb 20, 2025
75984e6
fix: group const value
facetosea Feb 20, 2025
d6f05d4
return code
facetosea Feb 20, 2025
d9bbe0d
return code
facetosea Feb 20, 2025
fa61c13
fix: _group_key not select
facetosea Feb 20, 2025
0f951ae
delete nulltuplepos
facetosea Feb 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
cols
  • Loading branch information
facetosea committed Dec 26, 2024
commit 983431bab6ea236f9ecb0d579209de53e4700041
1 change: 0 additions & 1 deletion include/libs/scalar/scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ int32_t sampleScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara
int32_t tailScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t uniqueScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t modeScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t colsScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);

#ifdef __cplusplus
}
Expand Down
5 changes: 0 additions & 5 deletions source/libs/function/inc/builtinsimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,6 @@ int32_t blockDBUsageSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo
int32_t blockDBUsageFunction(SqlFunctionCtx* pCtx);
int32_t blockDBUsageFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);

bool getColsFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
int32_t colsFunction(SqlFunctionCtx* pCtx);
int32_t colsPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
int32_t colsCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);

#ifdef __cplusplus
}
#endif
Expand Down
37 changes: 0 additions & 37 deletions source/libs/function/src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -5653,43 +5653,6 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.outputParaInfo = {.validDataType = FUNC_PARAM_SUPPORT_VARCHAR_TYPE}},
.translateFunc = translateOutVarchar,
},
{
.name = "cols",
.type = FUNCTION_TYPE_COLS,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_SELECT_COLS_FUNC,
.translateFunc = translateCols,
.dynDataRequiredFunc = NULL,
.getEnvFunc = getColsFuncEnv,
.initFunc = functionSetup,
.processFunc = colsFunction,
.sprocessFunc = colsScalarFunction,
.pPartialFunc = "_cols_partial",
.pMergeFunc = "_cols_merge",
.finalizeFunc = NULL
},
{
.name = "_cols_partial",
.type = FUNCTION_TYPE_COLS_PARTIAL,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_SELECT_COLS_FUNC,
.translateFunc = translateCols,
.dynDataRequiredFunc = NULL,
.getEnvFunc = getColsFuncEnv,
.initFunc = functionSetup,
.processFunc = colsFunction,
.finalizeFunc = colsPartialFinalize,
.combineFunc = colsCombine,
},
{
.name = "_cols_merge",
.type = FUNCTION_TYPE_COLS_MERGE,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_SELECT_COLS_FUNC,
.translateFunc = translateOutFirstIn,
.getEnvFunc = getFirstLastFuncEnv,
.initFunc = functionSetup,
.processFunc = lastFunctionMerge,
.finalizeFunc = colsPartialFinalize,
.combineFunc = colsCombine,
},
};
// clang-format on

Expand Down
74 changes: 0 additions & 74 deletions source/libs/function/src/builtinsimpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -7194,77 +7194,3 @@ int32_t cachedLastRowFunction(SqlFunctionCtx* pCtx) {
SET_VAL(pResInfo, numOfElems, 1);
return TSDB_CODE_SUCCESS;
}

bool getColsFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
SColumnNode* pNode = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0);
pEnv->calcMemSize = pNode->node.resType.bytes;
return true;
}

int32_t colsFunction(SqlFunctionCtx* pCtx) {
int32_t code = TSDB_CODE_SUCCESS;
SFunctionNode* pSelectFunc = ((SFunctionNode*)(pCtx[0].pExpr->pExpr->_function.pFunctNode->pParameterList->pHead->pNode));

SFuncExecFuncs selectExecFuncs;
code = fmGetFuncExecFuncs(pCtx->functionId, &selectExecFuncs);
if(TSDB_CODE_SUCCESS != code) {
return code;
}
if(selectExecFuncs.process == NULL) {
return TSDB_CODE_SUCCESS;
}
return selectExecFuncs.process(pCtx);
}

int32_t colsPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
int32_t code = TSDB_CODE_SUCCESS;

SResultRowEntryInfo* pEntryInfo = GET_RES_INFO(pCtx);
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pEntryInfo);

int32_t resultBytes = getFirstLastInfoSize(pRes->bytes, pRes->pkBytes);

// todo check for failure
char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
if (NULL == res) {
return terrno;
}
(void)memcpy(varDataVal(res), pRes, resultBytes);

varDataSetLen(res, resultBytes);

int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
if (NULL == pCol) {
taosMemoryFree(res);
return TSDB_CODE_OUT_OF_RANGE;
}

if (pEntryInfo->numOfRes == 0) {
colDataSetNULL(pCol, pBlock->info.rows);
code = setSelectivityValue(pCtx, pBlock, &pRes->nullTuplePos, pBlock->info.rows);
} else {
code = colDataSetVal(pCol, pBlock->info.rows, res, false);
if (TSDB_CODE_SUCCESS != code) {
taosMemoryFree(res);
return code;
}
code = setSelectivityValue(pCtx, pBlock, &pRes->pos, pBlock->info.rows);
}
taosMemoryFree(res);
return code;
}

int32_t colsCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
SFirstLastRes* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
int32_t bytes = pDBuf->bytes;

SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
SFirstLastRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);

pDBuf->hasResult = firstLastTransferInfoImpl(pSBuf, pDBuf, false);
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
pDResInfo->isNullRes &= pSResInfo->isNullRes;
return TSDB_CODE_SUCCESS;
}
159 changes: 59 additions & 100 deletions source/libs/parser/src/parTranslater.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <stdint.h>
#include "query.h"
#include "querynodes.h"
#include "taoserror.h"
#include "tdatablock.h"

#include "catalog.h"
Expand Down Expand Up @@ -5195,54 +5196,6 @@ static int32_t createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr, SNo
return code;
}

static int32_t createMultiResColsFunc(SFunctionNode* pSrcFunc, SFunctionNode* pSelectFunc, SExprNode* pExpr, SNode** ppNodeOut) {
SFunctionNode* pFunc = NULL;
int32_t code = nodesMakeNode(QUERY_NODE_FUNCTION, (SNode**)&pFunc);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
code = nodesMakeList(&pFunc->pParameterList);
SNode* pClonedFuncNode = NULL;
if (TSDB_CODE_SUCCESS != (code = nodesCloneNode((SNode*)pSelectFunc, &pClonedFuncNode)) ||
TSDB_CODE_SUCCESS != (code = nodesListStrictAppend(pFunc->pParameterList, pClonedFuncNode))) {
nodesDestroyNode((SNode*)pFunc);
return code;
}
SNode* pClonedExprNode = NULL;
if (TSDB_CODE_SUCCESS != (code = nodesCloneNode((SNode*)pExpr, &pClonedExprNode)) ||
TSDB_CODE_SUCCESS != (code = nodesListStrictAppend(pFunc->pParameterList, pClonedExprNode))) {
nodesDestroyNode((SNode*)pFunc);
return code;
}

pFunc->node.resType = pExpr->resType;
pFunc->funcId = pSrcFunc->funcId;
pFunc->funcType = pSrcFunc->funcType;
strcpy(pFunc->functionName, pSrcFunc->functionName);
char buf[TSDB_FUNC_NAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN + TSDB_NAME_DELIMITER_LEN + 3] = {0};
int32_t len = 0;
if(pExpr->asAlias) {
strncpy(pFunc->node.aliasName, pExpr->aliasName, TSDB_COL_NAME_LEN - 1);
strncpy(pFunc->node.userAlias, pExpr->userAlias, TSDB_COL_NAME_LEN - 1);
pFunc->node.asAlias = true;
} else if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
SColumnNode* pCol = (SColumnNode*)pExpr;
len = tsnprintf(buf, sizeof(buf) - 1, "%s.%s", pCol->tableAlias, pCol->colName);
(void)taosHashBinary(buf, len);
strncpy(pFunc->node.aliasName, buf, TSDB_COL_NAME_LEN - 1);
len = tsnprintf(buf, sizeof(buf) - 1, "%s", pCol->colName);
strncpy(pFunc->node.userAlias, buf, TSDB_COL_NAME_LEN - 1);
} else {
len = tsnprintf(buf, sizeof(buf) - 1, "%s(%s)", pSrcFunc->functionName, pExpr->aliasName);
(void)taosHashBinary(buf, len);
strncpy(pFunc->node.aliasName, buf, TSDB_COL_NAME_LEN - 1);
len = tsnprintf(buf, sizeof(buf) - 1, "%s(%s)", pSrcFunc->functionName, pExpr->userAlias);
strncpy(pFunc->node.userAlias, buf, TSDB_COL_NAME_LEN - 1);
}
*ppNodeOut = (SNode*)pFunc;
return code;
}

static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, bool igTags, SNodeList** pOutput) {
STableNode* pTable = NULL;
int32_t code = findTable(pCxt, pCol->tableAlias, &pTable);
Expand Down Expand Up @@ -7345,10 +7298,17 @@ static int32_t translateSelectWithoutFrom(STranslateContext* pCxt, SSelectStmt*
pCxt->dual = true;
return translateExprList(pCxt, pSelect->pProjectionList);
}
typedef struct SCheckColsFuncCxt {
bool hasColsFunc;
bool hasMultiColsFunc;
} SCheckColsFuncCxt;

typedef struct SHasMultiColsFuncCxt {
bool hasMultiColsFunc;
} SHasMultiColsFuncCxt;
static bool isColsFuncByName(SFunctionNode* pFunc) {
if (strcasecmp(pFunc->functionName, "cols") != 0) {
return false;
}
return true;
}

static bool isMultiColsFunc(SFunctionNode* pFunc) {
if (strcasecmp(pFunc->functionName, "cols") != 0) {
Expand All @@ -7358,12 +7318,15 @@ static bool isMultiColsFunc(SFunctionNode* pFunc) {
}

static EDealRes isMultiColsFuncNode(SNode** pNode, void* pContext) {
SHasMultiColsFuncCxt* pCxt = pContext;
SCheckColsFuncCxt* pCxt = pContext;
if (QUERY_NODE_FUNCTION == nodeType(*pNode)) {
SFunctionNode* pFunc = (SFunctionNode*)*pNode;
if (isMultiColsFunc(pFunc)) {
pCxt->hasMultiColsFunc = true;
return DEAL_RES_END;
if (isColsFuncByName(pFunc)) {
pCxt->hasColsFunc = true;
if (pFunc->pParameterList->length > 2) {
pCxt->hasMultiColsFunc = true;
return DEAL_RES_END;
}
}
}
return DEAL_RES_CONTINUE;
Expand All @@ -7384,33 +7347,54 @@ static EDealRes pushDownBindSelectFunc(SNode** pNode, void* pContext) {
return DEAL_RES_CONTINUE;
}

static bool hasMultiColsFuncInList(SNodeList* nodeList) {
SHasMultiColsFuncCxt pCxt = {false};

nodesRewriteExprs(nodeList, isMultiColsFuncNode, &pCxt);

return pCxt.hasMultiColsFunc;
static void checkColsFuncInList(SNodeList* nodeList, SCheckColsFuncCxt* pCheckouColsFuncCxt) {
nodesRewriteExprs(nodeList, isMultiColsFuncNode, pCheckouColsFuncCxt);
return;
}

static bool hasMultiColsFunc(SNode** pNode) {
SHasMultiColsFuncCxt pCxt = {false};

nodesRewriteExpr(pNode, isMultiColsFuncNode, &pCxt);
static void checkColsFunc(SNode** pNode, SCheckColsFuncCxt* pCheckouColsFuncCxt) {
nodesRewriteExpr(pNode, isMultiColsFuncNode, pCheckouColsFuncCxt);
return;
}

return pCxt.hasMultiColsFunc;
static bool invalidColsAlias(SFunctionNode* pFunc) {
if (pFunc->node.asAlias) {
if (pFunc->pParameterList->length > 2) {
return true;
} else {
SNode* pNode;
FOREACH(pNode, pFunc->pParameterList) {
SExprNode* pExpr = (SExprNode*)pNode;
if (pExpr->asAlias) {
return true;
}
}
}
}
return false;
}

static int32_t hasInvalidColsFunction(STranslateContext* pCxt, SNodeList* nodeList) {
static int32_t hasInvalidColsFunction(STranslateContext* pCxt, SNodeList* nodeList,
SCheckColsFuncCxt* pCheckouColsFuncCxt) {
SNode* pTmpNode = NULL;
FOREACH(pTmpNode, nodeList) {
if (QUERY_NODE_FUNCTION == nodeType(pTmpNode)) {
SFunctionNode* pFunc = (SFunctionNode*)pTmpNode;
if (hasMultiColsFuncInList(pFunc->pParameterList)) {
if (isColsFuncByName(pFunc)) {
pCheckouColsFuncCxt->hasColsFunc = true;
if (invalidColsAlias(pFunc)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLS_FUNCTION,
"Invalid using alias for cols function");
}
}
checkColsFuncInList(pFunc->pParameterList, pCheckouColsFuncCxt);
if (pCheckouColsFuncCxt->hasMultiColsFunc) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLS_FUNCTION,
"Invalid cols function in function %s", pFunc->functionName);
}
} else {
if (hasMultiColsFunc(&pTmpNode)) {
checkColsFunc(&pTmpNode, pCheckouColsFuncCxt);
if (pCheckouColsFuncCxt->hasMultiColsFunc) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLS_FUNCTION,
"Invalid cols function, can't be used at here");
}
Expand All @@ -7419,26 +7403,7 @@ static int32_t hasInvalidColsFunction(STranslateContext* pCxt, SNodeList* nodeLi
return TSDB_CODE_SUCCESS;
}

static bool invalidColsAlias(SFunctionNode* pFunc) {
if (strcasecmp(pFunc->functionName, "cols") != 0) {
return false;
}
if (pFunc->node.asAlias) {
if (pFunc->pParameterList->length > 2) {
return true;
} else {
SNode* pNode;
FOREACH(pNode, pFunc->pParameterList) {
SExprNode* pExpr = (SExprNode*)pNode;
if (pExpr->asAlias) {
return true;
}
}
}
}

return false;
}

static int32_t getSelectFuncIndex(SNodeList* FuncNodeList, SNode* pSelectFunc) {
SNode* pNode = NULL;
Expand All @@ -7453,21 +7418,14 @@ static int32_t getSelectFuncIndex(SNodeList* FuncNodeList, SNode* pSelectFunc) {
}

static int32_t rewriteColsFunction(STranslateContext* pCxt, SNodeList** nodeList) {
int32_t code = hasInvalidColsFunction(pCxt, *nodeList);
SCheckColsFuncCxt pCheckouColsFuncCxt = {false, false};
int32_t code = hasInvalidColsFunction(pCxt, *nodeList, &pCheckouColsFuncCxt);
if (TSDB_CODE_SUCCESS != code) {
return code;
}
bool needRewrite = false;
SNode* pTmpNode = NULL;
FOREACH(pTmpNode, *nodeList) {
if (QUERY_NODE_FUNCTION == nodeType(pTmpNode)) {
SFunctionNode* pFunc = (SFunctionNode*)pTmpNode;
if(invalidColsAlias(pFunc)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLS_FUNCTION,
"Invalid using alias for cols function");
}
needRewrite = true;
}
bool needRewrite = false;
if (pCheckouColsFuncCxt.hasColsFunc) {
needRewrite = true;
}

SNodeList* pNewNodeList = NULL;
Expand All @@ -7484,6 +7442,7 @@ static int32_t rewriteColsFunction(STranslateContext* pCxt, SNodeList** nodeList
SNode* pNewNode = NULL;
int32_t nums = 0;
int32_t selectFuncCount = 0;
SNode* pTmpNode = NULL;
FOREACH(pTmpNode, *nodeList) {
if (QUERY_NODE_FUNCTION == nodeType(pTmpNode)) {
SFunctionNode* pFunc = (SFunctionNode*)pTmpNode;
Expand Down
3 changes: 0 additions & 3 deletions source/libs/scalar/src/sclfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4589,6 +4589,3 @@ int32_t modeScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam
return selectScalarFunction(pInput, inputNum, pOutput);
}

int32_t colsScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
return selectScalarFunction(pInput, inputNum, pOutput);
}
Loading