feat: the length of binary/nchar type value is the same as that of column
This commit is contained in:
parent
427301c1d1
commit
89562acb01
|
@ -81,6 +81,7 @@ typedef struct SValueNode {
|
||||||
char* literal;
|
char* literal;
|
||||||
bool isDuration;
|
bool isDuration;
|
||||||
bool translate;
|
bool translate;
|
||||||
|
bool notReserved;
|
||||||
int16_t placeholderNo;
|
int16_t placeholderNo;
|
||||||
union {
|
union {
|
||||||
bool b;
|
bool b;
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
#include "querynodes.h"
|
|
||||||
#include "builtinsimpl.h"
|
#include "builtinsimpl.h"
|
||||||
|
#include "querynodes.h"
|
||||||
#include "scalar.h"
|
#include "scalar.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "tdatablock.h"
|
#include "tdatablock.h"
|
||||||
|
@ -215,7 +215,7 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
SValueNode* pValue = (SValueNode*) pParamNode;
|
SValueNode* pValue = (SValueNode*)pParamNode;
|
||||||
if (pValue->node.resType.type != TSDB_DATA_TYPE_BIGINT) {
|
if (pValue->node.resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
@ -224,6 +224,8 @@ static int32_t translateTop(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pValue->notReserved = true;
|
||||||
|
|
||||||
SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||||
pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
|
pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -336,7 +338,7 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT };
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +363,7 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
||||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT };
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes, .type = TSDB_DATA_TYPE_BIGINT};
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +394,7 @@ static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[resType].bytes, .type = resType};
|
pFunc->node.resType = (SDataType){.bytes = tDataTypes[resType].bytes, .type = resType};
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +436,7 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
uint8_t colType = pCol->resType.type;
|
uint8_t colType = pCol->resType.type;
|
||||||
if (IS_VAR_DATA_TYPE(colType)) {
|
if (IS_VAR_DATA_TYPE(colType)) {
|
||||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||||
} else {
|
} else {
|
||||||
|
@ -463,7 +465,7 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
uint8_t colType = pCol->resType.type;
|
uint8_t colType = pCol->resType.type;
|
||||||
if (IS_VAR_DATA_TYPE(colType)) {
|
if (IS_VAR_DATA_TYPE(colType)) {
|
||||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||||
} else {
|
} else {
|
||||||
|
@ -500,8 +502,7 @@ static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
||||||
|
|
||||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
if (QUERY_NODE_COLUMN != nodeType(pPara)) {
|
if (QUERY_NODE_COLUMN != nodeType(pPara)) {
|
||||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "The parameters of UNIQUE can only be columns");
|
||||||
"The parameters of UNIQUE can only be columns");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
||||||
|
|
|
@ -112,6 +112,7 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
||||||
COPY_CHAR_POINT_FIELD(literal);
|
COPY_CHAR_POINT_FIELD(literal);
|
||||||
COPY_SCALAR_FIELD(isDuration);
|
COPY_SCALAR_FIELD(isDuration);
|
||||||
COPY_SCALAR_FIELD(translate);
|
COPY_SCALAR_FIELD(translate);
|
||||||
|
COPY_SCALAR_FIELD(notReserved);
|
||||||
COPY_SCALAR_FIELD(placeholderNo);
|
COPY_SCALAR_FIELD(placeholderNo);
|
||||||
COPY_SCALAR_FIELD(typeData);
|
COPY_SCALAR_FIELD(typeData);
|
||||||
COPY_SCALAR_FIELD(unit);
|
COPY_SCALAR_FIELD(unit);
|
||||||
|
|
|
@ -646,12 +646,13 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_VARCHAR:
|
case TSDB_DATA_TYPE_VARCHAR:
|
||||||
case TSDB_DATA_TYPE_VARBINARY: {
|
case TSDB_DATA_TYPE_VARBINARY: {
|
||||||
pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + VARSTR_HEADER_SIZE + 1);
|
pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1);
|
||||||
if (NULL == pVal->datum.p) {
|
if (NULL == pVal->datum.p) {
|
||||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
varDataSetLen(pVal->datum.p, targetDt.bytes);
|
int32_t len = TMIN(targetDt.bytes - VARSTR_HEADER_SIZE, pVal->node.resType.bytes);
|
||||||
strncpy(varDataVal(pVal->datum.p), pVal->literal, targetDt.bytes);
|
varDataSetLen(pVal->datum.p, len);
|
||||||
|
strncpy(varDataVal(pVal->datum.p), pVal->literal, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||||
|
@ -662,19 +663,18 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
int32_t bytes = targetDt.bytes * TSDB_NCHAR_SIZE;
|
pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1);
|
||||||
pVal->datum.p = taosMemoryCalloc(1, bytes + VARSTR_HEADER_SIZE + 1);
|
|
||||||
if (NULL == pVal->datum.p) {
|
if (NULL == pVal->datum.p) {
|
||||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t output = 0;
|
int32_t len = 0;
|
||||||
if (!taosMbsToUcs4(pVal->literal, pVal->node.resType.bytes, (TdUcs4*)varDataVal(pVal->datum.p), bytes,
|
if (!taosMbsToUcs4(pVal->literal, pVal->node.resType.bytes, (TdUcs4*)varDataVal(pVal->datum.p),
|
||||||
&output)) {
|
targetDt.bytes - VARSTR_HEADER_SIZE, &len)) {
|
||||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||||
}
|
}
|
||||||
varDataSetLen(pVal->datum.p, output);
|
varDataSetLen(pVal->datum.p, len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_JSON:
|
case TSDB_DATA_TYPE_JSON:
|
||||||
|
@ -690,8 +690,20 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t calcTypeBytes(SDataType dt) {
|
||||||
|
if (TSDB_DATA_TYPE_BINARY == dt.type) {
|
||||||
|
return dt.bytes + VARSTR_HEADER_SIZE;
|
||||||
|
} else if (TSDB_DATA_TYPE_NCHAR == dt.type) {
|
||||||
|
return dt.bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
|
||||||
|
} else {
|
||||||
|
return dt.bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
return translateValueImpl(pCxt, pVal, pVal->node.resType);
|
SDataType dt = pVal->node.resType;
|
||||||
|
dt.bytes = calcTypeBytes(dt);
|
||||||
|
return translateValueImpl(pCxt, pVal, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isMultiResFunc(SNode* pNode) {
|
static bool isMultiResFunc(SNode* pNode) {
|
||||||
|
@ -2343,16 +2355,6 @@ static int32_t translateAlterDatabase(STranslateContext* pCxt, SAlterDatabaseStm
|
||||||
return buildCmdMsg(pCxt, TDMT_MND_ALTER_DB, (FSerializeFunc)tSerializeSAlterDbReq, &alterReq);
|
return buildCmdMsg(pCxt, TDMT_MND_ALTER_DB, (FSerializeFunc)tSerializeSAlterDbReq, &alterReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t calcTypeBytes(SDataType dt) {
|
|
||||||
if (TSDB_DATA_TYPE_BINARY == dt.type) {
|
|
||||||
return dt.bytes + VARSTR_HEADER_SIZE;
|
|
||||||
} else if (TSDB_DATA_TYPE_NCHAR == dt.type) {
|
|
||||||
return dt.bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
|
|
||||||
} else {
|
|
||||||
return dt.bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t columnDefNodeToField(SNodeList* pList, SArray** pArray) {
|
static int32_t columnDefNodeToField(SNodeList* pList, SArray** pArray) {
|
||||||
*pArray = taosArrayInit(LIST_LENGTH(pList), sizeof(SField));
|
*pArray = taosArrayInit(LIST_LENGTH(pList), sizeof(SField));
|
||||||
SNode* pNode;
|
SNode* pNode;
|
||||||
|
@ -4088,18 +4090,8 @@ static int32_t createValueFromFunction(STranslateContext* pCxt, SFunctionNode* p
|
||||||
return scalarCalculateConstants((SNode*)pFunc, (SNode**)pVal);
|
return scalarCalculateConstants((SNode*)pFunc, (SNode**)pVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t colDataBytesToValueDataBytes(uint8_t type, int32_t bytes) {
|
|
||||||
if (TSDB_DATA_TYPE_VARCHAR == type || TSDB_DATA_TYPE_BINARY == type || TSDB_DATA_TYPE_VARBINARY == type) {
|
|
||||||
return bytes - VARSTR_HEADER_SIZE;
|
|
||||||
} else if (TSDB_DATA_TYPE_NCHAR == type) {
|
|
||||||
return (bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
|
|
||||||
}
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SDataType schemaToDataType(SSchema* pSchema) {
|
static SDataType schemaToDataType(SSchema* pSchema) {
|
||||||
SDataType dt = {.type = pSchema->type, .bytes = pSchema->bytes, .precision = 0, .scale = 0};
|
SDataType dt = {.type = pSchema->type, .bytes = pSchema->bytes, .precision = 0, .scale = 0};
|
||||||
dt.bytes = colDataBytesToValueDataBytes(pSchema->type, pSchema->bytes);
|
|
||||||
return dt;
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -650,6 +650,9 @@ static EDealRes doRewritePrecalcExprs(SNode** pNode, void* pContext) {
|
||||||
SRewritePrecalcExprsCxt* pCxt = (SRewritePrecalcExprsCxt*)pContext;
|
SRewritePrecalcExprsCxt* pCxt = (SRewritePrecalcExprsCxt*)pContext;
|
||||||
switch (nodeType(*pNode)) {
|
switch (nodeType(*pNode)) {
|
||||||
case QUERY_NODE_VALUE: {
|
case QUERY_NODE_VALUE: {
|
||||||
|
if (((SValueNode*)*pNode)->notReserved) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
pCxt->errCode = rewriteValueToOperator(pCxt, pNode);
|
pCxt->errCode = rewriteValueToOperator(pCxt, pNode);
|
||||||
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
||||||
return DEAL_RES_ERROR;
|
return DEAL_RES_ERROR;
|
||||||
|
|
|
@ -50,4 +50,6 @@ TEST_F(PlanBasicTest, func) {
|
||||||
run("SELECT DIFF(c1) FROM t1");
|
run("SELECT DIFF(c1) FROM t1");
|
||||||
|
|
||||||
run("SELECT PERCENTILE(c1, 60) FROM t1");
|
run("SELECT PERCENTILE(c1, 60) FROM t1");
|
||||||
|
|
||||||
|
run("SELECT TOP(c1, 60) FROM t1");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue