提交 308ba7a0 编写于 作者: S Shungang Li

fix: type geometry predicates support

support "=, <>, is null, is not null, in, not in"
上级 05c7ec61
......@@ -66,8 +66,8 @@ int32_t* taosGetErrno();
#define TSDB_CODE_RPC_BROKEN_LINK TAOS_DEF_ERROR_CODE(0, 0x0018) //
#define TSDB_CODE_RPC_TIMEOUT TAOS_DEF_ERROR_CODE(0, 0x0019) //
#define TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED TAOS_DEF_ERROR_CODE(0, 0x0020) // "Vgroup could not be connected"
#define TSDB_CODE_RPC_SOMENODE_BROKEN_LINK TAOS_DEF_ERROR_CODE(0, 0x0021) //
#define TSDB_CODE_RPC_MAX_SESSIONS TAOS_DEF_ERROR_CODE(0, 0x0022) //
#define TSDB_CODE_RPC_SOMENODE_BROKEN_LINK TAOS_DEF_ERROR_CODE(0, 0x0021) //
#define TSDB_CODE_RPC_MAX_SESSIONS TAOS_DEF_ERROR_CODE(0, 0x0022) //
......@@ -277,7 +277,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_MND_INVALID_FUNC_COMMENT TAOS_DEF_ERROR_CODE(0, 0x0378)
#define TSDB_CODE_MND_INVALID_FUNC_RETRIEVE TAOS_DEF_ERROR_CODE(0, 0x0379)
// mnode-db
#define TSDB_CODE_MND_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0380)
......@@ -288,9 +288,9 @@ int32_t* taosGetErrno();
#define TSDB_CODE_MND_TOO_MANY_DATABASES TAOS_DEF_ERROR_CODE(0, 0x0385)
#define TSDB_CODE_MND_DB_IN_DROPPING TAOS_DEF_ERROR_CODE(0, 0x0386) //
// #define TSDB_CODE_MND_VGROUP_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0387) // 2.x
#define TSDB_CODE_MND_DB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0388) //
#define TSDB_CODE_MND_DB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0388) //
#define TSDB_CODE_MND_INVALID_DB_ACCT TAOS_DEF_ERROR_CODE(0, 0x0389) // internal
#define TSDB_CODE_MND_DB_OPTION_UNCHANGED TAOS_DEF_ERROR_CODE(0, 0x038A) //
#define TSDB_CODE_MND_DB_OPTION_UNCHANGED TAOS_DEF_ERROR_CODE(0, 0x038A) //
#define TSDB_CODE_MND_DB_INDEX_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x038B)
#define TSDB_CODE_MND_DB_RETENTION_PERIOD_ZERO TAOS_DEF_ERROR_CODE(0, 0x038C)
// #define TSDB_CODE_MND_INVALID_DB_OPTION_DAYS TAOS_DEF_ERROR_CODE(0, 0x0390) // 2.x
......@@ -516,6 +516,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_QRY_JSON_IN_GROUP_ERROR TAOS_DEF_ERROR_CODE(0, 0x072E)
#define TSDB_CODE_QRY_JOB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x072F)
#define TSDB_CODE_QRY_QWORKER_QUIT TAOS_DEF_ERROR_CODE(0, 0x0730)
#define TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR TAOS_DEF_ERROR_CODE(0, 0x0731)
// grant
#define TSDB_CODE_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0800)
......@@ -777,7 +778,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_TDLITE_IVLD_OPEN_DIR TAOS_DEF_ERROR_CODE(0, 0x5101)
// UTIL
#define TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x6000)
#define TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x6000)
#ifdef __cplusplus
}
......
......@@ -79,6 +79,7 @@ int32_t compareDoubleVal(const void *pLeft, const void *pRight);
int32_t compareLenPrefixedStr(const void *pLeft, const void *pRight);
int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight);
int32_t compareLenBinaryVal(const void *pLeft, const void *pRight);
int32_t comparestrRegexMatch(const void *pLeft, const void *pRight);
int32_t comparestrRegexNMatch(const void *pLeft, const void *pRight);
......
......@@ -2370,6 +2370,10 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys
if (pHandle->vnode) {
SOperatorInfo* pTableScanOp = createTableScanOperatorInfo(pTableScanNode, pHandle, pTableListInfo, pTaskInfo);
if (pTableScanOp == NULL) {
qError("createTableScanOperatorInfo error, errorcode: %d", pTaskInfo->code);
goto _error;
}
STableScanInfo* pTSInfo = (STableScanInfo*)pTableScanOp->info;
if (pHandle->version > 0) {
pTSInfo->base.cond.endVersion = pHandle->version;
......
......@@ -639,6 +639,10 @@ static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFP
ret = indexJsonSearch(arg->ivtIdx, mtm, output->result);
indexMultiTermQueryDestroy(mtm);
} else {
if (left->colValType == TSDB_DATA_TYPE_GEOMETRY || right->colValType == TSDB_DATA_TYPE_GEOMETRY) {
return TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR;
}
bool reverse = false, equal = false;
FilterFunc filterFunc = sifGetFilterFunc(qtype, &reverse, &equal);
......
......@@ -331,6 +331,7 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema,
int64_t iv;
uint64_t uv;
char* endptr = NULL;
int32_t code = TSDB_CODE_SUCCESS;
if (isNullValue(pSchema->type, pToken)) {
if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
......@@ -467,8 +468,7 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema,
break;
}
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_GEOMETRY: {
case TSDB_DATA_TYPE_BINARY: {
// Too long values will raise the invalid sql error message
if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) {
return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
......@@ -478,6 +478,30 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema,
break;
}
case TSDB_DATA_TYPE_GEOMETRY: {
unsigned char* output = NULL;
size_t size = 0;
code = parseGeometry(pToken, &output, &size);
if (code != TSDB_CODE_SUCCESS) {
code = buildSyntaxErrMsg(pMsgBuf, getThreadLocalGeosCtx()->errMsg, pToken->z);
} else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) {
// Too long values will raise the invalid sql error message
code = generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
} else {
val->pData = taosMemoryMalloc(size);
if (NULL == val->pData) {
code = TSDB_CODE_OUT_OF_MEMORY;
} else {
memcpy(val->pData, output, size);
val->nData = size;
}
}
geosFreeBuffer(output);
break;
}
case TSDB_DATA_TYPE_NCHAR: {
int32_t output = 0;
void* p = taosMemoryCalloc(1, pSchema->bytes - VARSTR_HEADER_SIZE);
......@@ -508,7 +532,7 @@ static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema,
}
}
return TSDB_CODE_SUCCESS;
return code;
}
// input pStmt->pSql: [(tag1_name, ...)] TAGS (tag1_value, ...) ...
......@@ -1382,7 +1406,7 @@ static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql,
code = buildSyntaxErrMsg(&pCxt->msg, getThreadLocalGeosCtx()->errMsg, pToken->z);
}
// Too long values will raise the invalid sql error message
else if (size > pSchema->bytes) {
else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) {
code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
}
else {
......
......@@ -8,13 +8,14 @@ target_include_directories(
)
target_link_libraries(scalar
PRIVATE os
PRIVATE util
PRIVATE os
PRIVATE util
PRIVATE common
PRIVATE nodes
PRIVATE function
PRIVATE qcom
PRIVATE parser
PRIVATE geometry
)
if(${BUILD_TEST})
......
......@@ -271,8 +271,9 @@ struct SFilterInfo {
SFilterPCtx pctx;
};
#define FILTER_NO_MERGE_DATA_TYPE(t) \
((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR || (t) == TSDB_DATA_TYPE_JSON)
#define FILTER_NO_MERGE_DATA_TYPE(t) \
((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR || (t) == TSDB_DATA_TYPE_JSON || \
(t) == TSDB_DATA_TYPE_GEOMETRY)
#define FILTER_NO_MERGE_OPTR(o) ((o) == OP_TYPE_IS_NULL || (o) == OP_TYPE_IS_NOT_NULL || (o) == FILTER_DUMMY_EMPTY_OPTR)
#define MR_EMPTY_RES(ctx) (ctx->rs == NULL)
......
......@@ -133,7 +133,7 @@ __compar_fn_t gDataCompare[] = {
setChkInBytes2, setChkInBytes4, setChkInBytes8, comparestrRegexMatch,
comparestrRegexNMatch, setChkNotInBytes1, setChkNotInBytes2, setChkNotInBytes4,
setChkNotInBytes8, compareChkNotInString, comparestrPatternNMatch, comparewcsPatternNMatch,
comparewcsRegexMatch, comparewcsRegexNMatch,
comparewcsRegexMatch, comparewcsRegexNMatch, compareLenBinaryVal
};
__compar_fn_t gInt8SignCompare[] = {compareInt8Val, compareInt8Int16, compareInt8Int32,
......@@ -257,8 +257,7 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
case TSDB_DATA_TYPE_DOUBLE:
comparFn = 5;
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_GEOMETRY: {
case TSDB_DATA_TYPE_BINARY: {
if (optr == OP_TYPE_MATCH) {
comparFn = 19;
} else if (optr == OP_TYPE_NMATCH) {
......@@ -297,6 +296,21 @@ int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
break;
}
case TSDB_DATA_TYPE_GEOMETRY: {
if (optr == OP_TYPE_EQUAL || optr == OP_TYPE_NOT_EQUAL || optr == OP_TYPE_IS_NULL ||
optr == OP_TYPE_IS_NOT_NULL) {
comparFn = 30;
} else if (optr == OP_TYPE_IN) {
comparFn = 8;
} else if (optr == OP_TYPE_NOT_IN) {
comparFn = 25;
} else {
terrno = TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR;
return 0;
}
break;
}
case TSDB_DATA_TYPE_UTINYINT:
comparFn = 11;
break;
......@@ -1042,12 +1056,12 @@ static FORCE_INLINE int32_t filterAddColFieldFromField(SFilterInfo *info, SFilte
int32_t filterAddFieldFromNode(SFilterInfo *info, SNode *node, SFilterFieldId *fid) {
if (node == NULL) {
fltDebug("empty node");
FLT_ERR_RET(TSDB_CODE_APP_ERROR);
goto _return;
}
if (nodeType(node) != QUERY_NODE_COLUMN && nodeType(node) != QUERY_NODE_VALUE &&
nodeType(node) != QUERY_NODE_NODE_LIST) {
FLT_ERR_RET(TSDB_CODE_APP_ERROR);
goto _return;
}
int32_t type;
......@@ -1063,6 +1077,7 @@ int32_t filterAddFieldFromNode(SFilterInfo *info, SNode *node, SFilterFieldId *f
filterAddField(info, v, NULL, type, fid, 0, true, NULL);
_return:
return TSDB_CODE_SUCCESS;
}
......@@ -1948,33 +1963,15 @@ int32_t fltInitValFieldData(SFilterInfo *info) {
}
SDataType *dType = &var->node.resType;
size_t bytes = 0;
if (type == TSDB_DATA_TYPE_BINARY) {
size_t len = (dType->type == TSDB_DATA_TYPE_BINARY || dType->type == TSDB_DATA_TYPE_NCHAR) ? dType->bytes
: MAX_NUM_STR_SIZE;
bytes = len + 1 + VARSTR_HEADER_SIZE;
fi->data = taosMemoryCalloc(1, bytes);
} else if (type == TSDB_DATA_TYPE_NCHAR) {
size_t len = (dType->type == TSDB_DATA_TYPE_BINARY || dType->type == TSDB_DATA_TYPE_NCHAR) ? dType->bytes
: MAX_NUM_STR_SIZE;
bytes = (len + 1) * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
fi->data = taosMemoryCalloc(1, bytes);
} else {
fi->data = taosMemoryCalloc(1, sizeof(int64_t));
}
if (dType->type == type) {
size_t bufBytes = TMAX(dType->bytes, sizeof(int64_t));
fi->data = taosMemoryCalloc(1, bufBytes);
assignVal(fi->data, nodesGetValueFromNode(var), dType->bytes, type);
} else {
SScalarParam out = {.columnData = taosMemoryCalloc(1, sizeof(SColumnInfoData))};
out.columnData->info.type = type;
out.columnData->info.precision = precision;
if (IS_VAR_DATA_TYPE(type)) {
out.columnData->info.bytes = bytes;
} else {
if (!IS_VAR_DATA_TYPE(type)) {
out.columnData->info.bytes = tDataTypes[type].bytes;
}
......@@ -1985,7 +1982,13 @@ int32_t fltInitValFieldData(SFilterInfo *info) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
memcpy(fi->data, out.columnData->pData, out.columnData->info.bytes);
size_t bufBytes = IS_VAR_DATA_TYPE(type) ? varDataTLen(out.columnData->pData)
: TMAX(out.columnData->info.bytes, sizeof(int64_t));
fi->data = taosMemoryCalloc(1, bufBytes);
size_t valBytes = IS_VAR_DATA_TYPE(type) ? varDataTLen(out.columnData->pData) : out.columnData->info.bytes;
memcpy(fi->data, out.columnData->pData, valBytes);
colDataDestroy(out.columnData);
taosMemoryFree(out.columnData);
}
......@@ -2751,6 +2754,7 @@ int32_t filterPostProcessRange(SFilterInfo *info) {
}
int32_t filterGenerateComInfo(SFilterInfo *info) {
terrno = 0;
info->cunits = taosMemoryMalloc(info->unitNum * sizeof(*info->cunits));
info->blkUnitRes = taosMemoryMalloc(sizeof(*info->blkUnitRes) * info->unitNum);
info->blkUnits = taosMemoryMalloc(sizeof(*info->blkUnits) * (info->unitNum + 1) * info->groupNum);
......@@ -2758,7 +2762,7 @@ int32_t filterGenerateComInfo(SFilterInfo *info) {
for (uint32_t i = 0; i < info->unitNum; ++i) {
SFilterUnit *unit = &info->units[i];
info->cunits[i].func = filterGetCompFuncIdx(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr);
info->cunits[i].func = filterGetCompFuncIdx(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr); // set terrno if err
info->cunits[i].rfunc = filterGetRangeCompFuncFromOptrs(unit->compare.optr, unit->compare.optr2);
info->cunits[i].optr = FILTER_UNIT_OPTR(unit);
info->cunits[i].colData = NULL;
......@@ -2779,7 +2783,7 @@ int32_t filterGenerateComInfo(SFilterInfo *info) {
info->cunits[i].dataType = FILTER_UNIT_DATA_TYPE(unit);
}
return TSDB_CODE_SUCCESS;
return terrno;
}
int32_t filterUpdateComUnits(SFilterInfo *info) {
......@@ -3336,6 +3340,7 @@ int32_t filterSetExecFunc(SFilterInfo *info) {
}
int32_t filterPreprocess(SFilterInfo *info) {
int32_t code = TSDB_CODE_SUCCESS;
SFilterGroupCtx **gRes = taosMemoryCalloc(info->groupNum, sizeof(SFilterGroupCtx *));
int32_t gResNum = 0;
......@@ -3361,7 +3366,7 @@ int32_t filterPreprocess(SFilterInfo *info) {
filterRewrite(info, gRes, gResNum);
filterGenerateComInfo(info);
FLT_ERR_JRET(filterGenerateComInfo(info));
_return:
......@@ -3373,7 +3378,7 @@ _return:
taosMemoryFreeClear(gRes);
return TSDB_CODE_SUCCESS;
return code;
}
int32_t fltSetColFieldDataImpl(SFilterInfo *info, void *param, filer_get_col_from_id fp, bool fromColId) {
......@@ -4290,30 +4295,27 @@ EDealRes fltReviseRewriter(SNode **pNode, void *pContext) {
return DEAL_RES_ERROR;
}
SColumnNode *refNode = (SColumnNode *)node->pLeft;
SExprNode *exprNode = NULL;
if (OP_TYPE_IN != node->opType) {
SColumnNode *refNode = (SColumnNode *)node->pLeft;
SValueNode *valueNode = (SValueNode *)node->pRight;
if (FILTER_GET_FLAG(stat->info->options, FLT_OPTION_TIMESTAMP) &&
TSDB_DATA_TYPE_UBIGINT == valueNode->node.resType.type && valueNode->datum.u <= INT64_MAX) {
valueNode->node.resType.type = TSDB_DATA_TYPE_BIGINT;
}
int32_t type = vectorGetConvertType(refNode->node.resType.type, valueNode->node.resType.type);
if (0 != type && type != refNode->node.resType.type) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
}
exprNode = &valueNode->node;
} else {
SColumnNode *refNode = (SColumnNode *)node->pLeft;
SNodeListNode *listNode = (SNodeListNode *)node->pRight;
if (LIST_LENGTH(listNode->pNodeList) > 10) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
}
int32_t type = vectorGetConvertType(refNode->node.resType.type, listNode->node.resType.type);
if (0 != type && type != refNode->node.resType.type) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
}
exprNode = &listNode->node;
}
int32_t type = vectorGetConvertType(refNode->node.resType.type, exprNode->resType.type);
if (0 != type && type != refNode->node.resType.type) {
stat->scalarMode = true;
return DEAL_RES_CONTINUE;
}
}
......@@ -4664,7 +4666,7 @@ bool filterExecute(SFilterInfo *info, SSDataBlock *pSrc, SColumnInfoData **p, SC
code = scalarCalculate(info->sclCtx.node, pList, &output);
taosArrayDestroy(pList);
FLT_ERR_RET(code);
FLT_ERR_RET(code); // TODO: current errcode returns as true
*p = output.columnData;
......
......@@ -26,6 +26,7 @@
#include "tdataformat.h"
#include "ttime.h"
#include "ttypes.h"
#include "geosWrapper.h"
#define LEFT_COL ((pLeftCol->info.type == TSDB_DATA_TYPE_JSON ? (void *)pLeftCol : pLeftCol->pData))
#define RIGHT_COL ((pRightCol->info.type == TSDB_DATA_TYPE_JSON ? (void *)pRightCol : pRightCol->pData))
......@@ -378,6 +379,31 @@ static FORCE_INLINE void ncharToVar(char *buf, SScalarParam *pOut, int32_t rowIn
taosMemoryFree(t);
}
// todo remove this malloc
static FORCE_INLINE void varToGeometry(char *buf, SScalarParam *pOut, int32_t rowIndex, int32_t *overflow) {
//[ToDo] support to parse WKB as well as WKT
unsigned char *t = NULL;
size_t len = 0;
if (initCtxGeomFromText()) {
sclError("failed to init geometry ctx");
return;
}
if (doGeomFromText(buf, &t, &len)) {
sclDebug("failed to convert text to geometry");
return;
}
char *output = taosMemoryCalloc(1, len + VARSTR_HEADER_SIZE);
memcpy(output + VARSTR_HEADER_SIZE, t, len);
varDataSetLen(output, len);
colDataSetVal(pOut->columnData, rowIndex, output, false);
taosMemoryFree(output);
geosFreeBuffer(t);
}
// TODO opt performance, tmp is not needed.
int32_t vectorConvertFromVarData(SSclVectorConvCtx *pCtx, int32_t *overflow) {
bool vton = false;
......@@ -401,6 +427,8 @@ int32_t vectorConvertFromVarData(SSclVectorConvCtx *pCtx, int32_t *overflow) {
vton = true;
} else if (TSDB_DATA_TYPE_TIMESTAMP == pCtx->outType) {
func = varToTimestamp;
} else if (TSDB_DATA_TYPE_GEOMETRY == pCtx->outType) {
func = varToGeometry;
} else {
sclError("invalid convert outType:%d, inType:%d", pCtx->outType, pCtx->inType);
return TSDB_CODE_APP_ERROR;
......@@ -881,7 +909,7 @@ int32_t vectorConvertSingleColImpl(const SScalarParam *pIn, SScalarParam *pOut,
}
int8_t gConvertTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = {
/* NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON GEOM VARB DECI BLOB MEDB*/
/* NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM*/
/*NULL*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/*BOOL*/ 0, 0, 2, 3, 4, 5, 6, 7, 5, 9, 7, 11, 12, 13, 14, 0, 7, 0, 0, 0, 0,
/*TINY*/ 0, 0, 0, 3, 4, 5, 6, 7, 5, 9, 7, 3, 4, 5, 7, 0, 7, 0, 0, 0, 0,
......@@ -890,7 +918,7 @@ int8_t gConvertTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = {
/*BIGI*/ 0, 0, 0, 0, 0, 0, 6, 7, 5, 9, 7, 5, 5, 5, 7, 0, 7, 0, 0, 0, 0,
/*FLOA*/ 0, 0, 0, 0, 0, 0, 0, 7, 7, 6, 7, 6, 6, 6, 6, 0, 7, 0, 0, 0, 0,
/*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 0, 0, 0,
/*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0,
/*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 0, 0, 0, 0, 20,
/*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 7, 0, 7, 0, 0, 0, 0,
/*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0,
/*UTIN*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 0, 7, 0, 0, 0, 0,
......
......@@ -225,6 +225,23 @@ int32_t compareLenPrefixedWStrDesc(const void *pLeft, const void *pRight) {
return compareLenPrefixedWStr(pRight, pLeft);
}
int32_t compareLenBinaryVal(const void *pLeft, const void *pRight) {
int32_t len1 = varDataLen(pLeft);
int32_t len2 = varDataLen(pRight);
int32_t minLen = TMIN(len1, len2);
int32_t ret = memcmp(varDataVal(pLeft), varDataVal(pRight), minLen);
if (ret == 0) {
if (len1 == len2) {
return 0;
} else {
return len1 > len2 ? 1 : -1;
}
} else {
return ret > 0 ? 1 : -1;
}
}
// string > number > bool > null
// ref: https://dev.mysql.com/doc/refman/8.0/en/json.html#json-comparison
int32_t compareJsonVal(const void *pLeft, const void *pRight) {
......
......@@ -405,6 +405,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JSON_NOT_SUPPORT_ERROR, "Json not support in t
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JSON_IN_GROUP_ERROR, "Json not support in group/partition by")
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_JOB_NOT_EXIST, "Job not exist")
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_QWORKER_QUIT, "Vnode/Qnode is quitting")
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_GEO_NOT_SUPPORT_ERROR, "Geometry not support in this operator")
// grant
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册