feat(query): support now()/today() function in select clause
TD-14243
This commit is contained in:
parent
b355e2b3c8
commit
ca3ce404af
|
@ -78,6 +78,8 @@ int32_t toISO8601Function(SScalarParam *pInput, int32_t inputNum, SScalarParam *
|
||||||
int32_t toUnixtimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t toUnixtimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
|
int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
|
int32_t todayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||||
|
|
||||||
bool getTimePseudoFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getTimePseudoFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
|
|
||||||
|
|
|
@ -433,6 +433,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.sprocessFunc = timeDiffFunction,
|
.sprocessFunc = timeDiffFunction,
|
||||||
.finalizeFunc = NULL
|
.finalizeFunc = NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "now",
|
||||||
|
.type = FUNCTION_TYPE_NOW,
|
||||||
|
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC,
|
||||||
|
.checkFunc = checkAndGetResultType,
|
||||||
|
.getEnvFunc = NULL,
|
||||||
|
.initFunc = NULL,
|
||||||
|
.sprocessFunc = nowFunction,
|
||||||
|
.finalizeFunc = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "today",
|
||||||
|
.type = FUNCTION_TYPE_TODAY,
|
||||||
|
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC,
|
||||||
|
.checkFunc = checkAndGetResultType,
|
||||||
|
.getEnvFunc = NULL,
|
||||||
|
.initFunc = NULL,
|
||||||
|
.sprocessFunc = todayFunction,
|
||||||
|
.finalizeFunc = NULL
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "_rowts",
|
.name = "_rowts",
|
||||||
.type = FUNCTION_TYPE_ROWTS,
|
.type = FUNCTION_TYPE_ROWTS,
|
||||||
|
@ -503,16 +523,6 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.sprocessFunc = winDurFunction,
|
.sprocessFunc = winDurFunction,
|
||||||
.finalizeFunc = NULL
|
.finalizeFunc = NULL
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.name = "now",
|
|
||||||
.type = FUNCTION_TYPE_NOW,
|
|
||||||
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC,
|
|
||||||
.checkFunc = checkAndGetResultType,
|
|
||||||
.getEnvFunc = getTimePseudoFuncEnv,
|
|
||||||
.initFunc = NULL,
|
|
||||||
.sprocessFunc = winDurFunction,
|
|
||||||
.finalizeFunc = NULL
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32_t funcMgtBuiltinsNum = (sizeof(funcMgtBuiltins) / sizeof(SBuiltinFuncDefinition));
|
const int32_t funcMgtBuiltinsNum = (sizeof(funcMgtBuiltins) / sizeof(SBuiltinFuncDefinition));
|
||||||
|
@ -672,7 +682,8 @@ int32_t checkAndGetResultType(SFunctionNode* pFunc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case FUNCTION_TYPE_NOW:
|
case FUNCTION_TYPE_NOW:
|
||||||
// todo
|
case FUNCTION_TYPE_TODAY:
|
||||||
|
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes, .type = TSDB_DATA_TYPE_TIMESTAMP};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(0); // to found the fault ASAP.
|
ASSERT(0); // to found the fault ASAP.
|
||||||
|
|
|
@ -93,6 +93,7 @@ SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pL
|
||||||
SNode* createBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
|
SNode* createBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
|
||||||
SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
|
SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
|
||||||
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList);
|
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList);
|
||||||
|
SNode* createFunctionNodeNoParam(SAstCreateContext* pCxt, const SToken* pFuncName);
|
||||||
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
|
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
|
||||||
SNode* createNodeListNodeEx(SAstCreateContext* pCxt, SNode* p1, SNode* p2);
|
SNode* createNodeListNodeEx(SAstCreateContext* pCxt, SNode* p1, SNode* p2);
|
||||||
SNode* createRealTableNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pTableName, SToken* pTableAlias);
|
SNode* createRealTableNode(SAstCreateContext* pCxt, SToken* pDbName, SToken* pTableName, SToken* pTableAlias);
|
||||||
|
|
|
@ -503,6 +503,8 @@ column_name(A) ::= NK_ID(B).
|
||||||
function_name(A) ::= NK_ID(B). { A = B; }
|
function_name(A) ::= NK_ID(B). { A = B; }
|
||||||
function_name(A) ::= FIRST(B). { A = B; }
|
function_name(A) ::= FIRST(B). { A = B; }
|
||||||
function_name(A) ::= LAST(B). { A = B; }
|
function_name(A) ::= LAST(B). { A = B; }
|
||||||
|
function_name(A) ::= NOW(B). { A = B; }
|
||||||
|
function_name(A) ::= TODAY(B). { A = B; }
|
||||||
|
|
||||||
%type table_alias { SToken }
|
%type table_alias { SToken }
|
||||||
%destructor table_alias { }
|
%destructor table_alias { }
|
||||||
|
@ -535,6 +537,7 @@ expression(A) ::= pseudo_column(B).
|
||||||
expression(A) ::= column_reference(B). { A = B; }
|
expression(A) ::= column_reference(B). { A = B; }
|
||||||
expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
||||||
expression(A) ::= function_name(B) NK_LP NK_STAR(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, createNodeList(pCxt, createColumnNode(pCxt, NULL, &C)))); }
|
expression(A) ::= function_name(B) NK_LP NK_STAR(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, createNodeList(pCxt, createColumnNode(pCxt, NULL, &C)))); }
|
||||||
|
expression(A) ::= function_name(B) NK_LP NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNodeNoParam(pCxt, &B)); }
|
||||||
//for CAST function CAST(expr AS type_name)
|
//for CAST function CAST(expr AS type_name)
|
||||||
expression(A) ::= function_name(B) NK_LP expression(C) AS type_name(D) NK_RP(E). {
|
expression(A) ::= function_name(B) NK_LP expression(C) AS type_name(D) NK_RP(E). {
|
||||||
SNodeList *p = createNodeList(pCxt, releaseRawExprNode(pCxt, C));
|
SNodeList *p = createNodeList(pCxt, releaseRawExprNode(pCxt, C));
|
||||||
|
@ -587,8 +590,8 @@ expression_list(A) ::= expression_list(B) NK_COMMA expression(C).
|
||||||
column_reference(A) ::= column_name(B). { A = createRawExprNode(pCxt, &B, createColumnNode(pCxt, NULL, &B)); }
|
column_reference(A) ::= column_name(B). { A = createRawExprNode(pCxt, &B, createColumnNode(pCxt, NULL, &B)); }
|
||||||
column_reference(A) ::= table_name(B) NK_DOT column_name(C). { A = createRawExprNodeExt(pCxt, &B, &C, createColumnNode(pCxt, &B, &C)); }
|
column_reference(A) ::= table_name(B) NK_DOT column_name(C). { A = createRawExprNodeExt(pCxt, &B, &C, createColumnNode(pCxt, &B, &C)); }
|
||||||
|
|
||||||
pseudo_column(A) ::= NOW(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
//pseudo_column(A) ::= NOW(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
pseudo_column(A) ::= TODAY(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
//pseudo_column(A) ::= TODAY(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
pseudo_column(A) ::= ROWTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
pseudo_column(A) ::= ROWTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
pseudo_column(A) ::= TBNAME(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
pseudo_column(A) ::= TBNAME(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
pseudo_column(A) ::= QSTARTTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
pseudo_column(A) ::= QSTARTTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
|
||||||
|
|
|
@ -367,6 +367,39 @@ SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNod
|
||||||
return (SNode*)func;
|
return (SNode*)func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNode* createFunctionNodeNoParam(SAstCreateContext* pCxt, const SToken* pFuncName) {
|
||||||
|
SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||||
|
CHECK_OUT_OF_MEM(func);
|
||||||
|
char buf[64] = {0};
|
||||||
|
|
||||||
|
int32_t dataType;
|
||||||
|
switch (pFuncName->type) {
|
||||||
|
case TK_NOW: {
|
||||||
|
int64_t ts = taosGetTimestamp(TSDB_TIME_PRECISION_MILLI);
|
||||||
|
snprintf(buf, sizeof(buf), "%"PRId64, ts);
|
||||||
|
dataType = TSDB_DATA_TYPE_BIGINT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TK_TODAY: {
|
||||||
|
int64_t ts = taosGetTimestampToday(TSDB_TIME_PRECISION_MILLI);
|
||||||
|
snprintf(buf, sizeof(buf), "%"PRId64, ts);
|
||||||
|
dataType = TSDB_DATA_TYPE_BIGINT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//case TK_TIMEZONE: {
|
||||||
|
// strncpy(buf, tsTimezoneStr, strlen(tsTimezoneStr));
|
||||||
|
// dataType = TSDB_DATA_TYPE_BINARY;
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
SToken token = {.type = pFuncName->type, .n = strlen(buf), .z = buf};
|
||||||
|
|
||||||
|
SNodeList *pParameterList = createNodeList(pCxt, createValueNode(pCxt, dataType, &token));
|
||||||
|
strncpy(func->functionName, pFuncName->z, pFuncName->n);
|
||||||
|
func->pParameterList = pParameterList;
|
||||||
|
return (SNode*)func;
|
||||||
|
}
|
||||||
|
|
||||||
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList) {
|
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList) {
|
||||||
SNodeListNode* list = (SNodeListNode*)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
SNodeListNode* list = (SNodeListNode*)nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||||
CHECK_OUT_OF_MEM(list);
|
CHECK_OUT_OF_MEM(list);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1242,6 +1242,22 @@ int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
|
||||||
|
if (inputNum != 1) {
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
colDataAppendInt64(pOutput->columnData, pOutput->numOfRows, (int64_t *)colDataGetData(pInput->columnData, 0));
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t todayFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
|
||||||
|
if (inputNum != 1) {
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
colDataAppendInt64(pOutput->columnData, pOutput->numOfRows, (int64_t *)colDataGetData(pInput->columnData, 0));
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t atanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
|
int32_t atanFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
|
||||||
return doScalarFunctionUnique(pInput, inputNum, pOutput, atan);
|
return doScalarFunctionUnique(pInput, inputNum, pOutput, atan);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue