提交 c336f2db 编写于 作者: 5 54liuyao

feat(query):added where expression

[TS-1210]
上级 9ff4b302
......@@ -145,6 +145,8 @@ static int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo);
static tSqlExpr* extractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo* pQueryInfo, int32_t tableIndex);
static void convertWhereStringCharset(tSqlExpr* pRight);
static bool isLogicalOperator(tSqlExpr* pExpr);
static bool isComparisonOperator(tSqlExpr* pExpr);
int validateTableName(char *tblName, int len, SStrToken* psTblToken, bool *dbIncluded);
static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) {
......@@ -4274,15 +4276,10 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
int32_t ret = 0;
int32_t ret = TSDB_CODE_SUCCESS;
const char* msg1 = "non binary column not support like/match operator";
const char* msg3 = "bool column not support this operator";
const char* msg4 = "primary key not support this operator";
SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex->columnIndex, pTableMeta->id.uid, pSchema);
pColumn->info.flist.numOfFilters++;
/*
* in case of TK_AND filter condition, we first find the corresponding column and build the query condition together
* the already existed condition.
......@@ -4296,8 +4293,8 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol
pColFilter->filterstr =
((pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0);
if (!pColFilter->filterstr) {
if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH) {
if (!pColFilter->filterstr && tSqlExprIsParentOfLeaf(pExpr)) {
if (pExpr->tokenId == TK_LIKE || pExpr->tokenId == TK_MATCH || pExpr->tokenId == TK_NMATCH) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
goto _err_ret;
}
......@@ -4310,11 +4307,10 @@ static int32_t checkColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCol
}
}
}
pColumn->columnIndex = pIndex->columnIndex;
pColumn->tableUid = pTableMeta->id.uid;
if (pColumn->columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX && pExpr->tokenId == TK_IN) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
if (pIndex->columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX && pTableMeta->id.uid == TK_IN
&& tSqlExprIsParentOfLeaf(pExpr)) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
goto _err_ret;
}
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
......@@ -4326,8 +4322,32 @@ _err_ret:
return ret;
}
static int32_t addAllColumn(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, uint32_t conTokenId,
SColumnIndex* pIndex) {
int32_t ret = TSDB_CODE_SUCCESS;
if(!tSqlExprIsLeaf(pExpr) || pExpr->tokenId == TK_ARROW) {
ret = addAllColumn(pCmd, pQueryInfo, pExpr->pLeft, conTokenId, pIndex);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
return addAllColumn(pCmd, pQueryInfo, pExpr->pRight, conTokenId, pIndex);
} else if (pExpr->tokenId == TK_ID) {
if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, pIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex);
SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex->columnIndex, pTableMeta->id.uid, pSchema);
pColumn->info.flist.numOfFilters++;
}
return ret;
}
static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr) {
int32_t ret = TSDB_CODE_SUCCESS;
const char* msg6 = "illegal condition expression";
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
tSqlExpr* p1 = extractExprForSTable(pCmd, pExpr, pQueryInfo, i);
......@@ -4339,7 +4359,18 @@ static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlEx
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL);
size_t colNum = taosArrayGetSize(colList);
for (int32_t k = 0; k < colNum; k++) {
SColIndex* pColIndex = taosArrayGet(colList, k);
if (TSDB_COL_IS_TAG(pColIndex->flag)) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
break;
}
}
taosArrayDestroy(&colList);
if (ret == TSDB_CODE_SUCCESS) {
ret = exprTreeValidateTree(tscGetErrorMsgPayload(pCmd), p);
}
SBufferWriter bw = tbufInitWriter(NULL, false);
......@@ -4387,7 +4418,7 @@ static int32_t checkColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
}
pQueryInfo->onlyHasTagCond &= false;
if (!tSqlExprIsParentOfLeaf(pExpr)) { // internal node
if (isLogicalOperator(pExpr)) { // internal node
int32_t ret = checkColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->tokenId);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
......@@ -4396,12 +4427,10 @@ static int32_t checkColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
return checkColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pRight, pExpr->tokenId);
} else { // handle leaf node
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&pExpr->pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
addAllColumn(pCmd, pQueryInfo, pExpr, pExpr->tokenId, &index);
return checkColumnFilterInfo(pCmd, pQueryInfo, &index, pExpr, relOptr);
}
return TSDB_CODE_SUCCESS;
}
static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
......@@ -5137,6 +5166,38 @@ void convertWhereStringCharset(tSqlExpr* pRight){
free(newData);
}
static int32_t handleColumnInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SColumnIndex* index) {
const char* msg2 = "illegal column name";
int32_t ret = TSDB_CODE_SUCCESS;
if (pExpr == NULL) {
return ret;
} else if (!tSqlExprIsLeaf(pExpr)) {
if (isComparisonOperator(pExpr)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pLeft, index);
if( ret != TSDB_CODE_SUCCESS) {
return ret;
}
ret = handleColumnInQueryCond(pCmd, pQueryInfo, pExpr->pRight, index);
return ret;
}
SStrToken* colName = NULL;
if (pExpr->tokenId == TK_ARROW) {
colName = &(pExpr->pLeft->columnName);
} else if (pExpr->tokenId == TK_ID) {
colName = &(pExpr->columnName);
}
if (colName) {
if (getColumnIndexByName(colName, pQueryInfo, index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
}
return ret;
}
static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SCondExpr* pCondExpr,
int32_t* type, int32_t* tbIdx, int32_t parentOptr, tSqlExpr** columnExpr,
tSqlExpr** tsExpr, bool joinQuery) {
......@@ -5144,7 +5205,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
const char* msg2 = "illegal column name";
const char* msg4 = "too many join tables";
const char* msg5 = "not support ordinary column join";
const char* msg6 = "illegal condition expression";
tSqlExpr* pLeft = (*pExpr)->pLeft;
tSqlExpr* pRight = (*pExpr)->pRight;
......@@ -5158,14 +5218,23 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
int32_t ret = TSDB_CODE_SUCCESS;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(colName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
if (!tSqlExprIsParentOfLeaf(*pExpr)) {
ret = handleColumnInQueryCond(pCmd, pQueryInfo, pLeft, &index);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
ret = handleColumnInQueryCond(pCmd, pQueryInfo, pRight, &index);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
} else {
if (getColumnIndexByName(colName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
}
*tbIdx = index.tableIndex;
assert(tSqlExprIsParentOfLeaf(*pExpr));
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
......@@ -5194,7 +5263,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
}
if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP && index.columnIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { // query on time range
if (!validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
if (!tSqlExprIsParentOfLeaf(*pExpr) || !validateJoinExprNode(pCmd, pQueryInfo, *pExpr, &index)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
......@@ -5316,8 +5385,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
if (pRight->tokenId == TK_ID) {
if (joinQuery) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); // other column cannot be served as the join column
} else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
}
......@@ -5368,7 +5435,7 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
int32_t leftTbIdx = 0;
int32_t rightTbIdx = 0;
if (!tSqlExprIsParentOfLeaf(*pExpr)) {
if (isLogicalOperator(*pExpr)) {
ret = getQueryCondExpr(pCmd, pQueryInfo, &(*pExpr)->pLeft, pCondExpr, type ? &leftType : NULL, &leftTbIdx, (*pExpr)->tokenId, &columnLeft, &tsLeft, joinQuery);
if (ret != TSDB_CODE_SUCCESS) {
goto err_ret;
......@@ -5429,6 +5496,11 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr
goto err_ret;
}
if (!tSqlExprIsLeaf((*pExpr)->pRight) ) {
ret = TSDB_CODE_TSC_INVALID_OPERATION;
goto err_ret;
}
ret = handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, tbIdx, parentOptr, columnExpr, tsExpr, joinQuery);
if (ret) {
goto err_ret;
......@@ -5451,19 +5523,21 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSqlExpr** pExpr, SQueryInfo*
return;
}
if (tSqlExprIsParentOfLeaf(*pExpr)) {
if (!isLogicalOperator(*pExpr)) {
tSqlExpr* pLeft = (*pExpr)->pLeft;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if(pLeft->tokenId == TK_ARROW) {
pLeft = pLeft->pLeft;
}
if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return;
}
if (pLeft->tokenId == TK_ARROW || pLeft->tokenId == TK_ID) {
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if(pLeft->tokenId == TK_ARROW) {
pLeft = pLeft->pLeft;
}
if (getColumnIndexByName(&pLeft->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return;
}
if (index.tableIndex != tableIndex) {
return;
if (index.tableIndex != tableIndex) {
return;
}
}
*pOut = *pExpr;
......@@ -5686,7 +5760,6 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf
*/
static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
const char *msg1 = "invalid tag operator";
const char* msg2 = "not supported filter condition";
do {
......@@ -5706,10 +5779,6 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
if (p->_node.pRight && (retVal = validateTagCondExpr(pCmd, p->_node.pRight)) != TSDB_CODE_SUCCESS) {
return retVal;
}
if (IS_ARITHMETIC_OPTR(p->_node.optr)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
if (!IS_RELATION_OPTR(p->_node.optr)) {
break;
......@@ -5771,8 +5840,13 @@ static int32_t validateTagCondExpr(SSqlCmd* pCmd, tExprNode *p) {
return TSDB_CODE_SUCCESS;
}
bool isTablename(char* colName) {
return (strlen(colName) == strlen(TSQL_TBNAME_L) && strncasecmp(TSQL_TBNAME_L, colName, strlen(TSQL_TBNAME_L)) == 0);
}
static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
int32_t ret = TSDB_CODE_SUCCESS;
const char* msg6 = "illegal condition expression";
if (pCondExpr->pTagCond == NULL) {
return ret;
......@@ -5788,6 +5862,17 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
ret = exprTreeFromSqlExpr(pCmd, &p, p1, pQueryInfo, colList, NULL);
size_t colNum = taosArrayGetSize(colList);
for (int32_t k = 0; k < colNum; k++) {
SColIndex* pColIndex = taosArrayGet(colList, k);
if (TSDB_COL_IS_NORMAL_COL(pColIndex->flag) && !isTablename(pColIndex->name)) {
ret = invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
break;
}
}
if (ret == TSDB_CODE_SUCCESS) {
ret = exprTreeValidateTree(tscGetErrorMsgPayload(pCmd), p);
}
//if (ret == TSDB_CODE_SUCCESS) {
// ret = filterInitFromTree(p, &pQueryInfo->tagFilter, (int32_t)taosArrayGetSize(colList), NULL);
//}
......@@ -10253,23 +10338,6 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
}
}
if (pSqlExpr->tokenId == TK_BITAND && pSqlExpr->pLeft != NULL && pSqlExpr->pRight != NULL) {
// for example: col type is "bool" but expr "col & 1" received
uint8_t colType = pLeft->pSchema->type;
SStrToken *exprToken = &pSqlExpr->pRight->exprToken;
if (pSqlExpr->pLeft->type == SQL_NODE_TABLE_COLUMN && pSqlExpr->pRight->type == SQL_NODE_VALUE) {
if (colType == TSDB_DATA_TYPE_BOOL) {
if ((exprToken->n != 4 || strncasecmp(exprToken->z, "true", 4)) && (exprToken->n != 5 || strncasecmp(exprToken->z, "false", 5))) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} else if (IS_SIGNED_NUMERIC_TYPE(colType) || IS_UNSIGNED_NUMERIC_TYPE(colType)) {
if ((exprToken->n == 4 && strncasecmp(exprToken->z, "true", 4) == 0) || (exprToken->n == 5 || strncasecmp(exprToken->z, "false", 5) == 0)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
}
}
if (pSqlExpr->pRight != NULL) {
int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) {
......@@ -10408,3 +10476,35 @@ void normalizeSqlNode(SSqlNode* pSqlNode, const char* dbName) {
}
#endif
bool isLogicalOperator(tSqlExpr* pExpr) {
if (pExpr->tokenId == TK_AND || pExpr->tokenId == TK_OR) {
return true;
}
return false;
}
bool isComparisonOperator(tSqlExpr* pExpr) {
switch (pExpr->tokenId) {
case TK_EQ:
case TK_NE:
case TK_ISNULL:
case TK_NOTNULL:
case TK_IS:
case TK_LIKE:
case TK_MATCH:
case TK_NMATCH:
case TK_CONTAINS:
case TK_GLOB:
case TK_BETWEEN:
case TK_IN:
case TK_GT:
case TK_GE:
case TK_LT:
case TK_LE:
return true;
default:
return false;
}
return false;
}
......@@ -1004,7 +1004,7 @@ static void doSetupSDataBlock(SSqlRes* pRes, SSDataBlock* pBlock, void* pFilterI
filterConverNcharColumns(pFilterInfo, pBlock->info.rows, &gotNchar);
int8_t* p = NULL;
//bool all = doFilterDataBlock(pFilterInfo, numOfFilterCols, pBlock->info.rows, p);
bool all = filterExecute(pFilterInfo, pBlock->info.rows, &p, NULL, 0);
bool all = filterExecute(pFilterInfo, pBlock->info.rows, &p, NULL, (int16_t)taosArrayGetSize(pBlock->pDataBlock));
if (gotNchar) {
filterFreeNcharColumns(pFilterInfo);
}
......
......@@ -403,267 +403,94 @@ void vectorRemainder(void *left, int32_t len1, int32_t _left_type, void *right,
}
}
typedef int64_t (*_arithmetic_getVectorBigintValue_fn_t)(void *src, int32_t index);
int64_t getVectorBigintValue_BOOL(void *src, int32_t index) {
return (int64_t)*((bool *)src + index);
}
int64_t getVectorBigintValue_TINYINT(void *src, int32_t index) {
return (int64_t)*((int8_t *)src + index);
}
int64_t getVectorBigintValue_UTINYINT(void *src, int32_t index) {
return (int64_t)*((uint8_t *)src + index);
}
int64_t getVectorBigintValue_SMALLINT(void *src, int32_t index) {
return (int64_t)*((int16_t *)src + index);
}
int64_t getVectorBigintValue_USMALLINT(void *src, int32_t index) {
return (int64_t)*((uint16_t *)src + index);
}
int64_t getVectorBigintValue_INT(void *src, int32_t index) {
return (int64_t)*((int32_t *)src + index);
}
int64_t getVectorBigintValue_UINT(void *src, int32_t index) {
return (int64_t)*((uint32_t *)src + index);
}
int64_t getVectorBigintValue_BIGINT(void *src, int32_t index) {
return (int64_t)*((int64_t *)src + index);
}
int64_t getVectorBigintValue_UBIGINT(void *src, int32_t index) {
return (int64_t)*((uint64_t *)src + index);
}
_arithmetic_getVectorBigintValue_fn_t getVectorBigintValueFn(int32_t srcType) {
_arithmetic_getVectorBigintValue_fn_t p = NULL;
if (srcType==TSDB_DATA_TYPE_BOOL) {
p = getVectorBigintValue_BOOL;
} else if (srcType==TSDB_DATA_TYPE_TINYINT) {
p = getVectorBigintValue_TINYINT;
} else if (srcType==TSDB_DATA_TYPE_UTINYINT) {
p = getVectorBigintValue_UTINYINT;
} else if (srcType==TSDB_DATA_TYPE_SMALLINT) {
p = getVectorBigintValue_SMALLINT;
} else if (srcType==TSDB_DATA_TYPE_USMALLINT) {
p = getVectorBigintValue_USMALLINT;
}else if (srcType==TSDB_DATA_TYPE_INT) {
p = getVectorBigintValue_INT;
} else if (srcType==TSDB_DATA_TYPE_UINT) {
p = getVectorBigintValue_UINT;
} else if (srcType==TSDB_DATA_TYPE_BIGINT) {
p = getVectorBigintValue_BIGINT;
} else if (srcType==TSDB_DATA_TYPE_UBIGINT) {
p = getVectorBigintValue_UBIGINT;
} else {
assert(0);
}
return p;
}
void vectorBitand(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
int32_t i = (_ord == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
int32_t step = (_ord == TSDB_ORDER_ASC) ? 1 : -1;
char *output = out;
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
double *output=(double*)out;
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
_arithmetic_getVectorBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(_left_type);
_arithmetic_getVectorBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(_right_type);
if (len1 == (len2)) {
for (; i >= 0 && i < (len2); i += step) {
if (isNull(getVectorValueAddrFnLeft(left, i), _left_type) || isNull(getVectorValueAddrFnRight(right, i), _right_type)) {
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = TSDB_DATA_BOOL_NULL;
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = TSDB_DATA_TINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = TSDB_DATA_SMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = TSDB_DATA_INT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = TSDB_DATA_BIGINT_NULL;
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = TSDB_DATA_UTINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = TSDB_DATA_USMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = TSDB_DATA_UINT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = TSDB_DATA_UBIGINT_NULL;
output += sizeof(int64_t);
break;
}
if ((len1) == (len2)) {
for (; i < (len2) && i >= 0; i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_BIGINT_NULL(output);
continue;
}
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = (*((bool *) left + i)) & (*((bool *) right + i));
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = (*((int8_t *) left + i)) & (*((int8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = (*((int16_t *) left + i)) & (*((int16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = (*((int32_t *) left + i)) & (*((int32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = (*((int64_t *) left + i)) & (*((int64_t *) right + i));
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = (*((uint8_t *) left + i)) & (*((uint8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = (*((uint16_t *) left + i)) & (*((uint16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = (*((uint32_t *) left + i)) & (*((uint32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = (*((uint64_t *) left + i)) & (*((uint64_t *) right + i));
output += sizeof(int64_t);
break;
}
*(int64_t *) output = getVectorBigintValueFnLeft(left,i) & getVectorBigintValueFnRight(right,i);
}
} else if (len1 == 1) {
for (; i >= 0 && i < (len2); i += step) {
if (isNull(getVectorValueAddrFnLeft(left, 0), _left_type) || isNull(getVectorValueAddrFnRight(right, i), _right_type)) {
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = TSDB_DATA_BOOL_NULL;
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = TSDB_DATA_TINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = TSDB_DATA_SMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = TSDB_DATA_INT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = TSDB_DATA_BIGINT_NULL;
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = TSDB_DATA_UTINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = TSDB_DATA_USMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = TSDB_DATA_UINT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = TSDB_DATA_UBIGINT_NULL;
output += sizeof(int64_t);
break;
}
} else if ((len1) == 1) {
for (; i >= 0 && i < (len2); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
SET_BIGINT_NULL(output);
continue;
}
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = (*(bool *) left) & (*((bool *) right + i));
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = (*(int8_t *) left) & (*((int8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = (*(int16_t *) left) & (*((int16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = (*(int32_t *) left) & (*((int32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = (*(int64_t *) left) & (*((int64_t *) right + i));
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = (*(uint8_t *) left) & (*((uint8_t *) right + i));
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = (*(uint16_t *) left) & (*((uint16_t *) right + i));
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = (*(uint32_t *) left) & (*((uint32_t *) right + i));
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = (*(uint64_t *) left) & (*((uint64_t *) right + i));
output += sizeof(int64_t);
break;
}
*(int64_t *) output = getVectorBigintValueFnLeft(left,0) & getVectorBigintValueFnRight(right,i);
}
} else if ((len2) == 1) {
for (; i >= 0 && i < len1; i += step) {
if (isNull(getVectorValueAddrFnLeft(left, i), _left_type) || isNull(getVectorValueAddrFnRight(right, 0), _right_type)) {
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = TSDB_DATA_BOOL_NULL;
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = TSDB_DATA_TINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = TSDB_DATA_SMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = TSDB_DATA_INT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = TSDB_DATA_BIGINT_NULL;
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = TSDB_DATA_UTINYINT_NULL;
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = TSDB_DATA_USMALLINT_NULL;
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = TSDB_DATA_UINT_NULL;
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = TSDB_DATA_UBIGINT_NULL;
output += sizeof(int64_t);
break;
}
for (; i >= 0 && i < (len1); i += step, output += 1) {
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
SET_BIGINT_NULL(output);
continue;
}
switch (_left_type) {
case TSDB_DATA_TYPE_BOOL:
*(bool *) output = (*((bool *) left + i)) & (*(bool *) right);
output += sizeof(bool);
break;
case TSDB_DATA_TYPE_TINYINT:
*(int8_t *) output = (*((int8_t *) left + i)) & (*(int8_t *) right);
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_SMALLINT:
*(int16_t *) output = (*((int16_t *) left + i)) & (*(int16_t *) right);
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_INT:
*(int32_t *) output = (*((int32_t *) left + i)) & (*(int32_t *) right);
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_BIGINT:
*(int64_t *) output = (*((int64_t *) left + i)) & (*(int64_t *) right);
output += sizeof(int64_t);
break;
case TSDB_DATA_TYPE_UTINYINT:
*(uint8_t *) output = (*((uint8_t *) left + i)) & (*(uint8_t *) right);
output += sizeof(int8_t);
break;
case TSDB_DATA_TYPE_USMALLINT:
*(uint16_t *) output = (*((uint16_t *) left + i)) & (*(uint16_t *) right);
output += sizeof(int16_t);
break;
case TSDB_DATA_TYPE_UINT:
*(uint32_t *) output = (*((uint32_t *) left + i)) & (*(uint32_t *) right);
output += sizeof(int32_t);
break;
case TSDB_DATA_TYPE_UBIGINT:
*(uint64_t *) output = (*((uint64_t *) left + i)) & (*(uint64_t *) right);
output += sizeof(int64_t);
break;
}
*(int64_t *) output = getVectorBigintValueFnLeft(left,i) & getVectorBigintValueFnRight(right,0);
}
}
}
......
......@@ -88,7 +88,6 @@ int32_t exprTreeValidateFunctionNode(char* msgbuf, tExprNode *pExpr) {
int32_t exprTreeValidateExprNode(tExprNode *pExpr) {
int16_t leftType = pExpr->_node.pLeft->resultType;
int16_t rightType = pExpr->_node.pRight->resultType;
int16_t resultType = leftType;
if (pExpr->_node.optr == TSDB_BINARY_OP_ADD || pExpr->_node.optr == TSDB_BINARY_OP_SUBTRACT ||
pExpr->_node.optr == TSDB_BINARY_OP_MULTIPLY || pExpr->_node.optr == TSDB_BINARY_OP_DIVIDE ||
......@@ -100,169 +99,15 @@ int32_t exprTreeValidateExprNode(tExprNode *pExpr) {
pExpr->resultBytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
return TSDB_CODE_SUCCESS;
} else if (pExpr->_node.optr == TSDB_BINARY_OP_BITAND) {
if ((leftType != TSDB_DATA_TYPE_BOOL && !IS_SIGNED_NUMERIC_TYPE(leftType) && !IS_UNSIGNED_NUMERIC_TYPE(leftType)) ||
(rightType != TSDB_DATA_TYPE_BOOL && !IS_SIGNED_NUMERIC_TYPE(rightType) && !IS_UNSIGNED_NUMERIC_TYPE(rightType)))
{
if (! (IS_NUMERIC_TYPE(leftType)|| leftType == TSDB_DATA_TYPE_BOOL)
|| ! (IS_NUMERIC_TYPE(rightType) || rightType == TSDB_DATA_TYPE_BOOL)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
uint8_t schemaType;
// now leftType and rightType are both numeric
if (pExpr->_node.pLeft->nodeType == TSQL_NODE_COL && pExpr->_node.pRight->nodeType == TSQL_NODE_COL) {
if (leftType != rightType) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} else if (pExpr->_node.pLeft->nodeType == TSQL_NODE_COL) {
if (pExpr->_node.pRight->nodeType != TSQL_NODE_VALUE) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else {
schemaType = pExpr->_node.pLeft->pSchema->type;
int64_t sVal = pExpr->_node.pRight->pVal->i64;
uint64_t uVal = pExpr->_node.pRight->pVal->u64;
switch (schemaType) {
case TSDB_DATA_TYPE_BOOL:
if ((pExpr->_node.pRight->pVal->nType != TSDB_DATA_TYPE_BOOL) ||
(pExpr->_node.pRight->pVal->i64 != 0 &&
pExpr->_node.pRight->pVal->i64 != 1 &&
pExpr->_node.pRight->pVal->i64 != TSDB_DATA_BOOL_NULL))
{
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_TINYINT:
if (sVal < -128 || sVal > 127) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_SMALLINT:
if (sVal < -32768 || sVal > 32767) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_INT:
if (sVal < INT32_MIN || sVal > INT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_BIGINT:
if (sVal < INT64_MIN || sVal > INT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_UTINYINT:
if (uVal > 255) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_USMALLINT:
if (uVal > 65535) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_UINT:
if (uVal > UINT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
case TSDB_DATA_TYPE_UBIGINT:
if (uVal > UINT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
break;
}
pExpr->_node.pRight->pSchema->type = schemaType;
pExpr->_node.pRight->pVal->nType = schemaType;
pExpr->_node.pRight->resultType = schemaType;
pExpr->_node.pRight->resultBytes = tDataTypes[schemaType].bytes;
}
} else {
if (pExpr->_node.pLeft->nodeType != TSQL_NODE_VALUE) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else {
schemaType = pExpr->_node.pRight->pSchema->type;
int64_t sVal = pExpr->_node.pLeft->pVal->i64;
uint64_t uVal = pExpr->_node.pLeft->pVal->u64;
switch (schemaType) {
case TSDB_DATA_TYPE_BOOL:
if ((pExpr->_node.pLeft->pVal->nType != TSDB_DATA_TYPE_BOOL) ||
(pExpr->_node.pLeft->pVal->i64 != 0 &&
pExpr->_node.pLeft->pVal->i64 != 1 &&
pExpr->_node.pLeft->pVal->i64 != TSDB_DATA_BOOL_NULL))
{
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 1;
break;
case TSDB_DATA_TYPE_TINYINT:
if (sVal < -128 || sVal > 127) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 1;
break;
case TSDB_DATA_TYPE_SMALLINT:
if (sVal < -32768 || sVal > 32767) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 2;
break;
case TSDB_DATA_TYPE_INT:
if (sVal < INT32_MIN || sVal > INT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 4;
break;
case TSDB_DATA_TYPE_BIGINT:
if (sVal < INT64_MIN || sVal > INT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 8;
break;
case TSDB_DATA_TYPE_UTINYINT:
if (uVal > 255) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 1;
break;
case TSDB_DATA_TYPE_USMALLINT:
if (uVal > 65535) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 2;
break;
case TSDB_DATA_TYPE_UINT:
if (uVal > UINT32_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 4;
break;
case TSDB_DATA_TYPE_UBIGINT:
if (uVal > UINT64_MAX) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->_node.pLeft->pVal->nLen = 8;
break;
}
pExpr->_node.pLeft->pSchema->type = schemaType;
pExpr->_node.pLeft->pVal->nType = schemaType;
pExpr->_node.pLeft->resultType = schemaType;
pExpr->_node.pLeft->resultBytes = tDataTypes[schemaType].bytes;
}
resultType = schemaType;
}
if (resultType == TSDB_DATA_TYPE_BOOL) {
pExpr->resultType = TSDB_DATA_TYPE_BOOL;
pExpr->resultBytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
} else {
pExpr->resultType = resultType;
pExpr->resultBytes = tDataTypes[resultType].bytes;
if (IS_FLOAT_TYPE(leftType) || IS_FLOAT_TYPE(rightType)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pExpr->resultType = TSDB_DATA_TYPE_BIGINT;
pExpr->resultBytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
return TSDB_CODE_SUCCESS;
} else {
return TSDB_CODE_SUCCESS;
......
......@@ -289,6 +289,7 @@ void* getDataMax(int32_t type);
int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bool issigned);
#define SET_DOUBLE_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_DOUBLE_NULL)
#define SET_BIGINT_NULL(v) (*(int64_t *)(v) = TSDB_DATA_BIGINT_NULL)
#ifdef __cplusplus
}
......
......@@ -39,10 +39,11 @@ extern "C" {
enum {
FLD_TYPE_COLUMN = 1,
FLD_TYPE_VALUE = 2,
FLD_TYPE_MAX = 3,
FLD_DESC_NO_FREE = 4,
FLD_DATA_NO_FREE = 8,
FLD_DATA_IS_HASH = 16,
FLD_TYPE_EXPR = 3,
FLD_TYPE_MAX = 4,
FLD_DESC_NO_FREE = 16,
FLD_DATA_NO_FREE = 32,
FLD_DATA_IS_HASH = 64,
};
enum {
......@@ -182,6 +183,7 @@ typedef struct SFilterGroupCtx {
uint32_t colNum;
uint32_t *colIdx;
SFilterColInfo *colInfo;
bool hasExpr;
} SFilterGroupCtx;
typedef struct SFilterColCtx {
......@@ -206,6 +208,8 @@ typedef struct SFilterComUnit {
void *colData;
void *valData;
void *valData2;
void *expr;
void *exprData;
uint16_t colId;
uint16_t dataSize;
uint8_t dataType;
......@@ -289,7 +293,10 @@ typedef struct SFilterInfo {
#define FILTER_GET_VAL_FIELD_TYPE(fi) (((tVariant *)((fi)->desc))->nType)
#define FILTER_GET_VAL_FIELD_DATA(fi) ((char *)(fi)->data)
#define FILTER_GET_JSON_VAL_FIELD_DATA(fi) ((char *)(fi)->desc)
#define FILTER_GET_TYPE(fl) ((fl) & FLD_TYPE_MAX)
#define FILTER_GET_TYPE(fl) ((fl) & 0xF)
#define FILTER_GET_FIELD_DESC(fi) ((fi)->desc)
#define FILTER_GET_EXPR_TYPE(i, id) (((tExprNode*)(FILTER_GET_FIELD_DESC(FILTER_GET_FIELD(i, id))))->resultType)
#define FILTER_GET_EXPR_SIZE(i, id) (((tExprNode*)(FILTER_GET_FIELD_DESC(FILTER_GET_FIELD(i, id))))->resultBytes)
#define FILTER_GROUP_UNIT(i, g, uid) ((i)->units + (g)->unitIdxs[uid])
#define FILTER_UNIT_LEFT_FIELD(i, u) FILTER_GET_FIELD(i, (u)->left)
......
......@@ -3155,6 +3155,10 @@ void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFi
FORCE_INLINE int32_t getColumnDataFromId(void *param, int32_t id, void **data) {
int32_t numOfCols = ((SColumnDataParam *)param)->numOfCols;
SArray* pDataBlock = ((SColumnDataParam *)param)->pDataBlock;
if (id == INT32_MAX) {
*data = pDataBlock;
return TSDB_CODE_SUCCESS;
}
for (int32_t j = 0; j < numOfCols; ++j) {
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, j);
......
......@@ -54,11 +54,16 @@ static FORCE_INLINE int32_t filterFieldValDescCompare(const void *desc1, const v
return tVariantCompare(val1, val2);
}
static FORCE_INLINE int32_t filterExprCompare(const void *desc1, const void *desc2) {
return -1;
}
filter_desc_compare_func gDescCompare [FLD_TYPE_MAX] = {
NULL,
filterFieldColDescCompare,
filterFieldValDescCompare
filterFieldValDescCompare,
filterExprCompare
};
bool filterRangeCompGi (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
......@@ -833,7 +838,7 @@ int32_t filterAddField(SFilterInfo *info, void *desc, void **data, int32_t type,
info->fields[type].fields[idx].desc = desc;
info->fields[type].fields[idx].data = data ? *data : NULL;
if (type == FLD_TYPE_COLUMN) {
if (type == FLD_TYPE_COLUMN || type == FLD_TYPE_EXPR) {
FILTER_SET_FLAG(info->fields[type].fields[idx].flag, FLD_DATA_NO_FREE);
}
......@@ -873,7 +878,8 @@ static FORCE_INLINE int32_t filterAddColFieldFromField(SFilterInfo *info, SFilte
int32_t filterAddFieldFromNode(SFilterInfo *info, tExprNode *node, SFilterFieldId *fid) {
CHK_LRET(node == NULL, TSDB_CODE_QRY_APP_ERROR, "empty node");
CHK_RET(node->nodeType != TSQL_NODE_COL && node->nodeType != TSQL_NODE_VALUE, TSDB_CODE_QRY_APP_ERROR);
CHK_RET(node->nodeType != TSQL_NODE_COL && node->nodeType != TSQL_NODE_VALUE
&&node->nodeType != TSQL_NODE_EXPR, TSDB_CODE_QRY_APP_ERROR);
int32_t type;
void *v;
......@@ -882,6 +888,9 @@ int32_t filterAddFieldFromNode(SFilterInfo *info, tExprNode *node, SFilterFieldI
type = FLD_TYPE_COLUMN;
v = node->pSchema;
node->pSchema = NULL;
} else if (node->nodeType == TSQL_NODE_EXPR) {
type = FLD_TYPE_EXPR;
v = node;
} else {
type = FLD_TYPE_VALUE;
v = node->pVal;
......@@ -933,9 +942,11 @@ int32_t filterAddUnit(SFilterInfo *info, uint8_t optr, SFilterFieldId *left, SFi
}
SFilterField *col = FILTER_UNIT_LEFT_FIELD(info, u);
assert(FILTER_GET_FLAG(col->flag, FLD_TYPE_COLUMN));
info->units[info->unitNum].compare.type = FILTER_GET_COL_FIELD_TYPE(col);
if (FILTER_GET_TYPE(col->flag) == FLD_TYPE_COLUMN) {
info->units[info->unitNum].compare.type = FILTER_GET_COL_FIELD_TYPE(col);
} else {
info->units[info->unitNum].compare.type = (uint8_t)FILTER_GET_EXPR_TYPE(info, u->left);
}
*uidx = info->unitNum;
......@@ -1188,7 +1199,7 @@ static int32_t filterDealJson(SFilterInfo *info, tExprNode* tree, tExprNode** pL
jsonKeyMd5((*pLeft)->_node.pRight->pVal->pz, (*pLeft)->_node.pRight->pVal->nLen, keyMd5);
memcpy(schema->name, keyMd5, TSDB_MAX_JSON_KEY_MD5_LEN);
(*pLeft) = (*pLeft)->_node.pLeft; // -> operation use left as input
}else if(((*pLeft)->pSchema->type == TSDB_DATA_TYPE_JSON) &&
}else if((*pLeft)->nodeType == TSQL_NODE_COL && ((*pLeft)->pSchema->type == TSDB_DATA_TYPE_JSON) &&
(tree->_node.optr == TSDB_RELATION_ISNULL || tree->_node.optr == TSDB_RELATION_NOTNULL)){
SSchema* schema = (*pLeft)->pSchema;
char keyMd5[TSDB_MAX_JSON_KEY_MD5_LEN] = {0};
......@@ -1212,7 +1223,16 @@ int32_t filterAddGroupUnitFromNode(SFilterInfo *info, tExprNode* tree, SArray *g
if((ret = filterDealJson(info, tree, &pLeft)) != TSDB_CODE_SUCCESS) return ret;
SFilterFieldId left = {0}, right = {0};
filterAddFieldFromNode(info, pLeft, &left);
uint8_t type = FILTER_GET_COL_FIELD_TYPE(FILTER_GET_FIELD(info, left));
if (pLeft->nodeType != TSQL_NODE_VALUE && pLeft->nodeType != TSQL_NODE_COL) {
tree->_node.pLeft = NULL;
}
uint8_t type;
if (left.type == FLD_TYPE_EXPR) {
type = (uint8_t)FILTER_GET_EXPR_TYPE(info, left);
} else {
type = FILTER_GET_COL_FIELD_TYPE(FILTER_GET_FIELD(info, left));
}
int32_t len = 0;
uint32_t uidx = 0;
......@@ -1576,6 +1596,9 @@ void filterDumpInfoToString(SFilterInfo *info, const char *msg, int32_t options)
char str[512] = {0};
SFilterField *left = FILTER_UNIT_LEFT_FIELD(info, unit);
if (FILTER_GET_TYPE(left->flag) == FLD_TYPE_EXPR) {
continue;
}
SSchema *sch = left->desc;
if (unit->compare.optr >= TSDB_RELATION_INVALID && unit->compare.optr <= TSDB_RELATION_CONTAINS){
len = sprintf(str, "UNIT[%d] => [%d][%s] %s [", i, sch->colId, sch->name, gOptrStr[unit->compare.optr].str);
......@@ -1751,6 +1774,9 @@ void filterFreeField(SFilterField* field, int32_t type) {
if (!FILTER_GET_FLAG(field->flag, FLD_DESC_NO_FREE)) {
if (type == FLD_TYPE_VALUE) {
tVariantDestroy(field->desc);
} else if (type == FLD_TYPE_EXPR) {
tExprTreeDestroy(field->desc, NULL);
field->desc = NULL;
}
tfree(field->desc);
......@@ -2100,6 +2126,9 @@ _return:
int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t* gResNum) {
bool empty = false;
if (info->fields[FLD_TYPE_COLUMN].num == 0) {
return TSDB_CODE_SUCCESS;
}
uint32_t *colIdx = malloc(info->fields[FLD_TYPE_COLUMN].num * sizeof(uint32_t));
uint32_t colIdxi = 0;
uint32_t gResIdx = 0;
......@@ -2109,11 +2138,16 @@ int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t
gRes[gResIdx] = calloc(1, sizeof(SFilterGroupCtx));
gRes[gResIdx]->colInfo = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(SFilterColInfo));
gRes[gResIdx]->hasExpr = false;
colIdxi = 0;
empty = false;
for (uint32_t j = 0; j < g->unitNum; ++j) {
SFilterUnit* u = FILTER_GROUP_UNIT(info, g, j);
if(u->left.type == FLD_TYPE_EXPR) {
gRes[gResIdx]->hasExpr = true;
continue;
}
uint32_t cidx = FILTER_UNIT_COL_IDX(u);
if (gRes[gResIdx]->colInfo[cidx].info == NULL) {
......@@ -2174,6 +2208,10 @@ int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t
void filterCheckColConflict(SFilterGroupCtx* gRes1, SFilterGroupCtx* gRes2, bool *conflict) {
uint32_t idx1 = 0, idx2 = 0, m = 0, n = 0;
bool equal = false;
if (gRes1->hasExpr || gRes2->hasExpr) {
*conflict = true;
return;
}
for (; m < gRes1->colNum; ++m) {
idx1 = gRes1->colIdx[m];
......@@ -2646,7 +2684,12 @@ int32_t filterGenerateComInfo(SFilterInfo *info) {
info->cunits[i].rfunc = filterGetRangeCompFuncFromOptrs(unit->compare.optr, unit->compare.optr2);
info->cunits[i].optr = FILTER_UNIT_OPTR(unit);
info->cunits[i].colData = NULL;
info->cunits[i].colId = FILTER_UNIT_COL_ID(info, unit);
info->cunits[i].expr = NULL;
if (unit->left.type == FLD_TYPE_COLUMN) {
info->cunits[i].colId = FILTER_UNIT_COL_ID(info, unit);
} else if (unit->left.type == FLD_TYPE_EXPR) {
info->cunits[i].expr = FILTER_GET_FIELD_DESC(FILTER_GET_FIELD(info, unit->left));
}
if (unit->right.type == FLD_TYPE_VALUE) {
if(FILTER_UNIT_DATA_TYPE(unit) == TSDB_DATA_TYPE_JSON){ // json value is tVariant
......@@ -2662,8 +2705,12 @@ int32_t filterGenerateComInfo(SFilterInfo *info) {
} else {
info->cunits[i].valData2 = info->cunits[i].valData;
}
info->cunits[i].dataSize = FILTER_UNIT_COL_SIZE(info, unit);
if (unit->left.type == FLD_TYPE_COLUMN) {
info->cunits[i].dataSize = FILTER_UNIT_COL_SIZE(info, unit);
} else {
info->cunits[i].dataSize = FILTER_GET_EXPR_SIZE(info, unit->left);
}
info->cunits[i].dataType = FILTER_UNIT_DATA_TYPE(unit);
}
......@@ -2673,8 +2720,14 @@ int32_t filterGenerateComInfo(SFilterInfo *info) {
int32_t filterUpdateComUnits(SFilterInfo *info) {
for (uint32_t i = 0; i < info->unitNum; ++i) {
SFilterUnit *unit = &info->units[i];
info->cunits[i].colData = FILTER_UNIT_COL_DATA(info, unit, 0);
if (unit->left.type == FLD_TYPE_EXPR) {
SFilterField *t = FILTER_UNIT_LEFT_FIELD(info, unit);
info->cunits[i].colData = NULL;
info->cunits[i].exprData = t->data;
} else {
info->cunits[i].colData = FILTER_UNIT_COL_DATA(info, unit, 0);
info->cunits[i].exprData = NULL;
}
}
return TSDB_CODE_SUCCESS;
......@@ -2953,6 +3006,20 @@ _return:
return TSDB_CODE_SUCCESS;
}
char *getExprColumnData(void *param, const char* name, int32_t colId) {
void *data = NULL;
getColumnDataFromId(param, colId, &data);
return (char *) data;
}
void* filterExprTraverse (SFilterInfo *info, int32_t numOfRows, int16_t numOfCols) {
tExprOperandInfo output;
output.data = malloc(sizeof(int64_t) * numOfRows);
SSDataBlock* pBlock = (SSDataBlock*) info->cunits[0].exprData;
SColumnDataParam param = {.numOfCols = numOfCols, .pDataBlock = (SArray*)pBlock};
exprTreeNodeTraverse(info->cunits[0].expr, numOfRows, &output, &param, TSDB_ORDER_ASC, getExprColumnData);
return output.data;
}
static FORCE_INLINE bool filterExecuteImplAll(void *info, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols) {
return true;
......@@ -2963,18 +3030,26 @@ static FORCE_INLINE bool filterExecuteImplEmpty(void *info, int32_t numOfRows, i
static FORCE_INLINE bool filterExecuteImplIsNull(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
char *exprData = NULL;
uint32_t uidx = info->groups[0].unitIdxs[0];
void *colData = NULL;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
if (info->cunits[0].expr) {
exprData = filterExprTraverse(info, numOfRows, numOfCols);
} else {
exprData = info->cunits[uidx].colData;
}
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
uint32_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
colData = (char *)exprData + info->cunits[uidx].dataSize * i;
if(info->cunits[uidx].dataType == TSDB_DATA_TYPE_JSON){
if (!colData){ // for json->'key' is null
(*p)[i] = 1;
......@@ -2992,23 +3067,35 @@ static FORCE_INLINE bool filterExecuteImplIsNull(void *pinfo, int32_t numOfRows,
}
}
if (info->cunits[0].expr) {
tfree(exprData);
}
return all;
}
static FORCE_INLINE bool filterExecuteImplNotNull(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
char *exprData = NULL;
uint32_t uidx = info->groups[0].unitIdxs[0];
void *colData = NULL;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
if (info->cunits[0].expr) {
exprData = filterExprTraverse(info, numOfRows, numOfCols);
} else {
exprData = info->cunits[uidx].colData;
}
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
uint32_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
colData = (char *)exprData + info->cunits[uidx].dataSize * i;
if(info->cunits[uidx].dataType == TSDB_DATA_TYPE_JSON){
if (!colData) { // for json->'key' is not null
......@@ -3028,6 +3115,10 @@ static FORCE_INLINE bool filterExecuteImplNotNull(void *pinfo, int32_t numOfRows
}
}
if (info->cunits[0].expr) {
tfree(exprData);
}
return all;
}
......@@ -3081,11 +3172,16 @@ bool filterExecuteImplRange(void *pinfo, int32_t numOfRows, int8_t** p, SDataSta
void *valData = info->cunits[0].valData;
void *valData2 = info->cunits[0].valData2;
__compar_fn_t func = gDataCompare[info->cunits[0].func];
char *exprData = NULL;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
if (info->cunits[0].expr) {
exprData = colData = filterExprTraverse(info, numOfRows, numOfCols);
}
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
......@@ -3105,6 +3201,9 @@ bool filterExecuteImplRange(void *pinfo, int32_t numOfRows, int8_t** p, SDataSta
colData += dataSize;
}
if (info->cunits[0].expr) {
tfree(exprData);
}
return all;
}
......@@ -3112,18 +3211,26 @@ bool filterExecuteImplRange(void *pinfo, int32_t numOfRows, int8_t** p, SDataSta
bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
char *exprData = NULL;
uint32_t uidx = info->groups[0].unitIdxs[0];
void *colData = NULL;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
if (info->cunits[0].expr) {
exprData = filterExprTraverse(info, numOfRows, numOfCols);
} else {
exprData = info->cunits[uidx].colData;
}
if (*p == NULL) {
*p = calloc(numOfRows, sizeof(int8_t));
}
for (int32_t i = 0; i < numOfRows; ++i) {
uint32_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
colData = (char *)exprData + info->cunits[uidx].dataSize * i;
if (colData == NULL || isNull(colData, info->cunits[uidx].dataType)) {
(*p)[i] = 0;
all = false;
......@@ -3152,6 +3259,10 @@ bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SDataStat
}
}
if (info->cunits[0].expr) {
tfree(exprData);
}
return all;
}
......@@ -3167,6 +3278,27 @@ bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *
*p = calloc(numOfRows, sizeof(int8_t));
}
SArray* tmpData = NULL;
for (uint32_t g = 0; g < info->groupNum; ++g) {
SFilterGroup *group = &info->groups[g];
for (uint32_t u = 0; u < group->unitNum; ++u) {
uint32_t uidx = group->unitIdxs[u];
SFilterComUnit *cunit = &info->cunits[uidx];
if (cunit->expr) {
if (!tmpData) {
tmpData = taosArrayInit(10, POINTER_BYTES);
}
tExprOperandInfo output;
output.data = malloc(sizeof(int64_t) * numOfRows);
taosArrayPush(tmpData, output.data);
SSDataBlock* pBlock = (SSDataBlock*) cunit->exprData;
SColumnDataParam param = {.numOfCols = numOfCols, .pDataBlock = (SArray*)pBlock};
exprTreeNodeTraverse(cunit->expr, numOfRows, &output, &param, TSDB_ORDER_ASC, getExprColumnData);
cunit->colData = (char *) output.data;
}
}
}
for (int32_t i = 0; i < numOfRows; ++i) {
//FILTER_UNIT_CLR_F(info);
......@@ -3228,6 +3360,9 @@ bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SDataStatis *
}
}
if (tmpData) {
taosArrayDestroy(&tmpData);
}
return all;
}
......@@ -3317,7 +3452,8 @@ _return:
int32_t filterSetColFieldData(SFilterInfo *info, void *param, filer_get_col_from_id fp) {
CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "info NULL");
CHK_LRET(info->fields[FLD_TYPE_COLUMN].num <= 0, TSDB_CODE_QRY_APP_ERROR, "no column fileds");
CHK_LRET(info->fields[FLD_TYPE_COLUMN].num <= 0 && info->fields[FLD_TYPE_EXPR].num <= 0,
TSDB_CODE_QRY_APP_ERROR, "no column fileds");
if (FILTER_ALL_RES(info) || FILTER_EMPTY_RES(info)) {
return TSDB_CODE_SUCCESS;
......@@ -3330,6 +3466,11 @@ int32_t filterSetColFieldData(SFilterInfo *info, void *param, filer_get_col_from
(*fp)(param, sch->colId, &fi->data);
}
for (uint32_t i = 0; i < info->fields[FLD_TYPE_EXPR].num; ++i) {
SFilterField* fi = &info->fields[FLD_TYPE_EXPR].fields[i];
(*fp)(param, INT32_MAX, &fi->data);
}
filterUpdateComUnits(info);
return TSDB_CODE_SUCCESS;
......
......@@ -173,6 +173,11 @@ typedef struct SRange {
int32_t to;
} SRange;
typedef struct STagBlockInfo {
SSkipListNode *pSkipListNode;
SArray *pBlock;
} STagBlockInfo;
static STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList);
static int32_t checkForCachedLastRow(STsdbQueryHandle* pQueryHandle, STableGroupInfo *groupList);
static int32_t checkForCachedLast(STsdbQueryHandle* pQueryHandle);
......@@ -4334,7 +4339,15 @@ static FORCE_INLINE int32_t tsdbGetTagDataFromId(void *param, int32_t id, void *
return TSDB_CODE_SUCCESS;
}
static FORCE_INLINE int32_t tsdbGetTagData(void *param, int32_t id, void **data) {
STagBlockInfo* pInfo = (STagBlockInfo*) param;
if (id == INT32_MAX) {
*data = pInfo->pBlock;
} else {
return tsdbGetTagDataFromId(pInfo->pSkipListNode, id, data);
}
return TSDB_CODE_SUCCESS;
}
static void queryIndexedColumn(SSkipList* pSkipList, void* filterInfo, SArray* res) {
SSkipListIterator* iter = NULL;
......@@ -4389,26 +4402,77 @@ static void queryIndexedColumn(SSkipList* pSkipList, void* filterInfo, SArray* r
tsdbDebug("filter index column end");
}
static void getAllExprColId(tExprNode* pExpr, SArray* array) {
if (!pExpr) {
return;
}
if (pExpr->nodeType == TSQL_NODE_FUNC) {
for (int32_t i = 0; i < pExpr->_func.numChildren; ++i) {
getAllExprColId(pExpr->_func.pChildren[i], array);
}
} else if (pExpr->nodeType == TSQL_NODE_EXPR) {
getAllExprColId(pExpr->_node.pLeft, array);
getAllExprColId(pExpr->_node.pRight, array);
} else if (pExpr->nodeType == TSQL_NODE_COL) {
taosArrayPush(array, &pExpr->pSchema->colId);
}
}
static void getAllFilterExprColId(SFilterFields* pSf, SArray* array) {
for (uint32_t i = 0; i < pSf->num; ++i) {
SFilterField* fi = &(pSf->fields[i]);
if (FILTER_GET_TYPE(fi->flag) == FLD_TYPE_EXPR) {
getAllExprColId(fi->desc, array);
}
}
taosArraySort(array, getComparFunc(TSDB_DATA_TYPE_SMALLINT, 0));
taosArrayRemoveDuplicate(array, getComparFunc(TSDB_DATA_TYPE_SMALLINT, 0), NULL);
}
static void queryIndexlessColumn(SSkipList* pSkipList, void* filterInfo, SArray* res) {
SSkipListIterator* iter = tSkipListCreateIter(pSkipList);
int8_t *addToResult = NULL;
SFilterInfo *sfInfo = (SFilterInfo *)filterInfo;
SArray *array = NULL;
SArray *pDataBlock = NULL;
if (sfInfo->fields[FLD_TYPE_EXPR].num > 0) {
array = taosArrayInit(10, sizeof(int16_t));
getAllFilterExprColId(&(sfInfo->fields[FLD_TYPE_EXPR]), array);
}
while (tSkipListIterNext(iter)) {
SSkipListNode *pNode = tSkipListIterGet(iter);
filterSetColFieldData(filterInfo, pNode, tsdbGetTagDataFromId);
char *pData = SL_GET_NODE_DATA(pNode);
if (sfInfo->fields[FLD_TYPE_EXPR].num > 0) {
pDataBlock = taosArrayInit(10, sizeof(SColumnInfoData));
size_t num = taosArrayGetSize(array);
for(int32_t i = 0; i < num; ++i) {
int16_t *pColId = taosArrayGet(array, i);
void *data = NULL;
tsdbGetTagDataFromId(pNode, *pColId, &data);
SColumnInfoData colData = {{0}};
colData.pData = data;
colData.info.colId = *pColId;
taosArrayPush(pDataBlock, &colData);
}
}
STagBlockInfo stInfo = {.pSkipListNode = pNode, .pBlock = pDataBlock};
filterSetColFieldData(filterInfo, &stInfo, tsdbGetTagData);
bool all = filterExecute(filterInfo, 1, &addToResult, NULL, 0);
char *pData = SL_GET_NODE_DATA(pNode);
int16_t numOfCols = array ? (int16_t)taosArrayGetSize(array) : 0;
bool all = filterExecute(filterInfo, 1, &addToResult, NULL, numOfCols);
if (all || (addToResult && *addToResult)) {
STableKeyInfo info = {.pTable = (void*)pData, .lastKey = TSKEY_INITIAL_VAL};
taosArrayPush(res, &info);
}
taosArrayDestroy(&pDataBlock);
}
taosArrayDestroy(&array);
tfree(addToResult);
tSkipListDestroyIter(iter);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册