提交 de50a2d7 编写于 作者: weixin_48148422's avatar weixin_48148422

TD-97: parse tbname criteria

上级 ecad71a1
......@@ -696,7 +696,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pQueryMsg->slidingTimeUnit = pQueryInfo->slidingTimeUnit;
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
pQueryMsg->numOfTags = htonl(numOfTags);
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
pQueryMsg->queryType = htons(pQueryInfo->type);
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
......@@ -915,6 +915,14 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
}
}
if (pQueryInfo->tagCond.tbnameCond.cond == NULL) {
*pMsg = 0;
pMsg++;
} else {
strcpy(pMsg, pQueryInfo->tagCond.tbnameCond.cond);
pMsg += strlen(pQueryInfo->tagCond.tbnameCond.cond) + 1;
}
// tbname in/like query expression should be sent to mgmt node
msgLen = pMsg - pStart;
......
......@@ -141,16 +141,17 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
#define TSDB_RELATION_GREATER_EQUAL 5
#define TSDB_RELATION_NOT_EQUAL 6
#define TSDB_RELATION_LIKE 7
#define TSDB_RELATION_IN 8
#define TSDB_RELATION_AND 8
#define TSDB_RELATION_OR 9
#define TSDB_RELATION_NOT 10
#define TSDB_RELATION_AND 9
#define TSDB_RELATION_OR 10
#define TSDB_RELATION_NOT 11
#define TSDB_BINARY_OP_ADD 11
#define TSDB_BINARY_OP_SUBTRACT 12
#define TSDB_BINARY_OP_MULTIPLY 13
#define TSDB_BINARY_OP_DIVIDE 14
#define TSDB_BINARY_OP_REMAINDER 15
#define TSDB_BINARY_OP_ADD 12
#define TSDB_BINARY_OP_SUBTRACT 13
#define TSDB_BINARY_OP_MULTIPLY 14
#define TSDB_BINARY_OP_DIVIDE 15
#define TSDB_BINARY_OP_REMAINDER 16
#define TSDB_USERID_LEN 9
#define TS_PATH_DELIMITER_LEN 1
......
......@@ -470,6 +470,7 @@ typedef struct {
int64_t offset;
uint16_t queryType; // denote another query process
int16_t numOfOutput; // final output columns numbers
int16_t tagNameRelType; // relation of tag criteria and tbname criteria
int16_t interpoType; // interpolate type
uint64_t defaultVal; // default value array list
......
......@@ -279,8 +279,17 @@ SArray *tsdbGetTableList(TsdbQueryHandleT *pQueryHandle);
* @param pTagCond. tag query condition
*
*/
int32_t tsdbQueryByTagsCond(TsdbRepoT *tsdb, int64_t uid, const char *pTagCond, size_t len, STableGroupInfo *pGroupList,
SColIndex *pColIndex, int32_t numOfCols);
int32_t tsdbQueryByTagsCond(
TsdbRepoT *tsdb,
int64_t uid,
const char *pTagCond,
size_t len,
int16_t tagNameRelType,
const char* tbnameCond,
STableGroupInfo *pGroupList,
SColIndex *pColIndex,
int32_t numOfCols
);
int32_t tsdbGetOneTableGroup(TsdbRepoT *tsdb, int64_t uid, STableGroupInfo *pGroupInfo);
......
......@@ -35,6 +35,7 @@ enum {
TSQL_NODE_EXPR = 0x1,
TSQL_NODE_COL = 0x2,
TSQL_NODE_VALUE = 0x4,
TSQL_NODE_ARRAY = 0x8,
};
typedef bool (*__result_filter_fn_t)(const void *, void *);
......@@ -70,6 +71,7 @@ typedef struct tExprNode {
struct tExprNode *pRight; // right child pointer
} _node;
struct SSchema *pSchema;
SArray* array;
tVariant * pVal;
};
} tExprNode;
......@@ -91,7 +93,8 @@ uint8_t getBinaryExprOptr(SSQLToken *pToken);
SBuffer exprTreeToBinary(tExprNode* pExprTree);
int32_t exprTreeFromBinary(const void* pBuf, size_t size, tExprNode** pExprNode);
tExprNode* exprTreeFromBinary(const void* pBuf, size_t size);
tExprNode* exprTreeFromTableName(const char* tbnameCond);
#ifdef __cplusplus
}
......
......@@ -460,6 +460,9 @@ void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
free((*pExpr)->pVal);
} else if ((*pExpr)->nodeType == TSQL_NODE_COL) {
free((*pExpr)->pSchema);
} else if ((*pExpr)->nodeType == TSQL_NODE_ARRAY) {
// BUGBUG: memory leak, need free elements in the array
taosArrayDestroy((*pExpr)->array);
}
free(*pExpr);
......@@ -620,6 +623,8 @@ static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t ty
// DEFAULT_COMP(p1, p2);
//}
// develop_old mgmtSTableQuery for merge & intersect
int32_t merge(SArray *pLeft, SArray *pRight, SArray *pFinalRes) {
// assert(pFinalRes->pRes == 0);
//
......@@ -858,7 +863,7 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
tExprTreeTraverse(pSecond, NULL, result, param);
}
} else { // column project
assert(pLeft->nodeType == TSQL_NODE_COL && pRight->nodeType == TSQL_NODE_VALUE);
assert(pLeft->nodeType == TSQL_NODE_COL && (pRight->nodeType == TSQL_NODE_VALUE || pRight->nodeType == TSQL_NODE_ARRAY));
param->setupInfoFn(pExpr, param->pExtInfo);
if (pSkipList == NULL) {
......@@ -1032,49 +1037,141 @@ SBuffer exprTreeToBinary(tExprNode* pExprTree) {
return buf;
}
static void exprTreeFromBinaryImpl(tExprNode** pExprTree, SBuffer* pBuf) {
static tExprNode* exprTreeFromBinaryImpl(SBuffer* pBuf) {
tExprNode* pExpr = calloc(1, sizeof(tExprNode));
tbufReadToBuffer(pBuf, &pExpr->nodeType, sizeof(pExpr->nodeType));
pExpr->nodeType = tbufReadUint8(pBuf);
if (pExpr->nodeType == TSQL_NODE_VALUE) {
tVariant* pVal = calloc(1, sizeof(tVariant));
if (pVal == NULL) {
// TODO:
}
pExpr->pVal = pVal;
tbufReadToBuffer(pBuf, &pVal->nType, sizeof(pVal->nType));
pVal->nType = tbufReadUint32(pBuf);
if (pVal->nType == TSDB_DATA_TYPE_BINARY) {
tbufReadToBuffer(pBuf, &pVal->nLen, sizeof(pVal->nLen));
pVal->pz = calloc(1, pVal->nLen + 1);
tbufReadToBuffer(pBuf, pVal->pz, pVal->nLen);
} else {
tbufReadToBuffer(pBuf, &pVal->pz, sizeof(pVal->i64Key));
pVal->i64Key = tbufReadInt64(pBuf);
}
pExpr->pVal = pVal;
} else if (pExpr->nodeType == TSQL_NODE_COL) {
SSchema* pSchema = calloc(1, sizeof(SSchema));
tbufReadToBuffer(pBuf, &pSchema->colId, sizeof(pSchema->colId));
tbufReadToBuffer(pBuf, &pSchema->bytes, sizeof(pSchema->bytes));
tbufReadToBuffer(pBuf, &pSchema->type, sizeof(pSchema->type));
if (pSchema == NULL) {
// TODO:
}
pExpr->pSchema = pSchema;
pSchema->colId = tbufReadInt16(pBuf);
pSchema->bytes = tbufReadInt16(pBuf);
pSchema->type = tbufReadUint8(pBuf);
tbufReadToString(pBuf, pSchema->name, TSDB_COL_NAME_LEN);
pExpr->pSchema = pSchema;
} else if (pExpr->nodeType == TSQL_NODE_EXPR) {
tbufReadToBuffer(pBuf, &pExpr->_node.optr, sizeof(pExpr->_node.optr));
tbufReadToBuffer(pBuf, &pExpr->_node.hasPK, sizeof(pExpr->_node.hasPK));
exprTreeFromBinaryImpl(&pExpr->_node.pLeft, pBuf);
exprTreeFromBinaryImpl(&pExpr->_node.pRight, pBuf);
pExpr->_node.optr = tbufReadUint8(pBuf);
pExpr->_node.hasPK = tbufReadUint8(pBuf);
pExpr->_node.pLeft = exprTreeFromBinaryImpl(pBuf);
pExpr->_node.pRight = exprTreeFromBinaryImpl(pBuf);
assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL);
}
*pExprTree = pExpr;
return pExpr;
}
int32_t exprTreeFromBinary(const void* pBuf, size_t size, tExprNode** pExprNode) {
tExprNode* exprTreeFromBinary(const void* pBuf, size_t size) {
if (size == 0) {
return NULL;
}
SBuffer rbuf = {0};
/*int32_t code =*/ tbufBeginRead(&rbuf, pBuf, size);
exprTreeFromBinaryImpl(pExprNode, &rbuf);
return TSDB_CODE_SUCCESS;
tbufBeginRead(&rbuf, pBuf, size);
return exprTreeFromBinaryImpl(&rbuf);
}
static int cmpStrInArray(const void* a, const void* b) {
const char* x = *(const char**)a;
const char* y = *(const char**)b;
return strcmp(x, y);
}
tExprNode* exprTreeFromTableName(const char* tbnameCond) {
if (!tbnameCond) {
return NULL;
}
tExprNode* expr = calloc(1, sizeof(tExprNode));
if (expr == NULL) {
// TODO:
}
expr->nodeType = TSQL_NODE_EXPR;
tExprNode* left = calloc(1, sizeof(tExprNode));
if (left == NULL) {
// TODO:
}
expr->_node.pLeft = left;
left->nodeType = TSQL_NODE_COL;
SSchema* pSchema = calloc(1, sizeof(SSchema));
if (pSchema == NULL) {
// TODO:
}
left->pSchema = pSchema;
pSchema->type = TSDB_DATA_TYPE_BINARY;
pSchema->bytes = TSDB_TABLE_NAME_LEN;
strcpy(pSchema->name, TSQL_TBNAME_L);
pSchema->colId = -1;
tExprNode* right = calloc(1, sizeof(tExprNode));
if (right == NULL) {
// TODO
}
expr->_node.pRight = right;
if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN) == 0) {
expr->_node.optr = TSDB_RELATION_LIKE;
tVariant* pVal = calloc(1, sizeof(tVariant));
if (pVal == NULL) {
// TODO:
}
right->pVal = pVal;
pVal->nType = TSDB_DATA_TYPE_BINARY;
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_LIKE_LEN) + 1;
pVal->pz = malloc(len);
if (pVal->pz == NULL) {
// TODO:
}
memcpy(pVal->pz, tbnameCond + QUERY_COND_REL_PREFIX_LIKE_LEN, len);
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) {
expr->_node.optr = TSDB_RELATION_IN;
right->array = taosArrayInit(2, sizeof(char*));
const char* cond = tbnameCond + QUERY_COND_REL_PREFIX_IN_LEN;
for (const char *e = cond; *e != 0; e++) {
if (*e == ',') {
size_t len = e - cond + 1;
char* p = malloc( len );
memcpy(p, cond, len);
p[len - 1] = 0;
cond += len;
taosArrayPush(right->array, &p);
}
}
if (*cond != 0) {
size_t len = strlen(cond) + 1;
char* p = malloc( len );
memcpy(p, cond, len);
p[len - 1] = 0;
taosArrayPush(right->array, &p);
}
taosArraySort(right->array, cmpStrInArray);
}
return expr;
}
\ No newline at end of file
......@@ -5286,6 +5286,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
pQueryMsg->order = htons(pQueryMsg->order);
pQueryMsg->orderColId = htons(pQueryMsg->orderColId);
pQueryMsg->queryType = htons(pQueryMsg->queryType);
pQueryMsg->tagNameRelType = htons(pQueryMsg->tagNameRelType);
pQueryMsg->numOfCols = htons(pQueryMsg->numOfCols);
pQueryMsg->numOfOutput = htons(pQueryMsg->numOfOutput);
......@@ -5450,6 +5451,12 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
}
}
if (*pMsg != 0) {
size_t len = strlen(pMsg);
*tbnameCond = malloc(len + 1);
strcpy(*tbnameCond, pMsg);
}
qTrace("qmsg:%p query on %d table(s), qrange:%" PRId64 "-%" PRId64
", numOfGroupbyTagCols:%d, ts order:%d, "
"outputCols:%d, numOfCols:%d, interval:%d" PRId64 ", fillType:%d, comptsLen:%d, limit:%" PRId64
......@@ -6047,13 +6054,13 @@ int32_t qCreateQueryInfo(void *tsdb, SQueryTableMsg *pQueryMsg, qinfo_t *pQInfo)
int32_t code = TSDB_CODE_SUCCESS;
char * tagCond = NULL;
char * tagCond = NULL, *tbnameCond = NULL;
SArray * pTableIdList = NULL;
SSqlFuncMsg **pExprMsg = NULL;
SColIndex * pGroupColIndex = NULL;
SColumnInfo* pTagColumnInfo = NULL;
if ((code = convertQueryMsg(pQueryMsg, &pTableIdList, &pExprMsg, &tagCond, &pGroupColIndex, &pTagColumnInfo)) !=
if ((code = convertQueryMsg(pQueryMsg, &pTableIdList, &pExprMsg, &tagCond, &tbnameCond, &pGroupColIndex, &pTagColumnInfo)) !=
TSDB_CODE_SUCCESS) {
return code;
}
......@@ -6089,7 +6096,7 @@ int32_t qCreateQueryInfo(void *tsdb, SQueryTableMsg *pQueryMsg, qinfo_t *pQInfo)
STableId *id = taosArrayGet(pTableIdList, 0);
id->uid = -1; // todo fix me
/*int32_t ret =*/tsdbQueryByTagsCond(tsdb, id->uid, tagCond, pQueryMsg->tagCondLen, &groupInfo, pGroupColIndex,
/*int32_t ret =*/tsdbQueryByTagsCond(tsdb, id->uid, tagCond, pQueryMsg->tagCondLen, pQueryMsg->tagNameRelType, tbnameCond, &groupInfo, pGroupColIndex,
pQueryMsg->numOfGroupCols);
if (groupInfo.numOfTables == 0) { // no qualified tables no need to do query
code = TSDB_CODE_SUCCESS;
......@@ -6112,6 +6119,8 @@ int32_t qCreateQueryInfo(void *tsdb, SQueryTableMsg *pQueryMsg, qinfo_t *pQInfo)
code = initQInfo(pQueryMsg, tsdb, *pQInfo, isSTableQuery);
_query_over:
tfree(tagCond);
tfree(tbnameCond);
taosArrayDestroy(pTableIdList);
// if failed to add ref for all meters in this query, abort current query
......
......@@ -1327,12 +1327,9 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
}
if (numOfOrderCols == 0 || size == 1) { // no group by tags clause or only one table
size_t num = taosArrayGetSize(pTableList);
SArray* sa = taosArrayInit(num, sizeof(SPair));
for(int32_t i = 0; i < num; ++i) {
SArray* sa = taosArrayInit(size, sizeof(SPair));
for(int32_t i = 0; i < size; ++i) {
STable* pTable = taosArrayGetP(pTableList, i);
SPair p = {.first = pTable};
taosArrayPush(sa, &p);
}
......@@ -1393,6 +1390,9 @@ bool tSkipListNodeFilterCallback(const void* pNode, void* param) {
case TSDB_RELATION_LIKE: {
return ret == 0;
}
case TSDB_RELATION_IN: {
}
default:
assert(false);
......@@ -1400,6 +1400,7 @@ bool tSkipListNodeFilterCallback(const void* pNode, void* param) {
return true;
}
static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr) {
// query according to the binary expression
STSchema* pSchema = pSTable->tagSchema;
......@@ -1422,12 +1423,22 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr)
tExprTreeDestroy(&pExpr, destroyHelper);
convertQueryResult(pRes, pTableList);
taosArrayDestroy(pTableList);
return TSDB_CODE_SUCCESS;
}
int32_t tsdbQueryByTagsCond(TsdbRepoT* tsdb, int64_t uid, const char* pTagCond, size_t len, STableGroupInfo* pGroupInfo,
SColIndex* pColIndex, int32_t numOfCols) {
int32_t tsdbQueryByTagsCond(
TsdbRepoT *tsdb,
int64_t uid,
const char *pTagCond,
size_t len,
int16_t tagNameRelType,
const char* tbnameCond,
STableGroupInfo *pGroupList,
SColIndex *pColIndex,
int32_t numOfCols
) {
STable* pSTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid);
if (pSTable == NULL) {
uError("failed to get stable, uid:%" PRIu64, uid);
......@@ -1437,11 +1448,12 @@ int32_t tsdbQueryByTagsCond(TsdbRepoT* tsdb, int64_t uid, const char* pTagCond,
SArray* res = taosArrayInit(8, POINTER_BYTES);
STSchema* pTagSchema = tsdbGetTableTagSchema(tsdbGetMeta(tsdb), pSTable);
if (pTagCond == NULL || len == 0) { // no tags condition, all tables created according to this stable are involved
// no tags and tbname condition, all child tables of this stable are involved
if (tbnameCond == NULL && (pTagCond == NULL || len == 0)) {
int32_t ret = getAllTableIdList(tsdb, uid, res);
if (ret != TSDB_CODE_SUCCESS) {
taosArrayDestroy(res);
return ret;
if (ret == TSDB_CODE_SUCCESS) {
pGroupList->numOfTables = taosArrayGetSize(res);
pGroupList->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols);
}
pGroupInfo->numOfTables = taosArrayGetSize(res);
......@@ -1450,20 +1462,24 @@ int32_t tsdbQueryByTagsCond(TsdbRepoT* tsdb, int64_t uid, const char* pTagCond,
return ret;
}
tExprNode* pExprNode = NULL;
int32_t ret = TSDB_CODE_SUCCESS;
// failed to build expression, no result, return immediately
if ((ret = exprTreeFromBinary(pTagCond, len, &pExprNode) != TSDB_CODE_SUCCESS) || (pExprNode == NULL)) {
uError("stable:%" PRIu64 ", failed to deserialize expression tree, error exists", uid);
taosArrayDestroy(res);
return ret;
tExprNode* expr = exprTreeFromTableName(tbnameCond);
tExprNode* tagExpr = exprTreeFromBinary(pTagCond, len);
if (tagExpr != NULL) {
if (expr == NULL) {
expr = tagExpr;
} else {
tExprNode* tbnameExpr = expr;
expr = calloc(1, sizeof(tExprNode));
expr->nodeType = TSQL_NODE_EXPR;
expr->_node.optr = tagNameRelType;
expr->_node.pLeft = tbnameExpr;
expr->_node.pRight = tagExpr;
}
}
doQueryTableList(pSTable, res, pExprNode);
pGroupInfo->numOfTables = taosArrayGetSize(res);
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols);
doQueryTableList(pSTable, res, expr);
pGroupList->numOfTables = taosArrayGetSize(res);
pGroupList->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols);
taosArrayDestroy(res);
return ret;
......
......@@ -53,7 +53,7 @@ void* taosArrayPush(SArray* pArray, void* pData);
*
* @param pArray
*/
void taosArrayPop(SArray* pArray);
void* taosArrayPop(SArray* pArray);
/**
* get the data from array
......@@ -112,6 +112,21 @@ SArray* taosArrayClone(SArray* pSrc);
*/
void taosArrayDestroy(SArray* pArray);
/**
* sort the array
* @param pArray
* @param compar
*/
void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*));
/**
* search the array
* @param pArray
* @param compar
* @param key
*/
void* taosArraySearch(SArray* pArray, int (*compar)(const void*, const void*), const void* key);
#ifdef __cplusplus
}
#endif
......
......@@ -120,7 +120,7 @@ void tbufWriteString(SBuffer* buf, const char* str);
TBUFFER_DEFINE_FUNCTION(bool, Bool)
TBUFFER_DEFINE_FUNCTION(char, Char)
TBUFFER_DEFINE_FUNCTION(int8_t, Int8)
TBUFFER_DEFINE_FUNCTION(uint8_t, Unt8)
TBUFFER_DEFINE_FUNCTION(uint8_t, Uint8)
TBUFFER_DEFINE_FUNCTION(int16_t, Int16)
TBUFFER_DEFINE_FUNCTION(uint16_t, Uint16)
TBUFFER_DEFINE_FUNCTION(int32_t, Int32)
......
......@@ -76,12 +76,13 @@ void* taosArrayPush(SArray* pArray, void* pData) {
return dst;
}
void taosArrayPop(SArray* pArray) {
void* taosArrayPop(SArray* pArray) {
if (pArray == NULL || pArray->size == 0) {
return;
return NULL;
}
pArray->size -= 1;
return TARRAY_GET_ELEM(pArray, pArray->size);
}
void* taosArrayGet(const SArray* pArray, size_t index) {
......@@ -183,3 +184,18 @@ void taosArrayDestroy(SArray* pArray) {
free(pArray->pData);
free(pArray);
}
void taosArraySort(SArray* pArray, int (*compar)(const void*, const void*)) {
assert(pArray != NULL);
assert(compar != NULL);
qsort(pArray->pData, pArray->size, pArray->elemSize, compar);
}
void* taosArraySearch(SArray* pArray, int (*compar)(const void*, const void*), const void* key) {
assert(pArray != NULL);
assert(compar != NULL);
assert(key != NULL);
return bsearch(key, pArray->pData, pArray->size, pArray->elemSize, compar);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册