Merge branch '3.0' into feature/TD-13066-3.0
This commit is contained in:
commit
64d6a27f80
|
@ -621,6 +621,14 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_PAR_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x2639)
|
#define TSDB_CODE_PAR_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x2639)
|
||||||
#define TSDB_CODE_PAR_INVALID_DROP_STABLE TAOS_DEF_ERROR_CODE(0, 0x263A)
|
#define TSDB_CODE_PAR_INVALID_DROP_STABLE TAOS_DEF_ERROR_CODE(0, 0x263A)
|
||||||
#define TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE TAOS_DEF_ERROR_CODE(0, 0x263B)
|
#define TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE TAOS_DEF_ERROR_CODE(0, 0x263B)
|
||||||
|
#define TSDB_CODE_PAR_DUPLICATED_COLUMN TAOS_DEF_ERROR_CODE(0, 0x263C)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_TAGS_LENGTH TAOS_DEF_ERROR_CODE(0, 0x263D)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_ROW_LENGTH TAOS_DEF_ERROR_CODE(0, 0x263E)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_COLUMNS_NUM TAOS_DEF_ERROR_CODE(0, 0x263F)
|
||||||
|
#define TSDB_CODE_PAR_TOO_MANY_COLUMNS TAOS_DEF_ERROR_CODE(0, 0x2640)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_FIRST_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2641)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN TAOS_DEF_ERROR_CODE(0, 0x2642)
|
||||||
|
#define TSDB_CODE_PAR_INVALID_TAGS_NUM TAOS_DEF_ERROR_CODE(0, 0x2643)
|
||||||
|
|
||||||
//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)
|
||||||
|
|
|
@ -73,6 +73,11 @@ bool spreadFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo)
|
||||||
int32_t spreadFunction(SqlFunctionCtx* pCtx);
|
int32_t spreadFunction(SqlFunctionCtx* pCtx);
|
||||||
int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||||
|
|
||||||
|
bool getHistogramFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
|
bool histogramFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||||
|
int32_t histogramFunction(SqlFunctionCtx* pCtx);
|
||||||
|
int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -225,6 +225,26 @@ static int32_t translateSpread(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
|
if (4 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||||
|
if (!IS_NUMERIC_TYPE(colType)) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||||
|
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||||
|
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE };
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateLastRow(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
static int32_t translateLastRow(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
// todo
|
// todo
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -242,8 +262,7 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
||||||
"The parameters of first/last can only be columns");
|
"The parameters of first/last can only be columns");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t paraType = ((SExprNode*)pPara)->resType.type;
|
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
||||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[paraType].bytes, .type = paraType};
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,6 +619,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.processFunc = diffFunction,
|
.processFunc = diffFunction,
|
||||||
.finalizeFunc = functionFinalize
|
.finalizeFunc = functionFinalize
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "histogram",
|
||||||
|
.type = FUNCTION_TYPE_HISTOGRAM,
|
||||||
|
.classification = FUNC_MGT_AGG_FUNC,
|
||||||
|
.translateFunc = translateHistogram,
|
||||||
|
.getEnvFunc = getHistogramFuncEnv,
|
||||||
|
.initFunc = histogramFunctionSetup,
|
||||||
|
.processFunc = histogramFunction,
|
||||||
|
.finalizeFunc = histogramFinalize
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "abs",
|
.name = "abs",
|
||||||
.type = FUNCTION_TYPE_ABS,
|
.type = FUNCTION_TYPE_ABS,
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "tdatablock.h"
|
#include "tdatablock.h"
|
||||||
#include "tpercentile.h"
|
#include "tpercentile.h"
|
||||||
|
|
||||||
|
#define HISTOGRAM_MAX_BINS_NUM 100
|
||||||
|
|
||||||
typedef struct SSumRes {
|
typedef struct SSumRes {
|
||||||
union {
|
union {
|
||||||
int64_t isum;
|
int64_t isum;
|
||||||
|
@ -89,6 +91,22 @@ typedef struct SSpreadInfo {
|
||||||
double max;
|
double max;
|
||||||
} SSpreadInfo;
|
} SSpreadInfo;
|
||||||
|
|
||||||
|
typedef struct SHistoFuncBin {
|
||||||
|
double lower;
|
||||||
|
double upper;
|
||||||
|
union {
|
||||||
|
int64_t count;
|
||||||
|
double percentage;
|
||||||
|
};
|
||||||
|
} SHistoFuncBin;
|
||||||
|
|
||||||
|
typedef struct SHistoFuncInfo {
|
||||||
|
int32_t numOfBins;
|
||||||
|
bool normalized;
|
||||||
|
SHistoFuncBin bins[];
|
||||||
|
} SHistoFuncInfo;
|
||||||
|
|
||||||
|
|
||||||
#define SET_VAL(_info, numOfElem, res) \
|
#define SET_VAL(_info, numOfElem, res) \
|
||||||
do { \
|
do { \
|
||||||
if ((numOfElem) <= 0) { \
|
if ((numOfElem) <= 0) { \
|
||||||
|
@ -1777,3 +1795,34 @@ int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
}
|
}
|
||||||
return functionFinalize(pCtx, pBlock);
|
return functionFinalize(pCtx, pBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getHistogramFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||||
|
pEnv->calcMemSize = sizeof(SHistoFuncInfo) + HISTOGRAM_MAX_BINS_NUM * sizeof(SHistoFuncBin);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool histogramFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||||
|
if (!functionSetup(pCtx, pResultInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHistoFuncInfo* pInfo = GET_ROWCELL_INTERBUF(pResultInfo);
|
||||||
|
char* binType = pCtx->param[1].param.pz;
|
||||||
|
char* binDesc = pCtx->param[2].param.pz;
|
||||||
|
int64_t nornalized = pCtx->param[3].param.i;
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t histogramFunction(SqlFunctionCtx *pCtx) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
|
SHistoFuncInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||||
|
//if (pInfo->hasResult == true) {
|
||||||
|
// SET_DOUBLE_VAL(&pInfo->result, pInfo->max - pInfo->min);
|
||||||
|
//}
|
||||||
|
return functionFinalize(pCtx, pBlock);
|
||||||
|
}
|
||||||
|
|
|
@ -2174,17 +2174,6 @@ static int32_t checkTableSmaOption(STranslateContext* pCxt, SCreateTableStmt* pS
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t checkTableTags(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
|
|
||||||
SNode* pNode;
|
|
||||||
FOREACH(pNode, pStmt->pTags) {
|
|
||||||
SColumnDefNode* pCol = (SColumnDefNode*)pNode;
|
|
||||||
if (pCol->dataType.type == TSDB_DATA_TYPE_JSON && LIST_LENGTH(pStmt->pTags) > 1) {
|
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t checkTableRollupOption(STranslateContext* pCxt, SNodeList* pFuncs) {
|
static int32_t checkTableRollupOption(STranslateContext* pCxt, SNodeList* pFuncs) {
|
||||||
if (NULL == pFuncs) {
|
if (NULL == pFuncs) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2196,6 +2185,113 @@ static int32_t checkTableRollupOption(STranslateContext* pCxt, SNodeList* pFuncs
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t checkTableTagsSchema(STranslateContext* pCxt, SHashObj* pHash, SNodeList* pTags) {
|
||||||
|
int32_t ntags = LIST_LENGTH(pTags);
|
||||||
|
if (0 == ntags) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
} else if (ntags > TSDB_MAX_TAGS) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
int32_t tagsSize = 0;
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
FOREACH(pNode, pTags) {
|
||||||
|
SColumnDefNode* pTag = (SColumnDefNode*)pNode;
|
||||||
|
int32_t len = strlen(pTag->colName);
|
||||||
|
if (NULL != taosHashGet(pHash, pTag->colName, len)) {
|
||||||
|
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && pTag->dataType.type == TSDB_DATA_TYPE_JSON && ntags > 1) {
|
||||||
|
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_ONLY_ONE_JSON_TAG);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
if ((TSDB_DATA_TYPE_VARCHAR == pTag->dataType.type && pTag->dataType.bytes > TSDB_MAX_BINARY_LEN) ||
|
||||||
|
(TSDB_DATA_TYPE_NCHAR == pTag->dataType.type && pTag->dataType.bytes > TSDB_MAX_NCHAR_LEN)) {
|
||||||
|
code = code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = taosHashPut(pHash, pTag->colName, len, &pTag, POINTER_BYTES);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
tagsSize += pTag->dataType.bytes;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code && tagsSize > TSDB_MAX_TAGS_LEN) {
|
||||||
|
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAGS_LENGTH, TSDB_MAX_TAGS_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t checkTableColsSchema(STranslateContext* pCxt, SHashObj* pHash, SNodeList* pCols) {
|
||||||
|
int32_t ncols = LIST_LENGTH(pCols);
|
||||||
|
if (ncols < TSDB_MIN_COLUMNS) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
|
||||||
|
} else if (ncols > TSDB_MAX_COLUMNS) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
int32_t rowSize = 0;
|
||||||
|
SNode* pNode = NULL;
|
||||||
|
FOREACH(pNode, pCols) {
|
||||||
|
SColumnDefNode* pCol = (SColumnDefNode*)pNode;
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
if (TSDB_DATA_TYPE_TIMESTAMP != pCol->dataType.type) {
|
||||||
|
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_FIRST_COLUMN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int32_t len = strlen(pCol->colName);
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != taosHashGet(pHash, pCol->colName, len)) {
|
||||||
|
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
if ((TSDB_DATA_TYPE_VARCHAR == pCol->dataType.type && pCol->dataType.bytes > TSDB_MAX_BINARY_LEN) ||
|
||||||
|
(TSDB_DATA_TYPE_NCHAR == pCol->dataType.type && pCol->dataType.bytes > TSDB_MAX_NCHAR_LEN)) {
|
||||||
|
code = code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = taosHashPut(pHash, pCol->colName, len, &pCol, POINTER_BYTES);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
rowSize += pCol->dataType.bytes;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code && rowSize > TSDB_MAX_BYTES_PER_ROW) {
|
||||||
|
code = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ROW_LENGTH, TSDB_MAX_BYTES_PER_ROW);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t checkTableSchema(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
|
||||||
|
SHashObj* pHash = taosHashInit(LIST_LENGTH(pStmt->pTags) + LIST_LENGTH(pStmt->pCols),
|
||||||
|
taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||||
|
if (NULL == pHash) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = checkTableTagsSchema(pCxt, pHash, pStmt->pTags);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = checkTableColsSchema(pCxt, pHash, pStmt->pCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosHashCleanup(pHash);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
|
static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
|
||||||
int32_t code = checkRangeOption(pCxt, "delay", pStmt->pOptions->delay, TSDB_MIN_ROLLUP_DELAY, TSDB_MAX_ROLLUP_DELAY);
|
int32_t code = checkRangeOption(pCxt, "delay", pStmt->pOptions->delay, TSDB_MIN_ROLLUP_DELAY, TSDB_MAX_ROLLUP_DELAY);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -2211,7 +2307,7 @@ static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt
|
||||||
code = checkTableSmaOption(pCxt, pStmt);
|
code = checkTableSmaOption(pCxt, pStmt);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = checkTableTags(pCxt, pStmt);
|
code = checkTableSchema(pCxt, pStmt);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -3838,6 +3934,10 @@ static int32_t buildDropTableVgroupHashmap(STranslateContext* pCxt, SDropTableCl
|
||||||
goto over;
|
goto over;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code && pClause->ignoreNotExists) {
|
||||||
|
code = TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
*pIsSuperTable = false;
|
*pIsSuperTable = false;
|
||||||
|
|
||||||
SVgroupInfo info = {0};
|
SVgroupInfo info = {0};
|
||||||
|
|
|
@ -129,7 +129,23 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
||||||
case TSDB_CODE_PAR_INVALID_DROP_STABLE:
|
case TSDB_CODE_PAR_INVALID_DROP_STABLE:
|
||||||
return "Cannot drop super table in batch";
|
return "Cannot drop super table in batch";
|
||||||
case TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE:
|
case TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE:
|
||||||
return "start(end) time of query range required or time range too large";
|
return "Start(end) time of query range required or time range too large";
|
||||||
|
case TSDB_CODE_PAR_DUPLICATED_COLUMN:
|
||||||
|
return "Duplicated column names";
|
||||||
|
case TSDB_CODE_PAR_INVALID_TAGS_LENGTH:
|
||||||
|
return "Tags length exceeds max length %d";
|
||||||
|
case TSDB_CODE_PAR_INVALID_ROW_LENGTH:
|
||||||
|
return "Row length exceeds max length %d";
|
||||||
|
case TSDB_CODE_PAR_INVALID_COLUMNS_NUM:
|
||||||
|
return "Illegal number of columns";
|
||||||
|
case TSDB_CODE_PAR_TOO_MANY_COLUMNS:
|
||||||
|
return "Too many columns";
|
||||||
|
case TSDB_CODE_PAR_INVALID_FIRST_COLUMN:
|
||||||
|
return "First column must be timestamp";
|
||||||
|
case TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN:
|
||||||
|
return "Invalid binary/nchar column length";
|
||||||
|
case TSDB_CODE_PAR_INVALID_TAGS_NUM:
|
||||||
|
return "Invalid number of tag columns";
|
||||||
case TSDB_CODE_OUT_OF_MEMORY:
|
case TSDB_CODE_OUT_OF_MEMORY:
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -277,6 +277,11 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
code = nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols);
|
code = nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, fmIsScanPseudoColumnFunc, &pScan->pScanPseudoCols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rewrite the expression in subsequent clauses
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = rewriteExprForSelect(pScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM);
|
||||||
|
}
|
||||||
|
|
||||||
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->pMeta);
|
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->pMeta);
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
|
|
@ -123,14 +123,40 @@ static SNodeList* osdGetAllFuncs(SLogicNode* pNode) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool needOptimizeDataRequire(const SFunctionNode* pFunc) {
|
||||||
|
if (!fmIsSpecialDataRequiredFunc(pFunc->funcId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SNode* pPara = NULL;
|
||||||
|
FOREACH(pPara, pFunc->pParameterList) {
|
||||||
|
if (QUERY_NODE_COLUMN != nodeType(pPara) && QUERY_NODE_VALUE != nodeType(pPara)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool needOptimizeDynamicScan(const SFunctionNode* pFunc) {
|
||||||
|
if (!fmIsDynamicScanOptimizedFunc(pFunc->funcId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SNode* pPara = NULL;
|
||||||
|
FOREACH(pPara, pFunc->pParameterList) {
|
||||||
|
if (QUERY_NODE_COLUMN != nodeType(pPara) && QUERY_NODE_VALUE != nodeType(pPara)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t osdGetRelatedFuncs(SScanLogicNode* pScan, SNodeList** pSdrFuncs, SNodeList** pDsoFuncs) {
|
static int32_t osdGetRelatedFuncs(SScanLogicNode* pScan, SNodeList** pSdrFuncs, SNodeList** pDsoFuncs) {
|
||||||
SNodeList* pAllFuncs = osdGetAllFuncs(pScan->node.pParent);
|
SNodeList* pAllFuncs = osdGetAllFuncs(pScan->node.pParent);
|
||||||
SNode* pFunc = NULL;
|
SNode* pFunc = NULL;
|
||||||
FOREACH(pFunc, pAllFuncs) {
|
FOREACH(pFunc, pAllFuncs) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (fmIsSpecialDataRequiredFunc(((SFunctionNode*)pFunc)->funcId)) {
|
if (needOptimizeDataRequire((SFunctionNode*)pFunc)) {
|
||||||
code = nodesListMakeStrictAppend(pSdrFuncs, nodesCloneNode(pFunc));
|
code = nodesListMakeStrictAppend(pSdrFuncs, nodesCloneNode(pFunc));
|
||||||
} else if (fmIsDynamicScanOptimizedFunc(((SFunctionNode*)pFunc)->funcId)) {
|
} else if (needOptimizeDynamicScan((SFunctionNode*)pFunc)) {
|
||||||
code = nodesListMakeStrictAppend(pDsoFuncs, nodesCloneNode(pFunc));
|
code = nodesListMakeStrictAppend(pDsoFuncs, nodesCloneNode(pFunc));
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
@ -541,9 +567,14 @@ static bool cpdIsPrimaryKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
|
||||||
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
|
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOperatorNode* pOper = (SOperatorNode*)pJoin->pOnConditions;
|
||||||
|
if (OP_TYPE_EQUAL != pOper->opType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets;
|
SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets;
|
||||||
SNodeList* pRightCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1))->pTargets;
|
SNodeList* pRightCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1))->pTargets;
|
||||||
SOperatorNode* pOper = (SOperatorNode*)pJoin->pOnConditions;
|
|
||||||
if (cpdIsPrimaryKey(pOper->pLeft, pLeftCols)) {
|
if (cpdIsPrimaryKey(pOper->pLeft, pLeftCols)) {
|
||||||
return cpdIsPrimaryKey(pOper->pRight, pRightCols);
|
return cpdIsPrimaryKey(pOper->pRight, pRightCols);
|
||||||
} else if (cpdIsPrimaryKey(pOper->pLeft, pRightCols)) {
|
} else if (cpdIsPrimaryKey(pOper->pLeft, pRightCols)) {
|
||||||
|
|
|
@ -20,11 +20,21 @@ using namespace std;
|
||||||
|
|
||||||
class PlanOptimizeTest : public PlannerTestBase {};
|
class PlanOptimizeTest : public PlannerTestBase {};
|
||||||
|
|
||||||
|
TEST_F(PlanOptimizeTest, optimizeScanData) {
|
||||||
|
useDb("root", "test");
|
||||||
|
|
||||||
|
run("SELECT COUNT(*) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT COUNT(c1) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT COUNT(CAST(c1 AS BIGINT)) FROM t1");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
run("select * from t1 order by ts");
|
run("SELECT * FROM t1 ORDER BY ts");
|
||||||
run("select * from t1 order by ts desc");
|
run("SELECT * FROM t1 ORDER BY ts DESC");
|
||||||
run("select c1 from t1 order by ts");
|
run("SELECT c1 FROM t1 ORDER BY ts");
|
||||||
run("select c1 from t1 order by ts desc");
|
run("SELECT c1 FROM t1 ORDER BY ts DESC");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1085,19 +1085,22 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
||||||
case TDMT_VND_CREATE_TABLE_RSP: {
|
case TDMT_VND_CREATE_TABLE_RSP: {
|
||||||
SVCreateTbBatchRsp batchRsp = {0};
|
SVCreateTbBatchRsp batchRsp = {0};
|
||||||
if (msg) {
|
if (msg) {
|
||||||
SCH_ERR_JRET(tDeserializeSVCreateTbBatchRsp(msg, msgSize, &batchRsp));
|
SCoder coder = {0};
|
||||||
if (batchRsp.pArray) {
|
tCoderInit(&coder, TD_LITTLE_ENDIAN, msg, msgSize, TD_DECODER);
|
||||||
int32_t num = taosArrayGetSize(batchRsp.pArray);
|
code = tDecodeSVCreateTbBatchRsp(&coder, &batchRsp);
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
if (TSDB_CODE_SUCCESS == code && batchRsp.nRsps > 0) {
|
||||||
SVCreateTbRsp *rsp = taosArrayGet(batchRsp.pArray, i);
|
for (int32_t i = 0; i < batchRsp.nRsps; ++i) {
|
||||||
|
SVCreateTbRsp *rsp = batchRsp.pRsps + i;
|
||||||
if (NEED_CLIENT_HANDLE_ERROR(rsp->code)) {
|
if (NEED_CLIENT_HANDLE_ERROR(rsp->code)) {
|
||||||
taosArrayDestroy(batchRsp.pArray);
|
tCoderClear(&coder);
|
||||||
SCH_ERR_JRET(rsp->code);
|
SCH_ERR_JRET(rsp->code);
|
||||||
|
} else if (TSDB_CODE_SUCCESS != rsp->code) {
|
||||||
|
code = rsp->code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayDestroy(batchRsp.pArray);
|
|
||||||
}
|
}
|
||||||
|
tCoderClear(&coder);
|
||||||
|
SCH_ERR_JRET(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_ERR_JRET(rspCode);
|
SCH_ERR_JRET(rspCode);
|
||||||
|
@ -1110,13 +1113,14 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
|
||||||
SCoder coder = {0};
|
SCoder coder = {0};
|
||||||
tCoderInit(&coder, TD_LITTLE_ENDIAN, msg, msgSize, TD_DECODER);
|
tCoderInit(&coder, TD_LITTLE_ENDIAN, msg, msgSize, TD_DECODER);
|
||||||
code = tDecodeSVDropTbBatchRsp(&coder, &batchRsp);
|
code = tDecodeSVDropTbBatchRsp(&coder, &batchRsp);
|
||||||
if (TSDB_CODE_SUCCESS == code && batchRsp.pArray) {
|
if (TSDB_CODE_SUCCESS == code && batchRsp.nRsps > 0) {
|
||||||
int32_t num = taosArrayGetSize(batchRsp.pArray);
|
for (int32_t i = 0; i < batchRsp.nRsps; ++i) {
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
SVDropTbRsp *rsp = batchRsp.pRsps + i;
|
||||||
SVDropTbRsp *rsp = taosArrayGet(batchRsp.pArray, i);
|
|
||||||
if (NEED_CLIENT_HANDLE_ERROR(rsp->code)) {
|
if (NEED_CLIENT_HANDLE_ERROR(rsp->code)) {
|
||||||
tCoderClear(&coder);
|
tCoderClear(&coder);
|
||||||
SCH_ERR_JRET(rsp->code);
|
SCH_ERR_JRET(rsp->code);
|
||||||
|
} else if (TSDB_CODE_SUCCESS != rsp->code) {
|
||||||
|
code = rsp->code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2282,7 +2286,7 @@ int32_t schCancelJob(SSchJob *pJob) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void schCloseJobRef(void) {
|
void schCloseJobRef(void) {
|
||||||
if (!atomic_load_8((int8_t*)&schMgmt.exit)) {
|
if (!atomic_load_8((int8_t *)&schMgmt.exit)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2791,7 +2795,7 @@ void schedulerFreeTaskList(SArray *taskList) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void schedulerDestroy(void) {
|
void schedulerDestroy(void) {
|
||||||
atomic_store_8((int8_t*)&schMgmt.exit, 1);
|
atomic_store_8((int8_t *)&schMgmt.exit, 1);
|
||||||
|
|
||||||
if (schMgmt.jobRef >= 0) {
|
if (schMgmt.jobRef >= 0) {
|
||||||
SSchJob *pJob = taosIterateRef(schMgmt.jobRef, 0);
|
SSchJob *pJob = taosIterateRef(schMgmt.jobRef, 0);
|
||||||
|
|
|
@ -443,6 +443,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SCH_STATUS_ERROR, "scheduler status erro
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_SCH_INTERNAL_ERROR, "scheduler internal error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_SCH_INTERNAL_ERROR, "scheduler internal error")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QW_MSG_ERROR, "Invalid msg order")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QW_MSG_ERROR, "Invalid msg order")
|
||||||
|
|
||||||
|
// parser
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_PAR_TABLE_NOT_EXIST, "Table does not exist")
|
||||||
|
|
||||||
//planner
|
//planner
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_PLAN_INTERNAL_ERROR, "planner internal error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_PLAN_INTERNAL_ERROR, "planner internal error")
|
||||||
|
|
||||||
|
|
|
@ -25,15 +25,15 @@ sql insert into tb3 values (now, 3, "Hash (cost=229.20..229.20 rows=101 width=2
|
||||||
sql create table tb4 using st1 tags(4);
|
sql create table tb4 using st1 tags(4);
|
||||||
sql insert into tb4 values (now, 4, "Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)");
|
sql insert into tb4 values (now, 4, "Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)");
|
||||||
|
|
||||||
sql create table tb1 using st2 tags(1);
|
#sql create table tb1 using st2 tags(1);
|
||||||
sql insert into tb1 values (now, 1, "Hash Join (cost=230.47..713.98 rows=101 width=488) (actual time=0.711..7.427 rows=100 loops=1)");
|
#sql insert into tb1 values (now, 1, "Hash Join (cost=230.47..713.98 rows=101 width=488) (actual time=0.711..7.427 rows=100 loops=1)");
|
||||||
|
|
||||||
sql create table tb2 using st2 tags(2);
|
#sql create table tb2 using st2 tags(2);
|
||||||
sql insert into tb2 values (now, 2, "Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.007..2.583 rows=10000 loops=1)");
|
#sql insert into tb2 values (now, 2, "Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.007..2.583 rows=10000 loops=1)");
|
||||||
sql create table tb3 using st2 tags(3);
|
#sql create table tb3 using st2 tags(3);
|
||||||
sql insert into tb3 values (now, 3, "Hash (cost=229.20..229.20 rows=101 width=244) (actual time=0.659..0.659 rows=100 loops=1)");
|
#sql insert into tb3 values (now, 3, "Hash (cost=229.20..229.20 rows=101 width=244) (actual time=0.659..0.659 rows=100 loops=1)");
|
||||||
sql create table tb4 using st2 tags(4);
|
#sql create table tb4 using st2 tags(4);
|
||||||
sql insert into tb4 values (now, 4, "Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)");
|
#sql insert into tb4 values (now, 4, "Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)");
|
||||||
|
|
||||||
|
|
||||||
print ======== step2
|
print ======== step2
|
||||||
|
|
|
@ -65,6 +65,15 @@ sql INSERT INTO dev_002 VALUES('2020-05-13 10:00:00.031', 5)
|
||||||
sql INSERT INTO dev_002 VALUES('2020-05-13 10:00:00.036', 6)
|
sql INSERT INTO dev_002 VALUES('2020-05-13 10:00:00.036', 6)
|
||||||
sql INSERT INTO dev_002 VALUES('2020-05-13 10:00:00.51', 7)
|
sql INSERT INTO dev_002 VALUES('2020-05-13 10:00:00.51', 7)
|
||||||
|
|
||||||
|
# vnode does not return the precision of the table
|
||||||
|
print ====> create database d1 precision 'us'
|
||||||
|
sql create database d1 precision 'us'
|
||||||
|
sql use d1
|
||||||
|
sql create table dev_001 (ts timestamp ,i timestamp ,j int)
|
||||||
|
sql insert into dev_001 values(1623046993681000,now,1)(1623046993681001,now+1s,2)(1623046993681002,now+2s,3)(1623046993681004,now+5s,4)
|
||||||
|
sql create table secondts(ts timestamp,t2 timestamp,i int)
|
||||||
|
sql insert into secondts values(1623046993681000,now,1)(1623046993681001,now+1s,2)(1623046993681002,now+2s,3)(1623046993681004,now+5s,4)
|
||||||
|
|
||||||
$loop_test = 0
|
$loop_test = 0
|
||||||
loop_test_pos:
|
loop_test_pos:
|
||||||
|
|
||||||
|
@ -288,15 +297,6 @@ sql_error sql select count(*) from dev_001 session(ts,0s)
|
||||||
sql_error select count(*) from dev_001 session(i,1y)
|
sql_error select count(*) from dev_001 session(i,1y)
|
||||||
sql_error select count(*) from dev_001 session(ts,1d) where ts <'2020-05-20 0:0:0'
|
sql_error select count(*) from dev_001 session(ts,1d) where ts <'2020-05-20 0:0:0'
|
||||||
|
|
||||||
# vnode does not return the precision of the table
|
|
||||||
print ====> create database d1 precision 'us'
|
|
||||||
sql create database d1 precision 'us'
|
|
||||||
sql use d1
|
|
||||||
sql create table dev_001 (ts timestamp ,i timestamp ,j int)
|
|
||||||
sql insert into dev_001 values(1623046993681000,now,1)(1623046993681001,now+1s,2)(1623046993681002,now+2s,3)(1623046993681004,now+5s,4)
|
|
||||||
sql create table secondts(ts timestamp,t2 timestamp,i int)
|
|
||||||
sql insert into secondts values(1623046993681000,now,1)(1623046993681001,now+1s,2)(1623046993681002,now+2s,3)(1623046993681004,now+5s,4)
|
|
||||||
|
|
||||||
#print ====> select count(*) from dev_001 session(ts,1u)
|
#print ====> select count(*) from dev_001 session(ts,1u)
|
||||||
#sql select _wstartts, count(*) from dev_001 session(ts,1u)
|
#sql select _wstartts, count(*) from dev_001 session(ts,1u)
|
||||||
#print rows: $rows
|
#print rows: $rows
|
||||||
|
|
|
@ -91,9 +91,9 @@ print =============== create normal table
|
||||||
sql create database ndb
|
sql create database ndb
|
||||||
sql use ndb
|
sql use ndb
|
||||||
sql create table nt0 (ts timestamp, i int)
|
sql create table nt0 (ts timestamp, i int)
|
||||||
sql create table if not exists nt0 (ts timestamp, i int)
|
# sql create table if not exists nt0 (ts timestamp, i int)
|
||||||
sql create table nt1 (ts timestamp, i int)
|
sql create table nt1 (ts timestamp, i int)
|
||||||
sql create table if not exists nt1 (ts timestamp, i int)
|
# sql create table if not exists nt1 (ts timestamp, i int)
|
||||||
sql create table if not exists nt3 (ts timestamp, i int)
|
sql create table if not exists nt3 (ts timestamp, i int)
|
||||||
|
|
||||||
sql show tables
|
sql show tables
|
||||||
|
|
Loading…
Reference in New Issue