提交 c40b590a 编写于 作者: X Xiaoyu Wang

enh: window clause validity check

上级 61a6bee8
......@@ -53,6 +53,11 @@ typedef struct SScanLogicNode {
double ratio;
SNodeList* pDynamicScanFuncs;
int32_t dataRequired;
int64_t interval;
int64_t offset;
int64_t sliding;
int8_t intervalUnit;
int8_t slidingUnit;
} SScanLogicNode;
typedef struct SJoinLogicNode {
......@@ -208,6 +213,11 @@ typedef struct STableScanPhysiNode {
double ratio;
int32_t dataRequired;
SNodeList* pDynamicScanFuncs;
int64_t interval;
int64_t offset;
int64_t sliding;
int8_t intervalUnit;
int8_t slidingUnit;
} STableScanPhysiNode;
typedef STableScanPhysiNode STableSeqScanPhysiNode;
......@@ -264,7 +274,6 @@ typedef struct SIntervalPhysiNode {
int64_t sliding;
int8_t intervalUnit;
int8_t slidingUnit;
uint8_t precision;
SFillNode* pFill;
} SIntervalPhysiNode;
......
......@@ -57,6 +57,7 @@ typedef enum EColumnType {
typedef struct SColumnNode {
SExprNode node; // QUERY_NODE_COLUMN
uint64_t tableId;
int8_t tableType;
col_id_t colId;
EColumnType colType; // column or tag
char dbName[TSDB_DB_NAME_LEN];
......@@ -196,8 +197,8 @@ typedef struct SStateWindowNode {
typedef struct SSessionWindowNode {
ENodeType type; // QUERY_NODE_SESSION_WINDOW
SNode* pCol; // timestamp primary key
SNode* pGap; // gap between two session window(in microseconds)
SColumnNode* pCol; // timestamp primary key
SValueNode* pGap; // gap between two session window(in microseconds)
} SSessionWindowNode;
typedef struct SIntervalWindowNode {
......
......@@ -579,7 +579,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_INVALID_PORT TAOS_DEF_ERROR_CODE(0, 0x2612)
#define TSDB_CODE_PAR_INVALID_ENDPOINT TAOS_DEF_ERROR_CODE(0, 0x2613)
#define TSDB_CODE_PAR_EXPRIE_STATEMENT TAOS_DEF_ERROR_CODE(0, 0x2614)
#define TSDB_CODE_PAR_INTERVAL_VALUE_TOO_SMALL TAOS_DEF_ERROR_CODE(0, 0x2615)
#define TSDB_CODE_PAR_INTER_VALUE_TOO_SMALL TAOS_DEF_ERROR_CODE(0, 0x2615)
#define TSDB_CODE_PAR_DB_NOT_SPECIFIED TAOS_DEF_ERROR_CODE(0, 0x2616)
#define TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME TAOS_DEF_ERROR_CODE(0, 0x2617)
#define TSDB_CODE_PAR_CORRESPONDING_STABLE_ERR TAOS_DEF_ERROR_CODE(0, 0x2618)
......@@ -598,6 +598,17 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_INVALID_OPTION_UNIT TAOS_DEF_ERROR_CODE(0, 0x2625)
#define TSDB_CODE_PAR_INVALID_KEEP_UNIT TAOS_DEF_ERROR_CODE(0, 0x2626)
#define TSDB_CODE_PAR_AGG_FUNC_NESTING TAOS_DEF_ERROR_CODE(0, 0x2627)
#define TSDB_CODE_PAR_INVALID_STATE_WIN_TYPE TAOS_DEF_ERROR_CODE(0, 0x2628)
#define TSDB_CODE_PAR_INVALID_STATE_WIN_COL TAOS_DEF_ERROR_CODE(0, 0x2629)
#define TSDB_CODE_PAR_INVALID_STATE_WIN_TABLE TAOS_DEF_ERROR_CODE(0, 0x262A)
#define TSDB_CODE_PAR_INTER_SESSION_GAP TAOS_DEF_ERROR_CODE(0, 0x262B)
#define TSDB_CODE_PAR_INTER_SESSION_COL TAOS_DEF_ERROR_CODE(0, 0x262C)
#define TSDB_CODE_PAR_INTER_OFFSET_NEGATIVE TAOS_DEF_ERROR_CODE(0, 0x262D)
#define TSDB_CODE_PAR_INTER_OFFSET_UNIT TAOS_DEF_ERROR_CODE(0, 0x262E)
#define TSDB_CODE_PAR_INTER_OFFSET_TOO_BIG TAOS_DEF_ERROR_CODE(0, 0x262F)
#define TSDB_CODE_PAR_INTER_SLIDING_UNIT TAOS_DEF_ERROR_CODE(0, 0x2630)
#define TSDB_CODE_PAR_INTER_SLIDING_TOO_BIG TAOS_DEF_ERROR_CODE(0, 0x2631)
#define TSDB_CODE_PAR_INTER_SLIDING_TOO_SMALL TAOS_DEF_ERROR_CODE(0, 0x2632)
//planner
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
......
......@@ -316,6 +316,9 @@ int32_t qExplainResAppendRow(SExplainCtx *ctx, char *tbuf, int32_t len, int32_t
return TSDB_CODE_SUCCESS;
}
static uint8_t getIntervalPrecision(SIntervalPhysiNode* pIntNode) {
return ((SColumnNode*)pIntNode->window.pTspk)->node.resType.precision;
}
int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
int32_t tlen = 0;
......@@ -658,10 +661,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, pIntNode->precision),
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(pIntNode->precision),
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, pIntNode->precision), pIntNode->slidingUnit);
uint8_t precision = getIntervalPrecision(pIntNode);
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, precision),
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision), pIntNode->slidingUnit);
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
......
......@@ -6831,7 +6831,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
.intervalUnit = pIntervalPhyNode->intervalUnit,
.slidingUnit = pIntervalPhyNode->slidingUnit,
.offset = pIntervalPhyNode->offset,
.precision = pIntervalPhyNode->precision
.precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision
};
int32_t primaryTsSlotId = ((SColumnNode*) pIntervalPhyNode->window.pTspk)->slotId;
......
......@@ -399,7 +399,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{
.name = "sum",
.type = FUNCTION_TYPE_SUM,
.classification = FUNC_MGT_AGG_FUNC,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
.translateFunc = translateSum,
.getEnvFunc = getSumFuncEnv,
.initFunc = functionSetup,
......
......@@ -748,6 +748,11 @@ static const char* jkTableScanPhysiPlanEndKey = "EndKey";
static const char* jkTableScanPhysiPlanRatio = "Ratio";
static const char* jkTableScanPhysiPlanDataRequired = "DataRequired";
static const char* jkTableScanPhysiPlanDynamicScanFuncs = "DynamicScanFuncs";
static const char* jkTableScanPhysiPlanInterval = "Interval";
static const char* jkTableScanPhysiPlanOffset = "Offset";
static const char* jkTableScanPhysiPlanSliding = "Sliding";
static const char* jkTableScanPhysiPlanIntervalUnit = "intervalUnit";
static const char* jkTableScanPhysiPlanSlidingUnit = "slidingUnit";
static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
const STableScanPhysiNode* pNode = (const STableScanPhysiNode*)pObj;
......@@ -771,6 +776,21 @@ static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkTableScanPhysiPlanDynamicScanFuncs, pNode->pDynamicScanFuncs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanInterval, pNode->interval);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanOffset, pNode->offset);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanSliding, pNode->sliding);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanIntervalUnit, pNode->intervalUnit);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanSlidingUnit, pNode->slidingUnit);
}
return code;
}
......@@ -797,6 +817,21 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkTableScanPhysiPlanDynamicScanFuncs, &pNode->pDynamicScanFuncs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanInterval, pNode->interval);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanOffset, pNode->offset);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanSliding, pNode->sliding);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanIntervalUnit, pNode->intervalUnit);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanSlidingUnit, pNode->slidingUnit);
}
return code;
}
......@@ -1159,7 +1194,6 @@ static const char* jkIntervalPhysiPlanSliding = "Sliding";
static const char* jkIntervalPhysiPlanIntervalUnit = "intervalUnit";
static const char* jkIntervalPhysiPlanSlidingUnit = "slidingUnit";
static const char* jkIntervalPhysiPlanFill = "Fill";
static const char* jkIntervalPhysiPlanPrecision = "Precision";
static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
const SIntervalPhysiNode* pNode = (const SIntervalPhysiNode*)pObj;
......@@ -1183,9 +1217,6 @@ static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkIntervalPhysiPlanFill, nodeToJson, pNode->pFill);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanPrecision, pNode->precision);
}
return code;
}
......@@ -1212,9 +1243,6 @@ static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkIntervalPhysiPlanFill, (SNode**)&pNode->pFill);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUTinyIntValue(pJson, jkIntervalPhysiPlanPrecision, &pNode->precision);
}
return code;
}
......
......@@ -87,9 +87,9 @@ static EDealRes walkNode(SNode* pNode, ETraversalOrder order, FNodeWalker walker
}
case QUERY_NODE_SESSION_WINDOW: {
SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
res = walkNode(pSession->pCol, order, walker, pContext);
res = walkNode((SNode*)pSession->pCol, order, walker, pContext);
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
res = walkNode(pSession->pGap, order, walker, pContext);
res = walkNode((SNode*)pSession->pGap, order, walker, pContext);
}
break;
}
......@@ -227,9 +227,9 @@ static EDealRes rewriteNode(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
}
case QUERY_NODE_SESSION_WINDOW: {
SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
res = rewriteNode(&pSession->pCol, order, rewriter, pContext);
res = rewriteNode((SNode**)&pSession->pCol, order, rewriter, pContext);
if (DEAL_RES_ERROR != res && DEAL_RES_END != res) {
res = rewriteNode(&pSession->pGap, order, rewriter, pContext);
res = rewriteNode((SNode**)&pSession->pGap, order, rewriter, pContext);
}
break;
}
......
......@@ -499,8 +499,8 @@ SNode* createOrderByExprNode(SAstCreateContext* pCxt, SNode* pExpr, EOrder order
SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap) {
SSessionWindowNode* session = (SSessionWindowNode*)nodesMakeNode(QUERY_NODE_SESSION_WINDOW);
CHECK_OUT_OF_MEM(session);
session->pCol = pCol;
session->pGap = pGap;
session->pCol = (SColumnNode*)pCol;
session->pGap = (SValueNode*)pGap;
return (SNode*)session;
}
......
......@@ -19,6 +19,7 @@
#include "cmdnodes.h"
#include "functionMgt.h"
#include "parUtil.h"
#include "tglobal.h"
#include "ttime.h"
#define GET_OPTION_VAL(pVal, defaultVal) (NULL == (pVal) ? (defaultVal) : getBigintFromValueNode((SValueNode*)(pVal)))
......@@ -227,6 +228,7 @@ static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* p
strcpy(pCol->node.aliasName, pColSchema->name);
}
pCol->tableId = pTable->pMeta->uid;
pCol->tableType = pTable->pMeta->tableType;
pCol->colId = pColSchema->colId;
pCol->colType = isTag ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN;
pCol->node.resType.type = pColSchema->type;
......@@ -364,18 +366,38 @@ static bool translateColumnUseAlias(STranslateContext* pCxt, SColumnNode* pCol)
}
static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
// count(*)/first(*)/last(*)
// count(*)/first(*)/last(*) and so on
if (0 == strcmp(pCol->colName, "*")) {
return DEAL_RES_CONTINUE;
}
EDealRes res = DEAL_RES_CONTINUE;
if ('\0' != pCol->tableAlias[0]) {
return translateColumnWithPrefix(pCxt, pCol);
res = translateColumnWithPrefix(pCxt, pCol);
} else {
bool found = false;
if (SQL_CLAUSE_ORDER_BY == pCxt->currClause) {
found = translateColumnUseAlias(pCxt, pCol);
}
res = (found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol));
}
bool found = false;
if (SQL_CLAUSE_ORDER_BY == pCxt->currClause) {
found = translateColumnUseAlias(pCxt, pCol);
if (DEAL_RES_ERROR == res) {
return res;
}
if (SQL_CLAUSE_WINDOW == pCxt->currClause && QUERY_NODE_STATE_WINDOW == nodeType(pCxt->pCurrStmt->pWindow)) {
if (!IS_INTEGER_TYPE(pCol->node.resType.type)) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_STATE_WIN_TYPE);
}
if (COLUMN_TYPE_TAG == pCol->colType) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_STATE_WIN_COL);
}
if (TSDB_SUPER_TABLE == pCol->tableType) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_STATE_WIN_TABLE);
}
}
return found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol);
return DEAL_RES_CONTINUE;
}
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
......@@ -639,7 +661,7 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
if (!pSelect->isDistinct) {
nodesWalkExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
}
if (cxt.existAggFunc && cxt.existCol) {
if ((cxt.existAggFunc || NULL != pSelect->pWindow) && cxt.existCol) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SINGLE_GROUP);
}
return TSDB_CODE_SUCCESS;
......@@ -1091,20 +1113,100 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
return translateExprList(pCxt, pSelect->pGroupByList);
}
static int32_t translateIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
SValueNode* pIntervalVal = (SValueNode*)pInterval->pInterval;
SValueNode* pIntervalOffset = (SValueNode*)pInterval->pOffset;
SValueNode* pSliding = (SValueNode*)pInterval->pSliding;
if (pIntervalVal->datum.i <= 0) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTERVAL_VALUE_TOO_SMALL, pIntervalVal->literal);
static bool isValTimeUnit(char unit) {
return ('n' == unit || 'y' == unit);
}
static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char unit) {
int64_t days = convertTimeFromPrecisionToUnit(val, fromPrecision, 'd');
switch (unit) {
case 'b':
case 'u':
case 'a':
case 's':
case 'm':
case 'h':
case 'd':
case 'w':
return days / 28;
case 'n':
return val;
case 'y':
return val * 12;
default:
break;
}
return -1;
}
static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
uint8_t precision = ((SColumnNode*)pInterval->pCol)->node.resType.precision;
SValueNode* pInter = (SValueNode*)pInterval->pInterval;
bool valInter = isValTimeUnit(pInter->unit);
if (pInter->datum.i <= 0 ||
(!valInter && convertTimePrecision(pInter->datum.i, precision, TSDB_TIME_PRECISION_MICRO) < tsMinIntervalTime)) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_VALUE_TOO_SMALL, tsMinIntervalTime);
}
if (NULL != pInterval->pOffset) {
SValueNode* pOffset = (SValueNode*)pInterval->pOffset;
bool valOffset = isValTimeUnit(pOffset->unit);
if (pOffset->datum.i <= 0) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_NEGATIVE);
}
if (pInter->unit == 'n' && pOffset->unit == 'y') {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_UNIT);
}
if ((!valInter && !valOffset && pOffset->datum.i >= pInter->datum.i) ||
(getMonthsFromTimeVal(pOffset->datum.i, precision, pOffset->unit) >= getMonthsFromTimeVal(pInter->datum.i, precision, pInter->unit))) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_OFFSET_TOO_BIG);
}
}
if (NULL != pInterval->pSliding) {
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
SValueNode* pSliding = (SValueNode*)pInterval->pSliding;
if (pInter->unit == 'n' || pInter->unit == 'y') {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_UNIT);
}
if ((pSliding->datum.i < convertTimePrecision(tsMinSlidingTime, TSDB_TIME_PRECISION_MILLI, precision)) ||
(pInter->datum.i / pSliding->datum.i > INTERVAL_SLIDING_FACTOR)) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_TOO_SMALL);
}
if (pSliding->datum.i > pInter->datum.i) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SLIDING_TOO_BIG);
}
}
return TSDB_CODE_SUCCESS;
}
static int32_t checkStateWindow(STranslateContext* pCxt, SStateWindowNode* pState) {
// todo check for "function not support for state_window"
return TSDB_CODE_SUCCESS;
}
static int32_t checkSessionWindow(STranslateContext* pCxt, SSessionWindowNode* pSession) {
if ('y' == pSession->pGap->unit || 'n' == pSession->pGap->unit || 0 == pSession->pGap->datum.i) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SESSION_GAP);
}
if (PRIMARYKEY_TIMESTAMP_COL_ID != pSession->pCol->colId) {
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTER_SESSION_COL);
}
// todo check for "function not support for session"
return TSDB_CODE_SUCCESS;
}
static int32_t doTranslateWindow(STranslateContext* pCxt, SNode* pWindow) {
static int32_t checkWindow(STranslateContext* pCxt, SNode* pWindow) {
switch (nodeType(pWindow)) {
case QUERY_NODE_STATE_WINDOW:
return checkStateWindow(pCxt, (SStateWindowNode*)pWindow);
case QUERY_NODE_SESSION_WINDOW:
return checkSessionWindow(pCxt, (SSessionWindowNode*)pWindow);
case QUERY_NODE_INTERVAL_WINDOW:
return translateIntervalWindow(pCxt, (SIntervalWindowNode*)pWindow);
return checkIntervalWindow(pCxt, (SIntervalWindowNode*)pWindow);
default:
break;
}
......@@ -1118,7 +1220,7 @@ static int32_t translateWindow(STranslateContext* pCxt, SNode* pWindow) {
pCxt->currClause = SQL_CLAUSE_WINDOW;
int32_t code = translateExpr(pCxt, pWindow);
if (TSDB_CODE_SUCCESS == code) {
code = doTranslateWindow(pCxt, pWindow);
code = checkWindow(pCxt, pWindow);
}
return code;
}
......
......@@ -55,8 +55,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Endpoint should be in the format of 'fqdn:port'";
case TSDB_CODE_PAR_EXPRIE_STATEMENT:
return "This statement is no longer supported";
case TSDB_CODE_PAR_INTERVAL_VALUE_TOO_SMALL:
return "This interval value is too small : %s";
case TSDB_CODE_PAR_INTER_VALUE_TOO_SMALL:
return "Interval cannot be less than %d us";
case TSDB_CODE_PAR_DB_NOT_SPECIFIED:
return "Database not specified";
case TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME:
......@@ -93,6 +93,28 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "Invalid option keep unit: %c, %c, %c, only m, h, d allowed";
case TSDB_CODE_PAR_AGG_FUNC_NESTING:
return "Aggregate functions do not support nesting";
case TSDB_CODE_PAR_INVALID_STATE_WIN_TYPE:
return "Only support STATE_WINDOW on integer column";
case TSDB_CODE_PAR_INVALID_STATE_WIN_COL:
return "Not support STATE_WINDOW on tag column";
case TSDB_CODE_PAR_INVALID_STATE_WIN_TABLE:
return "STATE_WINDOW not support for super table query";
case TSDB_CODE_PAR_INTER_SESSION_GAP:
return "SESSION gap should be fixed time window, and greater than 0";
case TSDB_CODE_PAR_INTER_SESSION_COL:
return "Only support SESSION on primary timestamp column";
case TSDB_CODE_PAR_INTER_OFFSET_NEGATIVE:
return "Interval offset cannot be negative";
case TSDB_CODE_PAR_INTER_OFFSET_UNIT:
return "Cannot use 'year' as offset when interval is 'month'";
case TSDB_CODE_PAR_INTER_OFFSET_TOO_BIG:
return "Interval offset should be shorter than interval";
case TSDB_CODE_PAR_INTER_SLIDING_UNIT:
return "Does not support sliding when interval is natural month/year";
case TSDB_CODE_PAR_INTER_SLIDING_TOO_BIG:
return "sliding value no larger than the interval value";
case TSDB_CODE_PAR_INTER_SLIDING_TOO_SMALL:
return "sliding value can not less than 1% of interval value";
case TSDB_CODE_OUT_OF_MEMORY:
return "Out of memory";
default:
......
......@@ -166,12 +166,24 @@ static int32_t osdGetDataRequired(SNodeList* pFuncs) {
return dataRequired;
}
static void setScanWindowInfo(SScanLogicNode* pScan) {
if (QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pScan->node.pParent) &&
WINDOW_TYPE_INTERVAL == ((SWindowLogicNode*)pScan->node.pParent)->winType) {
pScan->interval = ((SWindowLogicNode*)pScan->node.pParent)->interval;
pScan->offset = ((SWindowLogicNode*)pScan->node.pParent)->offset;
pScan->sliding = ((SWindowLogicNode*)pScan->node.pParent)->sliding;
pScan->intervalUnit = ((SWindowLogicNode*)pScan->node.pParent)->intervalUnit;
pScan->slidingUnit = ((SWindowLogicNode*)pScan->node.pParent)->slidingUnit;
}
}
static int32_t osdOptimize(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
SOsdInfo info = {0};
int32_t code = osdMatch(pCxt, pLogicNode, &info);
if (TSDB_CODE_SUCCESS == code && (NULL != info.pDsoFuncs || NULL != info.pSdrFuncs)) {
info.pScan->dataRequired = osdGetDataRequired(info.pSdrFuncs);
info.pScan->pDynamicScanFuncs = info.pDsoFuncs;
setScanWindowInfo((SScanLogicNode*)info.pScan);
OPTIMIZE_FLAG_SET_MASK(info.pScan->node.optimizedFlag, OPTIMIZE_FLAG_OSD);
pCxt->optimized = true;
}
......
......@@ -443,6 +443,11 @@ static int32_t createTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubp
nodesDestroyNode(pTableScan);
return TSDB_CODE_OUT_OF_MEMORY;
}
pTableScan->interval = pScanLogicNode->interval;
pTableScan->offset = pScanLogicNode->offset;
pTableScan->sliding = pScanLogicNode->sliding;
pTableScan->intervalUnit = pScanLogicNode->intervalUnit;
pTableScan->slidingUnit = pScanLogicNode->slidingUnit;
return createScanPhysiNodeFinalize(pCxt, pScanLogicNode, (SScanPhysiNode*)pTableScan, pPhyNode);
}
......@@ -819,7 +824,6 @@ static int32_t createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChil
pInterval->sliding = pWindowLogicNode->sliding;
pInterval->intervalUnit = pWindowLogicNode->intervalUnit;
pInterval->slidingUnit = pWindowLogicNode->slidingUnit;
pInterval->precision = ((SColumnNode*)pWindowLogicNode->pTspk)->node.resType.precision;
pInterval->pFill = nodesCloneNode(pWindowLogicNode->pFill);
if (NULL != pWindowLogicNode->pFill && NULL == pInterval->pFill) {
......
......@@ -666,18 +666,14 @@ int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu
}
int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
if (inputNum!= 3) {
return TSDB_CODE_FAILED;
}
int16_t inputType = pInput[0].columnData->info.type;
int16_t outputType = *(int16_t *)pInput[1].columnData->pData;
int16_t outputType = pOutput[0].columnData->info.type;
if (outputType != TSDB_DATA_TYPE_BIGINT && outputType != TSDB_DATA_TYPE_UBIGINT &&
outputType != TSDB_DATA_TYPE_VARCHAR && outputType != TSDB_DATA_TYPE_NCHAR &&
outputType != TSDB_DATA_TYPE_TIMESTAMP) {
return TSDB_CODE_FAILED;
}
int64_t outputLen = *(int64_t *)pInput[2].columnData->pData;
int64_t outputLen = pOutput[0].columnData->info.bytes;
char *input = NULL;
char *outputBuf = taosMemoryCalloc(outputLen * pInput[0].numOfRows, 1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册