[TD-1978]
This commit is contained in:
parent
276b7a6dbb
commit
2b9a3b1e1b
|
@ -69,7 +69,10 @@ static void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t na
|
|||
static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult);
|
||||
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
|
||||
int8_t type, char* fieldName, SSqlExpr* pSqlExpr);
|
||||
static int32_t changeFunctionID(int32_t optr, int16_t* functionId);
|
||||
|
||||
static int32_t convertFunctionId(int32_t optr, int16_t* functionId);
|
||||
static uint8_t convertOptr(SStrToken *pToken);
|
||||
|
||||
static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable, bool joinQuery);
|
||||
|
||||
static bool validateIpAddress(const char* ip, size_t size);
|
||||
|
@ -123,6 +126,45 @@ static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo);
|
|||
static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index);
|
||||
static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid);
|
||||
|
||||
static uint8_t convertOptr(SStrToken *pToken) {
|
||||
switch (pToken->type) {
|
||||
case TK_LT:
|
||||
return TSDB_RELATION_LESS;
|
||||
case TK_LE:
|
||||
return TSDB_RELATION_LESS_EQUAL;
|
||||
case TK_GT:
|
||||
return TSDB_RELATION_GREATER;
|
||||
case TK_GE:
|
||||
return TSDB_RELATION_GREATER_EQUAL;
|
||||
case TK_NE:
|
||||
return TSDB_RELATION_NOT_EQUAL;
|
||||
case TK_AND:
|
||||
return TSDB_RELATION_AND;
|
||||
case TK_OR:
|
||||
return TSDB_RELATION_OR;
|
||||
case TK_EQ:
|
||||
return TSDB_RELATION_EQUAL;
|
||||
case TK_PLUS:
|
||||
return TSDB_BINARY_OP_ADD;
|
||||
case TK_MINUS:
|
||||
return TSDB_BINARY_OP_SUBTRACT;
|
||||
case TK_STAR:
|
||||
return TSDB_BINARY_OP_MULTIPLY;
|
||||
case TK_SLASH:
|
||||
case TK_DIVIDE:
|
||||
return TSDB_BINARY_OP_DIVIDE;
|
||||
case TK_REM:
|
||||
return TSDB_BINARY_OP_REMAINDER;
|
||||
case TK_LIKE:
|
||||
return TSDB_RELATION_LIKE;
|
||||
case TK_ISNULL:
|
||||
return TSDB_RELATION_ISNULL;
|
||||
case TK_NOTNULL:
|
||||
return TSDB_RELATION_NOTNULL;
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used during parsing query sql. Since the query sql usually small in length, error position
|
||||
* is not needed in the final error message.
|
||||
|
@ -1725,7 +1767,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
}
|
||||
|
||||
int16_t functionID = 0;
|
||||
if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
|
||||
if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
|
@ -1861,7 +1903,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
int32_t intermediateResSize = 0;
|
||||
|
||||
int16_t functionID = 0;
|
||||
if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
|
||||
if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
|
@ -1932,7 +1974,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
bool requireAllFields = (pItem->pNode->pParam == NULL);
|
||||
|
||||
int16_t functionID = 0;
|
||||
if (changeFunctionID(optr, &functionID) != TSDB_CODE_SUCCESS) {
|
||||
if (convertFunctionId(optr, &functionID) != TSDB_CODE_SUCCESS) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9);
|
||||
}
|
||||
|
||||
|
@ -2121,7 +2163,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
* for dp = 100, it is max,
|
||||
*/
|
||||
int16_t functionId = 0;
|
||||
if (changeFunctionID(optr, &functionId) != TSDB_CODE_SUCCESS) {
|
||||
if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
|
||||
|
@ -2138,7 +2180,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
}
|
||||
|
||||
int16_t functionId = 0;
|
||||
if (changeFunctionID(optr, &functionId) != TSDB_CODE_SUCCESS) {
|
||||
if (convertFunctionId(optr, &functionId) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
|
||||
|
@ -2397,7 +2439,7 @@ int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo*
|
|||
return doGetColumnIndexByName(pCmd, &tmpToken, pQueryInfo, pIndex);
|
||||
}
|
||||
|
||||
int32_t changeFunctionID(int32_t optr, int16_t* functionId) {
|
||||
int32_t convertFunctionId(int32_t optr, int16_t* functionId) {
|
||||
switch (optr) {
|
||||
case TK_COUNT:
|
||||
*functionId = TSDB_FUNC_COUNT;
|
||||
|
@ -6535,7 +6577,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
|
|||
(*pExpr)->_node.pRight = pRight;
|
||||
|
||||
SStrToken t = {.type = pSqlExpr->nSQLOptr};
|
||||
(*pExpr)->_node.optr = getBinaryExprOptr(&t);
|
||||
(*pExpr)->_node.optr = convertOptr(&t);
|
||||
|
||||
assert((*pExpr)->_node.optr != 0);
|
||||
|
||||
|
|
|
@ -130,16 +130,6 @@ SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct SSchema tscGetTbnameColumnSchema() {
|
||||
struct SSchema s = {
|
||||
.colId = TSDB_TBNAME_COLUMN_INDEX,
|
||||
.type = TSDB_DATA_TYPE_BINARY,
|
||||
.bytes = TSDB_TABLE_NAME_LEN
|
||||
};
|
||||
|
||||
strcpy(s.name, TSQL_TBNAME_L);
|
||||
return s;
|
||||
}
|
||||
static void tscInitCorVgroupInfo(SCorVgroupInfo *corVgroupInfo, SVgroupInfo *vgroupInfo) {
|
||||
corVgroupInfo->version = 0;
|
||||
corVgroupInfo->inUse = 0;
|
||||
|
|
|
@ -35,6 +35,10 @@ bool tscValidateTableNameLength(size_t len);
|
|||
|
||||
SColumnFilterInfo* tscFilterInfoClone(const SColumnFilterInfo* src, int32_t numOfFilters);
|
||||
|
||||
// int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t slidingTime, int64_t intervalTime, char timeUnit, int16_t precision);
|
||||
/**
|
||||
* get the schema for the "tbname" column. it is a built column
|
||||
* @return
|
||||
*/
|
||||
SSchema tscGetTbnameColumnSchema();
|
||||
|
||||
#endif // TDENGINE_NAME_H
|
||||
|
|
|
@ -188,3 +188,14 @@ void extractTableNameFromToken(SStrToken* pToken, SStrToken* pTable) {
|
|||
pToken->z = r;
|
||||
}
|
||||
}
|
||||
|
||||
SSchema tscGetTbnameColumnSchema() {
|
||||
struct SSchema s = {
|
||||
.colId = TSDB_TBNAME_COLUMN_INDEX,
|
||||
.type = TSDB_DATA_TYPE_BINARY,
|
||||
.bytes = TSDB_TABLE_NAME_LEN
|
||||
};
|
||||
|
||||
strcpy(s.name, TSQL_TBNAME_L);
|
||||
return s;
|
||||
}
|
|
@ -81,14 +81,13 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
|
|||
void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||
char *(*cb)(void *, const char*, int32_t));
|
||||
|
||||
uint8_t getBinaryExprOptr(SStrToken *pToken);
|
||||
|
||||
void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *));
|
||||
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
|
||||
|
||||
tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
||||
tExprNode* exprTreeFromTableName(const char* tbnameCond);
|
||||
|
||||
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
|
||||
|
||||
void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -309,9 +309,6 @@ void tSQLSetColumnType(TAOS_FIELD *pField, SStrToken *pToken);
|
|||
|
||||
void *ParseAlloc(void *(*mallocProc)(size_t));
|
||||
|
||||
// convert the sql filter expression into binary data
|
||||
int32_t tSQLExprToBinary(tSQLExpr* pExpr, SStringBuilder* sb);
|
||||
|
||||
enum {
|
||||
TSQL_NODE_TYPE_EXPR = 0x1,
|
||||
TSQL_NODE_TYPE_ID = 0x2,
|
||||
|
|
|
@ -13,12 +13,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "exception.h"
|
||||
#include "qAst.h"
|
||||
#include "qSqlparser.h"
|
||||
#include "qSyntaxtreefunction.h"
|
||||
#include "taosdef.h"
|
||||
#include "taosmsg.h"
|
||||
|
@ -30,200 +28,19 @@
|
|||
#include "tskiplist.h"
|
||||
#include "tsqlfunction.h"
|
||||
#include "tstoken.h"
|
||||
#include "ttokendef.h"
|
||||
#include "tulog.h"
|
||||
#include "tschemautil.h"
|
||||
|
||||
/*
|
||||
*
|
||||
* @date 2018-2-15
|
||||
* @version 0.2 operation for column filter
|
||||
*
|
||||
* @Description parse tag query expression to build ast
|
||||
* ver 0.2, filter the result on first column with high priority to limit the candidate set
|
||||
* ver 0.3, pipeline filter in the form of: (a+2)/9 > 14
|
||||
*
|
||||
*/
|
||||
static tExprNode *tExprNodeCreate(SSchema *pSchema, int32_t numOfCols, SStrToken *pToken);
|
||||
typedef struct {
|
||||
char* v;
|
||||
int32_t optr;
|
||||
} SEndPoint;
|
||||
|
||||
static tExprNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, char *str, int32_t *i);
|
||||
static void destroySyntaxTree(tExprNode *);
|
||||
typedef struct {
|
||||
SEndPoint* start;
|
||||
SEndPoint* end;
|
||||
} SQueryCond;
|
||||
|
||||
static uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight);
|
||||
|
||||
/*
|
||||
* Check the filter value type on the right hand side based on the column id on the left hand side,
|
||||
* the filter value type must be identical to field type for relational operation
|
||||
* As for binary arithmetic operation, it is not necessary to do so.
|
||||
*/
|
||||
static void reviseBinaryExprIfNecessary(tExprNode **pLeft, tExprNode **pRight, uint8_t *optr) {
|
||||
if (*optr >= TSDB_RELATION_LESS && *optr <= TSDB_RELATION_LIKE) {
|
||||
// make sure that the type of data on both sides of relational comparision are identical
|
||||
if ((*pLeft)->nodeType == TSQL_NODE_VALUE) {
|
||||
tVariantTypeSetType((*pLeft)->pVal, (*pRight)->pSchema->type);
|
||||
} else if ((*pRight)->nodeType == TSQL_NODE_VALUE) {
|
||||
tVariantTypeSetType((*pRight)->pVal, (*pLeft)->pSchema->type);
|
||||
}
|
||||
|
||||
} else if (*optr >= TSDB_BINARY_OP_ADD && *optr <= TSDB_BINARY_OP_REMAINDER) {
|
||||
if ((*pLeft)->nodeType == TSQL_NODE_VALUE) {
|
||||
/* convert to int/bigint may cause the precision loss */
|
||||
tVariantTypeSetType((*pLeft)->pVal, TSDB_DATA_TYPE_DOUBLE);
|
||||
} else if ((*pRight)->nodeType == TSQL_NODE_VALUE) {
|
||||
/* convert to int/bigint may cause the precision loss */
|
||||
tVariantTypeSetType((*pRight)->pVal, TSDB_DATA_TYPE_DOUBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* for expressions that are suitable for switch principle,
|
||||
* switch left and left and right hand side in expr if possible
|
||||
*/
|
||||
if ((*pLeft)->nodeType == TSQL_NODE_VALUE && (*pRight)->nodeType == TSQL_NODE_COL) {
|
||||
if (*optr >= TSDB_RELATION_GREATER && *optr <= TSDB_RELATION_GREATER_EQUAL && *optr != TSDB_RELATION_EQUAL) {
|
||||
SWAP(*pLeft, *pRight, tExprNode *);
|
||||
}
|
||||
|
||||
switch (*optr) {
|
||||
case TSDB_RELATION_GREATER:
|
||||
(*optr) = TSDB_RELATION_LESS;
|
||||
break;
|
||||
case TSDB_RELATION_LESS:
|
||||
(*optr) = TSDB_RELATION_GREATER;
|
||||
break;
|
||||
case TSDB_RELATION_GREATER_EQUAL:
|
||||
(*optr) = TSDB_RELATION_LESS_EQUAL;
|
||||
break;
|
||||
case TSDB_RELATION_LESS_EQUAL:
|
||||
(*optr) = TSDB_RELATION_GREATER_EQUAL;
|
||||
break;
|
||||
default:;
|
||||
// for other type of operations, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static tExprNode *tExprNodeCreate(SSchema *pSchema, int32_t numOfCols, SStrToken *pToken) {
|
||||
/* if the token is not a value, return false */
|
||||
if (pToken->type == TK_RP || (pToken->type != TK_INTEGER && pToken->type != TK_FLOAT && pToken->type != TK_ID &&
|
||||
pToken->type != TK_TBNAME && pToken->type != TK_STRING && pToken->type != TK_BOOL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t nodeSize = sizeof(tExprNode);
|
||||
tExprNode *pNode = NULL;
|
||||
|
||||
if (pToken->type == TK_ID || pToken->type == TK_TBNAME) {
|
||||
int32_t i = 0;
|
||||
if (pToken->type == TK_ID) {
|
||||
do {
|
||||
SStrToken tableToken = {0};
|
||||
extractTableNameFromToken(pToken, &tableToken);
|
||||
|
||||
size_t len = strlen(pSchema[i].name);
|
||||
if (strncmp(pToken->z, pSchema[i].name, pToken->n) == 0 && pToken->n == len) break;
|
||||
} while (++i < numOfCols);
|
||||
|
||||
if (i == numOfCols) { // column name is not valid, parse the expression failed
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nodeSize += sizeof(SSchema);
|
||||
|
||||
pNode = calloc(1, nodeSize);
|
||||
pNode->pSchema = (struct SSchema *)((char *)pNode + sizeof(tExprNode));
|
||||
pNode->nodeType = TSQL_NODE_COL;
|
||||
|
||||
if (pToken->type == TK_ID) {
|
||||
memcpy(pNode->pSchema, &pSchema[i], sizeof(SSchema));
|
||||
} else {
|
||||
pNode->pSchema->type = TSDB_DATA_TYPE_BINARY;
|
||||
pNode->pSchema->bytes = TSDB_TABLE_NAME_LEN - 1;
|
||||
strcpy(pNode->pSchema->name, TSQL_TBNAME_L);
|
||||
pNode->pSchema->colId = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
nodeSize += sizeof(tVariant);
|
||||
pNode = calloc(1, nodeSize);
|
||||
pNode->pVal = (tVariant *)((char *)pNode + sizeof(tExprNode));
|
||||
|
||||
toTSDBType(pToken->type);
|
||||
tVariantCreate(pNode->pVal, pToken);
|
||||
pNode->nodeType = TSQL_NODE_VALUE;
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
uint8_t getBinaryExprOptr(SStrToken *pToken) {
|
||||
switch (pToken->type) {
|
||||
case TK_LT:
|
||||
return TSDB_RELATION_LESS;
|
||||
case TK_LE:
|
||||
return TSDB_RELATION_LESS_EQUAL;
|
||||
case TK_GT:
|
||||
return TSDB_RELATION_GREATER;
|
||||
case TK_GE:
|
||||
return TSDB_RELATION_GREATER_EQUAL;
|
||||
case TK_NE:
|
||||
return TSDB_RELATION_NOT_EQUAL;
|
||||
case TK_AND:
|
||||
return TSDB_RELATION_AND;
|
||||
case TK_OR:
|
||||
return TSDB_RELATION_OR;
|
||||
case TK_EQ:
|
||||
return TSDB_RELATION_EQUAL;
|
||||
case TK_PLUS:
|
||||
return TSDB_BINARY_OP_ADD;
|
||||
case TK_MINUS:
|
||||
return TSDB_BINARY_OP_SUBTRACT;
|
||||
case TK_STAR:
|
||||
return TSDB_BINARY_OP_MULTIPLY;
|
||||
case TK_SLASH:
|
||||
case TK_DIVIDE:
|
||||
return TSDB_BINARY_OP_DIVIDE;
|
||||
case TK_REM:
|
||||
return TSDB_BINARY_OP_REMAINDER;
|
||||
case TK_LIKE:
|
||||
return TSDB_RELATION_LIKE;
|
||||
case TK_ISNULL:
|
||||
return TSDB_RELATION_ISNULL;
|
||||
case TK_NOTNULL:
|
||||
return TSDB_RELATION_NOTNULL;
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
|
||||
// previous generated expr is reduced as the left child
|
||||
static tExprNode *parseRemainStr(char *pstr, tExprNode *pExpr, SSchema *pSchema, int32_t optr,
|
||||
int32_t numOfCols, int32_t *i) {
|
||||
// set the previous generated node as the left child of new root
|
||||
pExpr->nodeType = TSQL_NODE_EXPR;
|
||||
|
||||
// remain is the right child
|
||||
tExprNode *pRight = createSyntaxTree(pSchema, numOfCols, pstr, i);
|
||||
if (pRight == NULL || (pRight->nodeType == TSQL_NODE_COL && pExpr->nodeType != TSQL_NODE_VALUE) ||
|
||||
(pExpr->nodeType == TSQL_NODE_VALUE && pRight->nodeType != TSQL_NODE_COL)) {
|
||||
tExprNodeDestroy(pExpr, NULL);
|
||||
tExprNodeDestroy(pRight, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tExprNode *pNewExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
|
||||
uint8_t k = optr;
|
||||
reviseBinaryExprIfNecessary(&pExpr, &pRight, &k);
|
||||
pNewExpr->_node.pLeft = pExpr;
|
||||
pNewExpr->_node.pRight = pRight;
|
||||
pNewExpr->_node.optr = k;
|
||||
|
||||
pNewExpr->_node.hasPK = isQueryOnPrimaryKey(pSchema[0].name, pExpr, pRight);
|
||||
pNewExpr->nodeType = TSQL_NODE_EXPR;
|
||||
|
||||
return pNewExpr;
|
||||
}
|
||||
|
||||
uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
||||
static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
||||
if (pLeft->nodeType == TSQL_NODE_COL) {
|
||||
// if left node is the primary column,return true
|
||||
return (strcmp(primaryColumnName, pLeft->pSchema->name) == 0) ? 1 : 0;
|
||||
|
@ -236,103 +53,6 @@ uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLef
|
|||
}
|
||||
}
|
||||
|
||||
static tExprNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, char *str, int32_t *i) {
|
||||
SStrToken t0 = tStrGetToken(str, i, false, 0, NULL);
|
||||
if (t0.n == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tExprNode *pLeft = NULL;
|
||||
if (t0.type == TK_LP) { // start new left child branch
|
||||
pLeft = createSyntaxTree(pSchema, numOfCols, str, i);
|
||||
} else {
|
||||
if (t0.type == TK_RP) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pLeft = tExprNodeCreate(pSchema, numOfCols, &t0);
|
||||
}
|
||||
|
||||
if (pLeft == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t0 = tStrGetToken(str, i, false, 0, NULL);
|
||||
if (t0.n == 0 || t0.type == TK_RP) {
|
||||
if (pLeft->nodeType != TSQL_NODE_EXPR) { // if left is not the expr, it is not a legal expr
|
||||
tExprNodeDestroy(pLeft, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pLeft;
|
||||
}
|
||||
|
||||
// get the operator of expr
|
||||
uint8_t optr = getBinaryExprOptr(&t0);
|
||||
if (optr == 0) {
|
||||
uError("not support binary operator:%d", t0.type);
|
||||
tExprNodeDestroy(pLeft, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(pLeft != NULL);
|
||||
tExprNode *pRight = NULL;
|
||||
|
||||
if (t0.type == TK_AND || t0.type == TK_OR || t0.type == TK_LP) {
|
||||
pRight = createSyntaxTree(pSchema, numOfCols, str, i);
|
||||
} else {
|
||||
/*
|
||||
* In case that pLeft is a field identification,
|
||||
* we parse the value in expression according to queried field type,
|
||||
* if we do not get the information, in case of value of field presented first,
|
||||
* we revised the value after the binary expression is completed.
|
||||
*/
|
||||
t0 = tStrGetToken(str, i, true, 0, NULL);
|
||||
if (t0.n == 0) {
|
||||
tExprNodeDestroy(pLeft, NULL); // illegal expression
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (t0.type == TK_LP) {
|
||||
pRight = createSyntaxTree(pSchema, numOfCols, str, i);
|
||||
} else {
|
||||
pRight = tExprNodeCreate(pSchema, numOfCols, &t0);
|
||||
}
|
||||
}
|
||||
|
||||
if (pRight == NULL) {
|
||||
tExprNodeDestroy(pLeft, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create binary expr as the child of new parent node */
|
||||
tExprNode *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
|
||||
reviseBinaryExprIfNecessary(&pLeft, &pRight, &optr);
|
||||
|
||||
pExpr->_node.hasPK = isQueryOnPrimaryKey(pSchema[0].name, pLeft, pRight);
|
||||
pExpr->_node.pLeft = pLeft;
|
||||
pExpr->_node.pRight = pRight;
|
||||
pExpr->_node.optr = optr;
|
||||
|
||||
t0 = tStrGetToken(str, i, true, 0, NULL);
|
||||
|
||||
if (t0.n == 0 || t0.type == TK_RP) {
|
||||
pExpr->nodeType = TSQL_NODE_EXPR;
|
||||
return pExpr;
|
||||
} else {
|
||||
uint8_t localOptr = getBinaryExprOptr(&t0);
|
||||
if (localOptr == 0) {
|
||||
uError("not support binary operator:%d", t0.type);
|
||||
free(pExpr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return parseRemainStr(str, pExpr, pSchema, localOptr, numOfCols, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void UNUSED_FUNC destroySyntaxTree(tExprNode *pNode) { tExprNodeDestroy(pNode, NULL); }
|
||||
|
||||
void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *)) {
|
||||
if (pNode == NULL) {
|
||||
return;
|
||||
|
@ -372,16 +92,6 @@ void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
|
|||
*pExpr = NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char* v;
|
||||
int32_t optr;
|
||||
} SEndPoint;
|
||||
|
||||
typedef struct {
|
||||
SEndPoint* start;
|
||||
SEndPoint* end;
|
||||
} SQueryCond;
|
||||
|
||||
// todo check for malloc failure
|
||||
static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
|
||||
int32_t optr = queryColInfo->optr;
|
||||
|
@ -395,13 +105,10 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
|
|||
pCond->end = calloc(1, sizeof(SEndPoint));
|
||||
pCond->end->optr = queryColInfo->optr;
|
||||
pCond->end->v = queryColInfo->q;
|
||||
} else if (optr == TSDB_RELATION_IN) {
|
||||
printf("relation is in\n");
|
||||
assert(0);
|
||||
} else if (optr == TSDB_RELATION_LIKE) {
|
||||
printf("relation is like\n");
|
||||
} else if (optr == TSDB_RELATION_IN || optr == TSDB_RELATION_LIKE) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -529,99 +236,6 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
|
|||
tSkipListDestroyIter(iter);
|
||||
}
|
||||
|
||||
int32_t merge(SArray *pLeft, SArray *pRight, SArray *pFinalRes) {
|
||||
// assert(pFinalRes->pRes == 0);
|
||||
//
|
||||
// pFinalRes->pRes = calloc((size_t)(pLeft->num + pRight->num), POINTER_BYTES);
|
||||
// pFinalRes->num = 0;
|
||||
//
|
||||
// // sort according to address
|
||||
// tSkipListNode **pLeftNodes = (tSkipListNode **)pLeft->pRes;
|
||||
// qsort(pLeftNodes, pLeft->num, sizeof(pLeft->pRes[0]), compareByAddr);
|
||||
//
|
||||
// tSkipListNode **pRightNodes = (tSkipListNode **)pRight->pRes;
|
||||
// qsort(pRightNodes, pRight->num, sizeof(pRight->pRes[0]), compareByAddr);
|
||||
//
|
||||
// int32_t i = 0, j = 0;
|
||||
//
|
||||
// // merge two sorted arrays in O(n) time
|
||||
// while (i < pLeft->num && j < pRight->num) {
|
||||
// int64_t ret = (int64_t)pLeftNodes[i] - (int64_t)pRightNodes[j];
|
||||
//
|
||||
// if (ret < 0) {
|
||||
// pFinalRes->pRes[pFinalRes->num++] = pLeftNodes[i++];
|
||||
// } else if (ret > 0) {
|
||||
// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++];
|
||||
// } else { // pNode->key > pkey[i]
|
||||
// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++];
|
||||
// i++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// while (i < pLeft->num) {
|
||||
// pFinalRes->pRes[pFinalRes->num++] = pLeftNodes[i++];
|
||||
// }
|
||||
//
|
||||
// while (j < pRight->num) {
|
||||
// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++];
|
||||
// }
|
||||
//
|
||||
// return pFinalRes->num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t intersect(SArray *pLeft, SArray *pRight, SArray *pFinalRes) {
|
||||
// int64_t num = MIN(pLeft->num, pRight->num);
|
||||
//
|
||||
// assert(pFinalRes->pRes == 0);
|
||||
//
|
||||
// pFinalRes->pRes = calloc(num, POINTER_BYTES);
|
||||
// pFinalRes->num = 0;
|
||||
//
|
||||
// // sort according to address
|
||||
// tSkipListNode **pLeftNodes = (tSkipListNode **)pLeft->pRes;
|
||||
// qsort(pLeftNodes, pLeft->num, sizeof(pLeft->pRes[0]), compareByAddr);
|
||||
//
|
||||
// tSkipListNode **pRightNodes = (tSkipListNode **)pRight->pRes;
|
||||
// qsort(pRightNodes, pRight->num, sizeof(pRight->pRes[0]), compareByAddr);
|
||||
//
|
||||
// int32_t i = 0, j = 0;
|
||||
// // merge two sorted arrays in O(n) time
|
||||
// while (i < pLeft->num && j < pRight->num) {
|
||||
// int64_t ret = (int64_t)pLeftNodes[i] - (int64_t)pRightNodes[j];
|
||||
//
|
||||
// if (ret < 0) {
|
||||
// i++;
|
||||
// } else if (ret > 0) {
|
||||
// j++;
|
||||
// } else { // pNode->key > pkey[i]
|
||||
// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j];
|
||||
// i++;
|
||||
// j++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return pFinalRes->num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* traverse the result and apply the function to each item to check if the item is qualified or not
|
||||
*/
|
||||
static UNUSED_FUNC void tArrayTraverse(tExprNode *pExpr, __result_filter_fn_t fp, SArray *pResult) {
|
||||
assert(pExpr->_node.pLeft->nodeType == TSQL_NODE_COL && pExpr->_node.pRight->nodeType == TSQL_NODE_VALUE && fp != NULL);
|
||||
|
||||
// scan the result array list and check for each item in the list
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pResult); ++i) {
|
||||
void* item = taosArrayGet(pResult, i);
|
||||
if (fp(item, pExpr->_node.info)) {
|
||||
i++;
|
||||
} else {
|
||||
taosArrayRemove(pResult, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool filterItem(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) {
|
||||
tExprNode *pLeft = pExpr->_node.pLeft;
|
||||
tExprNode *pRight = pExpr->_node.pRight;
|
||||
|
@ -649,32 +263,6 @@ static bool filterItem(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *p
|
|||
return param->nodeFilterFn(pItem, pExpr->_node.info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the filter expression on non-indexed tag columns to each element in the result list, which is generated
|
||||
* by filtering on indexed tag column. So the whole result set only needs to be iterated once to generate
|
||||
* result that is satisfied to the filter expression, no matter how the filter expression consisting of.
|
||||
*
|
||||
* @param pExpr filter expression on non-indexed tag columns.
|
||||
* @param pResult results from filter on the indexed tag column, which is usually the first tag column
|
||||
* @param pSchema tag schemas
|
||||
* @param fp filter callback function
|
||||
*/
|
||||
static UNUSED_FUNC void exprTreeTraverseImpl(tExprNode *pExpr, SArray *pResult, SExprTraverseSupp *param) {
|
||||
size_t size = taosArrayGetSize(pResult);
|
||||
|
||||
SArray* array = taosArrayInit(size, POINTER_BYTES);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
void *pItem = taosArrayGetP(pResult, i);
|
||||
|
||||
if (filterItem(pExpr, pItem, param)) {
|
||||
taosArrayPush(array, &pItem);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayCopy(pResult, array);
|
||||
taosArrayDestroy(array);
|
||||
}
|
||||
|
||||
static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSkipList *pSkipList, SExprTraverseSupp *param ) {
|
||||
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
|
||||
|
||||
|
@ -750,7 +338,7 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
|
|||
//apply the hierarchical expression to every node in skiplist for find the qualified nodes
|
||||
tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param);
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
/*
|
||||
* (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here
|
||||
*
|
||||
|
@ -972,6 +560,7 @@ tExprNode* exprTreeFromBinary(const void* data, size_t size) {
|
|||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SBufferReader br = tbufInitReader(data, size, false);
|
||||
return exprTreeFromBinaryImpl(&br);
|
||||
}
|
||||
|
@ -995,10 +584,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
SSchema* pSchema = exception_calloc(1, sizeof(SSchema));
|
||||
left->pSchema = pSchema;
|
||||
|
||||
pSchema->type = TSDB_DATA_TYPE_BINARY;
|
||||
pSchema->bytes = TSDB_TABLE_NAME_LEN - 1;
|
||||
strcpy(pSchema->name, TSQL_TBNAME_L);
|
||||
pSchema->colId = -1;
|
||||
*pSchema = tscGetTbnameColumnSchema();
|
||||
|
||||
tExprNode* right = exception_calloc(1, sizeof(tExprNode));
|
||||
expr->_node.pRight = right;
|
||||
|
|
Loading…
Reference in New Issue