enh: window clause validity check
This commit is contained in:
parent
61a6bee8f5
commit
c40b590ad8
|
@ -53,6 +53,11 @@ typedef struct SScanLogicNode {
|
||||||
double ratio;
|
double ratio;
|
||||||
SNodeList* pDynamicScanFuncs;
|
SNodeList* pDynamicScanFuncs;
|
||||||
int32_t dataRequired;
|
int32_t dataRequired;
|
||||||
|
int64_t interval;
|
||||||
|
int64_t offset;
|
||||||
|
int64_t sliding;
|
||||||
|
int8_t intervalUnit;
|
||||||
|
int8_t slidingUnit;
|
||||||
} SScanLogicNode;
|
} SScanLogicNode;
|
||||||
|
|
||||||
typedef struct SJoinLogicNode {
|
typedef struct SJoinLogicNode {
|
||||||
|
@ -208,6 +213,11 @@ typedef struct STableScanPhysiNode {
|
||||||
double ratio;
|
double ratio;
|
||||||
int32_t dataRequired;
|
int32_t dataRequired;
|
||||||
SNodeList* pDynamicScanFuncs;
|
SNodeList* pDynamicScanFuncs;
|
||||||
|
int64_t interval;
|
||||||
|
int64_t offset;
|
||||||
|
int64_t sliding;
|
||||||
|
int8_t intervalUnit;
|
||||||
|
int8_t slidingUnit;
|
||||||
} STableScanPhysiNode;
|
} STableScanPhysiNode;
|
||||||
|
|
||||||
typedef STableScanPhysiNode STableSeqScanPhysiNode;
|
typedef STableScanPhysiNode STableSeqScanPhysiNode;
|
||||||
|
@ -264,7 +274,6 @@ typedef struct SIntervalPhysiNode {
|
||||||
int64_t sliding;
|
int64_t sliding;
|
||||||
int8_t intervalUnit;
|
int8_t intervalUnit;
|
||||||
int8_t slidingUnit;
|
int8_t slidingUnit;
|
||||||
uint8_t precision;
|
|
||||||
SFillNode* pFill;
|
SFillNode* pFill;
|
||||||
} SIntervalPhysiNode;
|
} SIntervalPhysiNode;
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ typedef enum EColumnType {
|
||||||
typedef struct SColumnNode {
|
typedef struct SColumnNode {
|
||||||
SExprNode node; // QUERY_NODE_COLUMN
|
SExprNode node; // QUERY_NODE_COLUMN
|
||||||
uint64_t tableId;
|
uint64_t tableId;
|
||||||
|
int8_t tableType;
|
||||||
col_id_t colId;
|
col_id_t colId;
|
||||||
EColumnType colType; // column or tag
|
EColumnType colType; // column or tag
|
||||||
char dbName[TSDB_DB_NAME_LEN];
|
char dbName[TSDB_DB_NAME_LEN];
|
||||||
|
@ -196,8 +197,8 @@ typedef struct SStateWindowNode {
|
||||||
|
|
||||||
typedef struct SSessionWindowNode {
|
typedef struct SSessionWindowNode {
|
||||||
ENodeType type; // QUERY_NODE_SESSION_WINDOW
|
ENodeType type; // QUERY_NODE_SESSION_WINDOW
|
||||||
SNode* pCol; // timestamp primary key
|
SColumnNode* pCol; // timestamp primary key
|
||||||
SNode* pGap; // gap between two session window(in microseconds)
|
SValueNode* pGap; // gap between two session window(in microseconds)
|
||||||
} SSessionWindowNode;
|
} SSessionWindowNode;
|
||||||
|
|
||||||
typedef struct SIntervalWindowNode {
|
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_PORT TAOS_DEF_ERROR_CODE(0, 0x2612)
|
||||||
#define TSDB_CODE_PAR_INVALID_ENDPOINT TAOS_DEF_ERROR_CODE(0, 0x2613)
|
#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_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_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_INVALID_IDENTIFIER_NAME TAOS_DEF_ERROR_CODE(0, 0x2617)
|
||||||
#define TSDB_CODE_PAR_CORRESPONDING_STABLE_ERR TAOS_DEF_ERROR_CODE(0, 0x2618)
|
#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_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_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_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
|
//planner
|
||||||
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
|
#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;
|
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 qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, int32_t level) {
|
||||||
int32_t tlen = 0;
|
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_APPEND(EXPLAIN_WIDTH_FORMAT, pIntNode->window.node.pOutputDataBlockDesc->outputRowSize);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
uint8_t precision = getIntervalPrecision(pIntNode);
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_TIME_WINDOWS_FORMAT, INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->interval, pIntNode->intervalUnit, pIntNode->precision),
|
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(pIntNode->precision),
|
pIntNode->intervalUnit, pIntNode->offset, getPrecisionUnit(precision),
|
||||||
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, pIntNode->precision), pIntNode->slidingUnit);
|
INVERAL_TIME_FROM_PRECISION_TO_UNIT(pIntNode->sliding, pIntNode->slidingUnit, precision), pIntNode->slidingUnit);
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
||||||
|
|
|
@ -6831,7 +6831,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
||||||
.intervalUnit = pIntervalPhyNode->intervalUnit,
|
.intervalUnit = pIntervalPhyNode->intervalUnit,
|
||||||
.slidingUnit = pIntervalPhyNode->slidingUnit,
|
.slidingUnit = pIntervalPhyNode->slidingUnit,
|
||||||
.offset = pIntervalPhyNode->offset,
|
.offset = pIntervalPhyNode->offset,
|
||||||
.precision = pIntervalPhyNode->precision
|
.precision = ((SColumnNode*)pIntervalPhyNode->window.pTspk)->node.resType.precision
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t primaryTsSlotId = ((SColumnNode*) pIntervalPhyNode->window.pTspk)->slotId;
|
int32_t primaryTsSlotId = ((SColumnNode*) pIntervalPhyNode->window.pTspk)->slotId;
|
||||||
|
|
|
@ -399,7 +399,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "sum",
|
.name = "sum",
|
||||||
.type = FUNCTION_TYPE_SUM,
|
.type = FUNCTION_TYPE_SUM,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
|
||||||
.translateFunc = translateSum,
|
.translateFunc = translateSum,
|
||||||
.getEnvFunc = getSumFuncEnv,
|
.getEnvFunc = getSumFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
|
|
@ -748,6 +748,11 @@ static const char* jkTableScanPhysiPlanEndKey = "EndKey";
|
||||||
static const char* jkTableScanPhysiPlanRatio = "Ratio";
|
static const char* jkTableScanPhysiPlanRatio = "Ratio";
|
||||||
static const char* jkTableScanPhysiPlanDataRequired = "DataRequired";
|
static const char* jkTableScanPhysiPlanDataRequired = "DataRequired";
|
||||||
static const char* jkTableScanPhysiPlanDynamicScanFuncs = "DynamicScanFuncs";
|
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) {
|
static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const STableScanPhysiNode* pNode = (const STableScanPhysiNode*)pObj;
|
const STableScanPhysiNode* pNode = (const STableScanPhysiNode*)pObj;
|
||||||
|
@ -771,6 +776,21 @@ static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkTableScanPhysiPlanDynamicScanFuncs, pNode->pDynamicScanFuncs);
|
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;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -797,6 +817,21 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeList(pJson, jkTableScanPhysiPlanDynamicScanFuncs, &pNode->pDynamicScanFuncs);
|
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;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1159,7 +1194,6 @@ static const char* jkIntervalPhysiPlanSliding = "Sliding";
|
||||||
static const char* jkIntervalPhysiPlanIntervalUnit = "intervalUnit";
|
static const char* jkIntervalPhysiPlanIntervalUnit = "intervalUnit";
|
||||||
static const char* jkIntervalPhysiPlanSlidingUnit = "slidingUnit";
|
static const char* jkIntervalPhysiPlanSlidingUnit = "slidingUnit";
|
||||||
static const char* jkIntervalPhysiPlanFill = "Fill";
|
static const char* jkIntervalPhysiPlanFill = "Fill";
|
||||||
static const char* jkIntervalPhysiPlanPrecision = "Precision";
|
|
||||||
|
|
||||||
static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SIntervalPhysiNode* pNode = (const SIntervalPhysiNode*)pObj;
|
const SIntervalPhysiNode* pNode = (const SIntervalPhysiNode*)pObj;
|
||||||
|
@ -1183,9 +1217,6 @@ static int32_t physiIntervalNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddObject(pJson, jkIntervalPhysiPlanFill, nodeToJson, pNode->pFill);
|
code = tjsonAddObject(pJson, jkIntervalPhysiPlanFill, nodeToJson, pNode->pFill);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = tjsonAddIntegerToObject(pJson, jkIntervalPhysiPlanPrecision, pNode->precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1212,9 +1243,6 @@ static int32_t jsonToPhysiIntervalNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeObject(pJson, jkIntervalPhysiPlanFill, (SNode**)&pNode->pFill);
|
code = jsonToNodeObject(pJson, jkIntervalPhysiPlanFill, (SNode**)&pNode->pFill);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = tjsonGetUTinyIntValue(pJson, jkIntervalPhysiPlanPrecision, &pNode->precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,9 +87,9 @@ static EDealRes walkNode(SNode* pNode, ETraversalOrder order, FNodeWalker walker
|
||||||
}
|
}
|
||||||
case QUERY_NODE_SESSION_WINDOW: {
|
case QUERY_NODE_SESSION_WINDOW: {
|
||||||
SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
|
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) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -227,9 +227,9 @@ static EDealRes rewriteNode(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
|
||||||
}
|
}
|
||||||
case QUERY_NODE_SESSION_WINDOW: {
|
case QUERY_NODE_SESSION_WINDOW: {
|
||||||
SSessionWindowNode* pSession = (SSessionWindowNode*)pNode;
|
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) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -499,8 +499,8 @@ SNode* createOrderByExprNode(SAstCreateContext* pCxt, SNode* pExpr, EOrder order
|
||||||
SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap) {
|
SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap) {
|
||||||
SSessionWindowNode* session = (SSessionWindowNode*)nodesMakeNode(QUERY_NODE_SESSION_WINDOW);
|
SSessionWindowNode* session = (SSessionWindowNode*)nodesMakeNode(QUERY_NODE_SESSION_WINDOW);
|
||||||
CHECK_OUT_OF_MEM(session);
|
CHECK_OUT_OF_MEM(session);
|
||||||
session->pCol = pCol;
|
session->pCol = (SColumnNode*)pCol;
|
||||||
session->pGap = pGap;
|
session->pGap = (SValueNode*)pGap;
|
||||||
return (SNode*)session;
|
return (SNode*)session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "cmdnodes.h"
|
#include "cmdnodes.h"
|
||||||
#include "functionMgt.h"
|
#include "functionMgt.h"
|
||||||
#include "parUtil.h"
|
#include "parUtil.h"
|
||||||
|
#include "tglobal.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
|
|
||||||
#define GET_OPTION_VAL(pVal, defaultVal) (NULL == (pVal) ? (defaultVal) : getBigintFromValueNode((SValueNode*)(pVal)))
|
#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);
|
strcpy(pCol->node.aliasName, pColSchema->name);
|
||||||
}
|
}
|
||||||
pCol->tableId = pTable->pMeta->uid;
|
pCol->tableId = pTable->pMeta->uid;
|
||||||
|
pCol->tableType = pTable->pMeta->tableType;
|
||||||
pCol->colId = pColSchema->colId;
|
pCol->colId = pColSchema->colId;
|
||||||
pCol->colType = isTag ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN;
|
pCol->colType = isTag ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN;
|
||||||
pCol->node.resType.type = pColSchema->type;
|
pCol->node.resType.type = pColSchema->type;
|
||||||
|
@ -364,18 +366,38 @@ static bool translateColumnUseAlias(STranslateContext* pCxt, SColumnNode* pCol)
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes translateColumn(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, "*")) {
|
if (0 == strcmp(pCol->colName, "*")) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EDealRes res = DEAL_RES_CONTINUE;
|
||||||
if ('\0' != pCol->tableAlias[0]) {
|
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) {
|
if (DEAL_RES_ERROR == res) {
|
||||||
found = translateColumnUseAlias(pCxt, pCol);
|
return res;
|
||||||
}
|
}
|
||||||
return found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol);
|
|
||||||
|
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 DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
|
@ -639,7 +661,7 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
||||||
if (!pSelect->isDistinct) {
|
if (!pSelect->isDistinct) {
|
||||||
nodesWalkExprs(pSelect->pOrderByList, doCheckAggColCoexist, &cxt);
|
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 generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||||
}
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -1091,20 +1113,100 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
return translateExprList(pCxt, pSelect->pGroupByList);
|
return translateExprList(pCxt, pSelect->pGroupByList);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translateIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* pInterval) {
|
static bool isValTimeUnit(char unit) {
|
||||||
SValueNode* pIntervalVal = (SValueNode*)pInterval->pInterval;
|
return ('n' == unit || 'y' == unit);
|
||||||
SValueNode* pIntervalOffset = (SValueNode*)pInterval->pOffset;
|
}
|
||||||
SValueNode* pSliding = (SValueNode*)pInterval->pSliding;
|
|
||||||
if (pIntervalVal->datum.i <= 0) {
|
static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char unit) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INTERVAL_VALUE_TOO_SMALL, pIntervalVal->literal);
|
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;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doTranslateWindow(STranslateContext* pCxt, SNode* pWindow) {
|
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 checkWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||||
switch (nodeType(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:
|
case QUERY_NODE_INTERVAL_WINDOW:
|
||||||
return translateIntervalWindow(pCxt, (SIntervalWindowNode*)pWindow);
|
return checkIntervalWindow(pCxt, (SIntervalWindowNode*)pWindow);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1118,7 +1220,7 @@ static int32_t translateWindow(STranslateContext* pCxt, SNode* pWindow) {
|
||||||
pCxt->currClause = SQL_CLAUSE_WINDOW;
|
pCxt->currClause = SQL_CLAUSE_WINDOW;
|
||||||
int32_t code = translateExpr(pCxt, pWindow);
|
int32_t code = translateExpr(pCxt, pWindow);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = doTranslateWindow(pCxt, pWindow);
|
code = checkWindow(pCxt, pWindow);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
||||||
return "Endpoint should be in the format of 'fqdn:port'";
|
return "Endpoint should be in the format of 'fqdn:port'";
|
||||||
case TSDB_CODE_PAR_EXPRIE_STATEMENT:
|
case TSDB_CODE_PAR_EXPRIE_STATEMENT:
|
||||||
return "This statement is no longer supported";
|
return "This statement is no longer supported";
|
||||||
case TSDB_CODE_PAR_INTERVAL_VALUE_TOO_SMALL:
|
case TSDB_CODE_PAR_INTER_VALUE_TOO_SMALL:
|
||||||
return "This interval value is too small : %s";
|
return "Interval cannot be less than %d us";
|
||||||
case TSDB_CODE_PAR_DB_NOT_SPECIFIED:
|
case TSDB_CODE_PAR_DB_NOT_SPECIFIED:
|
||||||
return "Database not specified";
|
return "Database not specified";
|
||||||
case TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME:
|
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";
|
return "Invalid option keep unit: %c, %c, %c, only m, h, d allowed";
|
||||||
case TSDB_CODE_PAR_AGG_FUNC_NESTING:
|
case TSDB_CODE_PAR_AGG_FUNC_NESTING:
|
||||||
return "Aggregate functions do not support 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:
|
case TSDB_CODE_OUT_OF_MEMORY:
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -166,12 +166,24 @@ static int32_t osdGetDataRequired(SNodeList* pFuncs) {
|
||||||
return dataRequired;
|
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) {
|
static int32_t osdOptimize(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
|
||||||
SOsdInfo info = {0};
|
SOsdInfo info = {0};
|
||||||
int32_t code = osdMatch(pCxt, pLogicNode, &info);
|
int32_t code = osdMatch(pCxt, pLogicNode, &info);
|
||||||
if (TSDB_CODE_SUCCESS == code && (NULL != info.pDsoFuncs || NULL != info.pSdrFuncs)) {
|
if (TSDB_CODE_SUCCESS == code && (NULL != info.pDsoFuncs || NULL != info.pSdrFuncs)) {
|
||||||
info.pScan->dataRequired = osdGetDataRequired(info.pSdrFuncs);
|
info.pScan->dataRequired = osdGetDataRequired(info.pSdrFuncs);
|
||||||
info.pScan->pDynamicScanFuncs = info.pDsoFuncs;
|
info.pScan->pDynamicScanFuncs = info.pDsoFuncs;
|
||||||
|
setScanWindowInfo((SScanLogicNode*)info.pScan);
|
||||||
OPTIMIZE_FLAG_SET_MASK(info.pScan->node.optimizedFlag, OPTIMIZE_FLAG_OSD);
|
OPTIMIZE_FLAG_SET_MASK(info.pScan->node.optimizedFlag, OPTIMIZE_FLAG_OSD);
|
||||||
pCxt->optimized = true;
|
pCxt->optimized = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -443,6 +443,11 @@ static int32_t createTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubp
|
||||||
nodesDestroyNode(pTableScan);
|
nodesDestroyNode(pTableScan);
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
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);
|
return createScanPhysiNodeFinalize(pCxt, pScanLogicNode, (SScanPhysiNode*)pTableScan, pPhyNode);
|
||||||
}
|
}
|
||||||
|
@ -819,7 +824,6 @@ static int32_t createIntervalPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChil
|
||||||
pInterval->sliding = pWindowLogicNode->sliding;
|
pInterval->sliding = pWindowLogicNode->sliding;
|
||||||
pInterval->intervalUnit = pWindowLogicNode->intervalUnit;
|
pInterval->intervalUnit = pWindowLogicNode->intervalUnit;
|
||||||
pInterval->slidingUnit = pWindowLogicNode->slidingUnit;
|
pInterval->slidingUnit = pWindowLogicNode->slidingUnit;
|
||||||
pInterval->precision = ((SColumnNode*)pWindowLogicNode->pTspk)->node.resType.precision;
|
|
||||||
|
|
||||||
pInterval->pFill = nodesCloneNode(pWindowLogicNode->pFill);
|
pInterval->pFill = nodesCloneNode(pWindowLogicNode->pFill);
|
||||||
if (NULL != pWindowLogicNode->pFill && NULL == pInterval->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) {
|
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 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 &&
|
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_VARCHAR && outputType != TSDB_DATA_TYPE_NCHAR &&
|
||||||
outputType != TSDB_DATA_TYPE_TIMESTAMP) {
|
outputType != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||||
return TSDB_CODE_FAILED;
|
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 *input = NULL;
|
||||||
char *outputBuf = taosMemoryCalloc(outputLen * pInput[0].numOfRows, 1);
|
char *outputBuf = taosMemoryCalloc(outputLen * pInput[0].numOfRows, 1);
|
||||||
|
|
Loading…
Reference in New Issue