enh: cumulative functions support mixed use
This commit is contained in:
parent
22635992fd
commit
41b8ef7d93
|
@ -157,6 +157,13 @@ typedef enum EFunctionType {
|
||||||
FUNCTION_TYPE_UDF = 10000
|
FUNCTION_TYPE_UDF = 10000
|
||||||
} EFunctionType;
|
} EFunctionType;
|
||||||
|
|
||||||
|
typedef enum EFuncReturnRows {
|
||||||
|
FUNC_RETURN_ROWS_NORMAL = 1,
|
||||||
|
FUNC_RETURN_ROWS_INDEFINITE,
|
||||||
|
FUNC_RETURN_ROWS_N,
|
||||||
|
FUNC_RETURN_ROWS_N_MINUS_1
|
||||||
|
} EFuncReturnRows;
|
||||||
|
|
||||||
struct SqlFunctionCtx;
|
struct SqlFunctionCtx;
|
||||||
struct SResultRowEntryInfo;
|
struct SResultRowEntryInfo;
|
||||||
struct STimeWindow;
|
struct STimeWindow;
|
||||||
|
@ -167,6 +174,8 @@ void fmFuncMgtDestroy();
|
||||||
|
|
||||||
int32_t fmGetFuncInfo(SFunctionNode* pFunc, char* pMsg, int32_t msgLen);
|
int32_t fmGetFuncInfo(SFunctionNode* pFunc, char* pMsg, int32_t msgLen);
|
||||||
|
|
||||||
|
EFuncReturnRows fmGetFuncReturnRows(SFunctionNode* pFunc);
|
||||||
|
|
||||||
bool fmIsBuiltinFunc(const char* pFunc);
|
bool fmIsBuiltinFunc(const char* pFunc);
|
||||||
|
|
||||||
bool fmIsAggFunc(int32_t funcId);
|
bool fmIsAggFunc(int32_t funcId);
|
||||||
|
@ -198,6 +207,7 @@ bool fmIsImplicitTsFunc(int32_t funcId);
|
||||||
bool fmIsClientPseudoColumnFunc(int32_t funcId);
|
bool fmIsClientPseudoColumnFunc(int32_t funcId);
|
||||||
bool fmIsMultiRowsFunc(int32_t funcId);
|
bool fmIsMultiRowsFunc(int32_t funcId);
|
||||||
bool fmIsKeepOrderFunc(int32_t funcId);
|
bool fmIsKeepOrderFunc(int32_t funcId);
|
||||||
|
bool fmIsCumulativeFunc(int32_t funcId);
|
||||||
|
|
||||||
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,7 @@ typedef struct SSelectStmt {
|
||||||
char stmtName[TSDB_TABLE_NAME_LEN];
|
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
int32_t selectFuncNum;
|
int32_t selectFuncNum;
|
||||||
|
int32_t returnRows; // EFuncReturnRows
|
||||||
bool isEmptyResult;
|
bool isEmptyResult;
|
||||||
bool isTimeLineResult;
|
bool isTimeLineResult;
|
||||||
bool isSubquery;
|
bool isSubquery;
|
||||||
|
|
|
@ -26,6 +26,7 @@ typedef int32_t (*FTranslateFunc)(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
||||||
typedef EFuncDataRequired (*FFuncDataRequired)(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
|
typedef EFuncDataRequired (*FFuncDataRequired)(SFunctionNode* pFunc, STimeWindow* pTimeWindow);
|
||||||
typedef int32_t (*FCreateMergeFuncParameters)(SNodeList* pRawParameters, SNode* pPartialRes, SNodeList** pParameters);
|
typedef int32_t (*FCreateMergeFuncParameters)(SNodeList* pRawParameters, SNode* pPartialRes, SNodeList** pParameters);
|
||||||
typedef EFuncDataRequired (*FFuncDynDataRequired)(void* pRes, STimeWindow* pTimeWindow);
|
typedef EFuncDataRequired (*FFuncDynDataRequired)(void* pRes, STimeWindow* pTimeWindow);
|
||||||
|
typedef EFuncReturnRows (*FEstimateReturnRows)(SFunctionNode* pFunc);
|
||||||
|
|
||||||
typedef struct SBuiltinFuncDefinition {
|
typedef struct SBuiltinFuncDefinition {
|
||||||
const char* name;
|
const char* name;
|
||||||
|
@ -44,6 +45,7 @@ typedef struct SBuiltinFuncDefinition {
|
||||||
const char* pPartialFunc;
|
const char* pPartialFunc;
|
||||||
const char* pMergeFunc;
|
const char* pMergeFunc;
|
||||||
FCreateMergeFuncParameters createMergeParaFuc;
|
FCreateMergeFuncParameters createMergeParaFuc;
|
||||||
|
FEstimateReturnRows estimateReturnRowsFunc;
|
||||||
} SBuiltinFuncDefinition;
|
} SBuiltinFuncDefinition;
|
||||||
|
|
||||||
extern const SBuiltinFuncDefinition funcMgtBuiltins[];
|
extern const SBuiltinFuncDefinition funcMgtBuiltins[];
|
||||||
|
|
|
@ -48,6 +48,7 @@ extern "C" {
|
||||||
#define FUNC_MGT_CLIENT_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(19)
|
#define FUNC_MGT_CLIENT_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(19)
|
||||||
#define FUNC_MGT_MULTI_ROWS_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(20)
|
#define FUNC_MGT_MULTI_ROWS_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(20)
|
||||||
#define FUNC_MGT_KEEP_ORDER_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(21)
|
#define FUNC_MGT_KEEP_ORDER_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(21)
|
||||||
|
#define FUNC_MGT_CUMULATIVE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(22)
|
||||||
|
|
||||||
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||||
|
|
||||||
|
|
|
@ -1277,6 +1277,8 @@ static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EFuncReturnRows csumEstReturnRows(SFunctionNode* pFunc) { return FUNC_RETURN_ROWS_N; }
|
||||||
|
|
||||||
static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
if (2 != LIST_LENGTH(pFunc->pParameterList)) {
|
if (2 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
@ -1416,6 +1418,11 @@ static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EFuncReturnRows derivativeEstReturnRows(SFunctionNode* pFunc) {
|
||||||
|
return 1 == ((SValueNode*)nodesListGetNode(pFunc->pParameterList, 2))->datum.i ? FUNC_RETURN_ROWS_INDEFINITE
|
||||||
|
: FUNC_RETURN_ROWS_N_MINUS_1;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateIrate(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
@ -1551,6 +1558,14 @@ static int32_t translateDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EFuncReturnRows diffEstReturnRows(SFunctionNode* pFunc) {
|
||||||
|
if (1 == LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
|
return FUNC_RETURN_ROWS_N_MINUS_1;
|
||||||
|
}
|
||||||
|
return 1 == ((SValueNode*)nodesListGetNode(pFunc->pParameterList, 1))->datum.i ? FUNC_RETURN_ROWS_INDEFINITE
|
||||||
|
: FUNC_RETURN_ROWS_N_MINUS_1;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateLength(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateLength(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
@ -2231,13 +2246,14 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "derivative",
|
.name = "derivative",
|
||||||
.type = FUNCTION_TYPE_DERIVATIVE,
|
.type = FUNCTION_TYPE_DERIVATIVE,
|
||||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC,
|
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC | FUNC_MGT_CUMULATIVE_FUNC,
|
||||||
.translateFunc = translateDerivative,
|
.translateFunc = translateDerivative,
|
||||||
.getEnvFunc = getDerivativeFuncEnv,
|
.getEnvFunc = getDerivativeFuncEnv,
|
||||||
.initFunc = derivativeFuncSetup,
|
.initFunc = derivativeFuncSetup,
|
||||||
.processFunc = derivativeFunction,
|
.processFunc = derivativeFunction,
|
||||||
.sprocessFunc = derivativeScalarFunction,
|
.sprocessFunc = derivativeScalarFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize,
|
||||||
|
.estimateReturnRowsFunc = derivativeEstReturnRows
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "irate",
|
.name = "irate",
|
||||||
|
@ -2436,13 +2452,14 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "diff",
|
.name = "diff",
|
||||||
.type = FUNCTION_TYPE_DIFF,
|
.type = FUNCTION_TYPE_DIFF,
|
||||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC,
|
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC,
|
||||||
.translateFunc = translateDiff,
|
.translateFunc = translateDiff,
|
||||||
.getEnvFunc = getDiffFuncEnv,
|
.getEnvFunc = getDiffFuncEnv,
|
||||||
.initFunc = diffFunctionSetup,
|
.initFunc = diffFunctionSetup,
|
||||||
.processFunc = diffFunction,
|
.processFunc = diffFunction,
|
||||||
.sprocessFunc = diffScalarFunction,
|
.sprocessFunc = diffScalarFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize,
|
||||||
|
.estimateReturnRowsFunc = diffEstReturnRows
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "statecount",
|
.name = "statecount",
|
||||||
|
@ -2469,13 +2486,14 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "csum",
|
.name = "csum",
|
||||||
.type = FUNCTION_TYPE_CSUM,
|
.type = FUNCTION_TYPE_CSUM,
|
||||||
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC,
|
.classification = FUNC_MGT_INDEFINITE_ROWS_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC | FUNC_MGT_CUMULATIVE_FUNC,
|
||||||
.translateFunc = translateCsum,
|
.translateFunc = translateCsum,
|
||||||
.getEnvFunc = getCsumFuncEnv,
|
.getEnvFunc = getCsumFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
.processFunc = csumFunction,
|
.processFunc = csumFunction,
|
||||||
.sprocessFunc = csumScalarFunction,
|
.sprocessFunc = csumScalarFunction,
|
||||||
.finalizeFunc = NULL
|
.finalizeFunc = NULL,
|
||||||
|
.estimateReturnRowsFunc = csumEstReturnRows,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "mavg",
|
.name = "mavg",
|
||||||
|
|
|
@ -89,6 +89,14 @@ int32_t fmGetFuncInfo(SFunctionNode* pFunc, char* pMsg, int32_t msgLen) {
|
||||||
return TSDB_CODE_FUNC_NOT_BUILTIN_FUNTION;
|
return TSDB_CODE_FUNC_NOT_BUILTIN_FUNTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EFuncReturnRows fmGetFuncReturnRows(SFunctionNode* pFunc) {
|
||||||
|
if (NULL != funcMgtBuiltins[pFunc->funcId].estimateReturnRowsFunc) {
|
||||||
|
return funcMgtBuiltins[pFunc->funcId].estimateReturnRowsFunc(pFunc);
|
||||||
|
}
|
||||||
|
return (fmIsIndefiniteRowsFunc(pFunc->funcId) || fmIsMultiRowsFunc(pFunc->funcId)) ? FUNC_RETURN_ROWS_INDEFINITE
|
||||||
|
: FUNC_RETURN_ROWS_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
bool fmIsBuiltinFunc(const char* pFunc) {
|
bool fmIsBuiltinFunc(const char* pFunc) {
|
||||||
return NULL != taosHashGet(gFunMgtService.pFuncNameHashTable, pFunc, strlen(pFunc));
|
return NULL != taosHashGet(gFunMgtService.pFuncNameHashTable, pFunc, strlen(pFunc));
|
||||||
}
|
}
|
||||||
|
@ -192,6 +200,8 @@ bool fmIsMultiRowsFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, F
|
||||||
|
|
||||||
bool fmIsKeepOrderFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_KEEP_ORDER_FUNC); }
|
bool fmIsKeepOrderFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_KEEP_ORDER_FUNC); }
|
||||||
|
|
||||||
|
bool fmIsCumulativeFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_CUMULATIVE_FUNC); }
|
||||||
|
|
||||||
bool fmIsInterpFunc(int32_t funcId) {
|
bool fmIsInterpFunc(int32_t funcId) {
|
||||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1110,12 +1110,15 @@ static int32_t translateIndefiniteRowsFunc(STranslateContext* pCxt, SFunctionNod
|
||||||
if (!fmIsIndefiniteRowsFunc(pFunc->funcId)) {
|
if (!fmIsIndefiniteRowsFunc(pFunc->funcId)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
if (!isSelectStmt(pCxt->pCurrStmt) || SQL_CLAUSE_SELECT != pCxt->currClause ||
|
if (!isSelectStmt(pCxt->pCurrStmt) || SQL_CLAUSE_SELECT != pCxt->currClause) {
|
||||||
((SSelectStmt*)pCxt->pCurrStmt)->hasIndefiniteRowsFunc || ((SSelectStmt*)pCxt->pCurrStmt)->hasAggFuncs ||
|
|
||||||
((SSelectStmt*)pCxt->pCurrStmt)->hasMultiRowsFunc) {
|
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||||
}
|
}
|
||||||
if (NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pWindow || NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pGroupByList) {
|
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pCurrStmt;
|
||||||
|
if (pSelect->hasAggFuncs || pSelect->hasMultiRowsFunc ||
|
||||||
|
(pSelect->hasIndefiniteRowsFunc && pSelect->returnRows != fmGetFuncReturnRows(pFunc))) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||||
|
}
|
||||||
|
if (NULL != pSelect->pWindow || NULL != pSelect->pGroupByList) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC,
|
||||||
"%s function is not supported in window query or group query", pFunc->functionName);
|
"%s function is not supported in window query or group query", pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
@ -1230,18 +1233,28 @@ static int32_t getMultiResFuncNum(SNodeList* pParameterList) {
|
||||||
return LIST_LENGTH(pParameterList);
|
return LIST_LENGTH(pParameterList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t calcSelectFuncNum(SFunctionNode* pFunc, int32_t currSelectFuncNum) {
|
||||||
|
if (fmIsCumulativeFunc(pFunc->funcId)) {
|
||||||
|
return currSelectFuncNum > 0 ? currSelectFuncNum : 1;
|
||||||
|
}
|
||||||
|
return currSelectFuncNum + ((fmIsMultiResFunc(pFunc->funcId) && !fmIsLastRowFunc(pFunc->funcId))
|
||||||
|
? getMultiResFuncNum(pFunc->pParameterList)
|
||||||
|
: 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) {
|
static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) {
|
||||||
if (NULL != pCurrStmt && QUERY_NODE_SELECT_STMT == nodeType(pCurrStmt)) {
|
if (NULL != pCurrStmt && QUERY_NODE_SELECT_STMT == nodeType(pCurrStmt)) {
|
||||||
SSelectStmt* pSelect = (SSelectStmt*)pCurrStmt;
|
SSelectStmt* pSelect = (SSelectStmt*)pCurrStmt;
|
||||||
pSelect->hasAggFuncs = pSelect->hasAggFuncs ? true : fmIsAggFunc(pFunc->funcId);
|
pSelect->hasAggFuncs = pSelect->hasAggFuncs ? true : fmIsAggFunc(pFunc->funcId);
|
||||||
pSelect->hasRepeatScanFuncs = pSelect->hasRepeatScanFuncs ? true : fmIsRepeatScanFunc(pFunc->funcId);
|
pSelect->hasRepeatScanFuncs = pSelect->hasRepeatScanFuncs ? true : fmIsRepeatScanFunc(pFunc->funcId);
|
||||||
pSelect->hasIndefiniteRowsFunc = pSelect->hasIndefiniteRowsFunc ? true : fmIsIndefiniteRowsFunc(pFunc->funcId);
|
if (fmIsIndefiniteRowsFunc(pFunc->funcId)) {
|
||||||
|
pSelect->hasIndefiniteRowsFunc = true;
|
||||||
|
pSelect->returnRows = fmGetFuncReturnRows(pFunc);
|
||||||
|
}
|
||||||
pSelect->hasMultiRowsFunc = pSelect->hasMultiRowsFunc ? true : fmIsMultiRowsFunc(pFunc->funcId);
|
pSelect->hasMultiRowsFunc = pSelect->hasMultiRowsFunc ? true : fmIsMultiRowsFunc(pFunc->funcId);
|
||||||
if (fmIsSelectFunc(pFunc->funcId)) {
|
if (fmIsSelectFunc(pFunc->funcId)) {
|
||||||
pSelect->hasSelectFunc = true;
|
pSelect->hasSelectFunc = true;
|
||||||
pSelect->selectFuncNum += (fmIsMultiResFunc(pFunc->funcId) && !fmIsLastRowFunc(pFunc->funcId))
|
pSelect->selectFuncNum = calcSelectFuncNum(pFunc, pSelect->selectFuncNum);
|
||||||
? getMultiResFuncNum(pFunc->pParameterList)
|
|
||||||
: 1;
|
|
||||||
} else if (fmIsVectorFunc(pFunc->funcId)) {
|
} else if (fmIsVectorFunc(pFunc->funcId)) {
|
||||||
pSelect->hasOtherVectorFunc = true;
|
pSelect->hasOtherVectorFunc = true;
|
||||||
}
|
}
|
||||||
|
@ -2481,6 +2494,9 @@ static int32_t translateInterp(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartitionByList) {
|
static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartitionByList) {
|
||||||
|
if (NULL == pPartitionByList) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
|
pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
|
||||||
return translateExprList(pCxt, pPartitionByList);
|
return translateExprList(pCxt, pPartitionByList);
|
||||||
}
|
}
|
||||||
|
@ -5568,7 +5584,7 @@ static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
|
|
||||||
int32_t code = checkCreateTable(pCxt, pStmt, false);
|
int32_t code = checkCreateTable(pCxt, pStmt, false);
|
||||||
SVgroupInfo info = {0};
|
SVgroupInfo info = {0};
|
||||||
SName name;
|
SName name;
|
||||||
toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &name);
|
toName(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, &name);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = getTableHashVgroupImpl(pCxt, &name, &info);
|
code = getTableHashVgroupImpl(pCxt, &name, &info);
|
||||||
|
|
|
@ -175,6 +175,16 @@ TEST_F(PlanBasicTest, pseudoColumn) {
|
||||||
"WHERE ts BETWEEN '2017-7-14 18:00:00' AND '2017-7-14 19:00:00' INTERVAL(10S)");
|
"WHERE ts BETWEEN '2017-7-14 18:00:00' AND '2017-7-14 19:00:00' INTERVAL(10S)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PlanBasicTest, indefiniteRowsFunc) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT DIFF(c1) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT DIFF(c1), c2 FROM t1");
|
||||||
|
|
||||||
|
run("SELECT DIFF(c1), DIFF(c3), ts FROM t1");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PlanBasicTest, withoutFrom) {
|
TEST_F(PlanBasicTest, withoutFrom) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue