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;
|
||||
bool isDuration;
|
||||
bool translate;
|
||||
bool notReserved;
|
||||
int16_t placeholderNo;
|
||||
union {
|
||||
bool b;
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
*/
|
||||
|
||||
#include "builtins.h"
|
||||
#include "querynodes.h"
|
||||
#include "builtinsimpl.h"
|
||||
#include "querynodes.h"
|
||||
#include "scalar.h"
|
||||
#include "taoserror.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);
|
||||
}
|
||||
|
||||
SValueNode* pValue = (SValueNode*) pParamNode;
|
||||
SValueNode* pValue = (SValueNode*)pParamNode;
|
||||
if (pValue->node.resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||
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);
|
||||
}
|
||||
|
||||
pValue->notReserved = true;
|
||||
|
||||
SDataType* pType = &((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
pFunc->node.resType = (SDataType){.bytes = pType->bytes, .type = pType->type};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -336,7 +338,7 @@ static int32_t translateStateCount(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -361,7 +363,7 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -434,7 +436,7 @@ static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
}
|
||||
|
||||
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)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
} else {
|
||||
|
@ -463,7 +465,7 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
|||
}
|
||||
|
||||
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)) {
|
||||
pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType};
|
||||
} else {
|
||||
|
@ -500,8 +502,7 @@ static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
if (QUERY_NODE_COLUMN != nodeType(pPara)) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"The parameters of UNIQUE can only be columns");
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "The parameters of UNIQUE can only be columns");
|
||||
}
|
||||
|
||||
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
||||
|
|
|
@ -112,6 +112,7 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
|||
COPY_CHAR_POINT_FIELD(literal);
|
||||
COPY_SCALAR_FIELD(isDuration);
|
||||
COPY_SCALAR_FIELD(translate);
|
||||
COPY_SCALAR_FIELD(notReserved);
|
||||
COPY_SCALAR_FIELD(placeholderNo);
|
||||
COPY_SCALAR_FIELD(typeData);
|
||||
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_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) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
varDataSetLen(pVal->datum.p, targetDt.bytes);
|
||||
strncpy(varDataVal(pVal->datum.p), pVal->literal, targetDt.bytes);
|
||||
int32_t len = TMIN(targetDt.bytes - VARSTR_HEADER_SIZE, pVal->node.resType.bytes);
|
||||
varDataSetLen(pVal->datum.p, len);
|
||||
strncpy(varDataVal(pVal->datum.p), pVal->literal, len);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
|
@ -662,19 +663,18 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
|
|||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int32_t bytes = targetDt.bytes * TSDB_NCHAR_SIZE;
|
||||
pVal->datum.p = taosMemoryCalloc(1, bytes + VARSTR_HEADER_SIZE + 1);
|
||||
pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1);
|
||||
if (NULL == pVal->datum.p) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||
;
|
||||
}
|
||||
|
||||
int32_t output = 0;
|
||||
if (!taosMbsToUcs4(pVal->literal, pVal->node.resType.bytes, (TdUcs4*)varDataVal(pVal->datum.p), bytes,
|
||||
&output)) {
|
||||
int32_t len = 0;
|
||||
if (!taosMbsToUcs4(pVal->literal, pVal->node.resType.bytes, (TdUcs4*)varDataVal(pVal->datum.p),
|
||||
targetDt.bytes - VARSTR_HEADER_SIZE, &len)) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
}
|
||||
varDataSetLen(pVal->datum.p, output);
|
||||
varDataSetLen(pVal->datum.p, len);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_JSON:
|
||||
|
@ -690,8 +690,20 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD
|
|||
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) {
|
||||
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) {
|
||||
|
@ -2343,16 +2355,6 @@ static int32_t translateAlterDatabase(STranslateContext* pCxt, SAlterDatabaseStm
|
|||
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) {
|
||||
*pArray = taosArrayInit(LIST_LENGTH(pList), sizeof(SField));
|
||||
SNode* pNode;
|
||||
|
@ -4088,18 +4090,8 @@ static int32_t createValueFromFunction(STranslateContext* pCxt, SFunctionNode* p
|
|||
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) {
|
||||
SDataType dt = {.type = pSchema->type, .bytes = pSchema->bytes, .precision = 0, .scale = 0};
|
||||
dt.bytes = colDataBytesToValueDataBytes(pSchema->type, pSchema->bytes);
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
|
|
@ -650,6 +650,9 @@ static EDealRes doRewritePrecalcExprs(SNode** pNode, void* pContext) {
|
|||
SRewritePrecalcExprsCxt* pCxt = (SRewritePrecalcExprsCxt*)pContext;
|
||||
switch (nodeType(*pNode)) {
|
||||
case QUERY_NODE_VALUE: {
|
||||
if (((SValueNode*)*pNode)->notReserved) {
|
||||
break;
|
||||
}
|
||||
pCxt->errCode = rewriteValueToOperator(pCxt, pNode);
|
||||
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
||||
return DEAL_RES_ERROR;
|
||||
|
|
|
@ -50,4 +50,6 @@ TEST_F(PlanBasicTest, func) {
|
|||
run("SELECT DIFF(c1) FROM t1");
|
||||
|
||||
run("SELECT PERCENTILE(c1, 60) FROM t1");
|
||||
|
||||
run("SELECT TOP(c1, 60) FROM t1");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue