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 timeTruncateFunction(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);
|
||||
|
||||
|
|
|
@ -433,6 +433,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.sprocessFunc = timeDiffFunction,
|
||||
.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",
|
||||
.type = FUNCTION_TYPE_ROWTS,
|
||||
|
@ -503,16 +523,6 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.sprocessFunc = winDurFunction,
|
||||
.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));
|
||||
|
@ -672,7 +682,8 @@ int32_t checkAndGetResultType(SFunctionNode* pFunc) {
|
|||
}
|
||||
|
||||
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;
|
||||
default:
|
||||
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* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, SNode* pRight);
|
||||
SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList);
|
||||
SNode* createFunctionNodeNoParam(SAstCreateContext* pCxt, const SToken* pFuncName);
|
||||
SNode* createNodeListNode(SAstCreateContext* pCxt, SNodeList* pList);
|
||||
SNode* createNodeListNodeEx(SAstCreateContext* pCxt, SNode* p1, SNode* p2);
|
||||
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) ::= FIRST(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 }
|
||||
%destructor table_alias { }
|
||||
|
@ -535,6 +537,7 @@ expression(A) ::= pseudo_column(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 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)
|
||||
expression(A) ::= function_name(B) NK_LP expression(C) AS type_name(D) NK_RP(E). {
|
||||
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) ::= 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) ::= TODAY(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) ::= 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) ::= 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
SNodeListNode* list = (SNodeListNode*)nodesMakeNode(QUERY_NODE_NODE_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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return doScalarFunctionUnique(pInput, inputNum, pOutput, atan);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue