提交 9bd02b1c 编写于 作者: S shenglian zhou

support function as expression tree node

上级 fb2ca78d
...@@ -4380,36 +4380,37 @@ static int32_t validateSQLExprTerm(SSqlCmd* pCmd, tSqlExpr* pExpr, ...@@ -4380,36 +4380,37 @@ static int32_t validateSQLExprTerm(SSqlCmd* pCmd, tSqlExpr* pExpr,
if (uidLeft != uidRight && uidLeft != 0 && uidRight != 0) { if (uidLeft != uidRight && uidLeft != 0 && uidRight != 0) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
*uid = uidLeft; }
} else if (pExpr->type == SQL_NODE_SQLFUNCTION) { *uid = uidLeft;
validateArithmeticSQLFunc(pCmd, pExpr, pQueryInfo, pList, type, uid);
} else if (pExpr->type == SQL_NODE_TABLE_COLUMN) {
if (*type == NON_ARITHMEIC_EXPR) {
*type = NORMAL_ARITHMETIC;
} else if (*type == AGG_ARIGHTMEIC) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
SColumnIndex index = COLUMN_INDEX_INITIALIZER; } else if (pExpr->type == SQL_NODE_SQLFUNCTION) {
if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != validateArithmeticSQLFunc(pCmd, pExpr, pQueryInfo, pList, type, uid);
TSDB_CODE_SUCCESS) { } else if (pExpr->type == SQL_NODE_TABLE_COLUMN) {
return TSDB_CODE_TSC_INVALID_OPERATION; if (*type == NON_ARITHMEIC_EXPR) {
} *type = NORMAL_ARITHMETIC;
} else if (*type == AGG_ARIGHTMEIC) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql SColumnIndex index = COLUMN_INDEX_INITIALIZER;
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta; if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) !=
SSchema* pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex; TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) || // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
(pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)) { STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
return TSDB_CODE_TSC_INVALID_OPERATION; SSchema* pSchema = tscGetTableSchema(pTableMeta) + index.columnIndex;
}
pList->ids[pList->num++] = index; if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) ||
} else if ((pExpr->tokenId == TK_FLOAT && (isnan(pExpr->value.dKey) || isinf(pExpr->value.dKey))) || (pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)) {
pExpr->tokenId == TK_NULL) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
pList->ids[pList->num++] = index;
} else if ((pExpr->tokenId == TK_FLOAT && (isnan(pExpr->value.dKey) || isinf(pExpr->value.dKey))) ||
pExpr->tokenId == TK_NULL) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -9266,33 +9267,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf ...@@ -9266,33 +9267,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
} }
int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, uint64_t *uid) { int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, uint64_t *uid) {
tExprNode* pLeft = NULL; if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL) {
tExprNode* pRight= NULL;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (pSqlExpr->pLeft != NULL) {
int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
}
if (pSqlExpr->pRight != NULL) {
int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(pLeft, NULL);
return ret;
}
}
if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL && pSqlExpr->tokenId == 0) {
*pExpr = calloc(1, sizeof(tExprNode));
return TSDB_CODE_SUCCESS;
}
if (pSqlExpr->pLeft == NULL) { // it is the leaf node
assert(pSqlExpr->pRight == NULL);
if (pSqlExpr->type == SQL_NODE_VALUE) { if (pSqlExpr->type == SQL_NODE_VALUE) {
int32_t ret = TSDB_CODE_SUCCESS; int32_t ret = TSDB_CODE_SUCCESS;
*pExpr = calloc(1, sizeof(tExprNode)); *pExpr = calloc(1, sizeof(tExprNode));
...@@ -9306,7 +9281,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -9306,7 +9281,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
if (colSize > 0) { if (colSize > 0) {
SColIndex* idx = taosArrayGet(pCols, colSize - 1); SColIndex* idx = taosArrayGet(pCols, colSize - 1);
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx->colIndex); SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, idx->colIndex);
// convert time by precision // convert time by precision
if (pSchema != NULL && TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && TSDB_DATA_TYPE_BINARY == (*pExpr)->pVal->nType) { if (pSchema != NULL && TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && TSDB_DATA_TYPE_BINARY == (*pExpr)->pVal->nType) {
...@@ -9315,52 +9290,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -9315,52 +9290,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
} }
} }
return ret; return ret;
} else if (pSqlExpr->type == SQL_NODE_SQLFUNCTION) { } else if (pSqlExpr->type == SQL_NODE_TABLE_COLUMN) { // column name, normal column arithmetic expression
if (TSDB_FUNC_IS_SCALAR(pSqlExpr->functionId)) { SColumnIndex index = COLUMN_INDEX_INITIALIZER;
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_FUNC;
(*pExpr)->_func.functionId = pSqlExpr->functionId;
SArray* paramList = pSqlExpr->Expr.paramList;
size_t paramSize = taosArrayGetSize(paramList);
if (paramSize > 0) {
(*pExpr)->_func.numChilds = paramSize;
(*pExpr)->_func.pChilds = (tExprNode**)calloc(paramSize, sizeof(tExprNode*));
}
for (int i = 0; i < taosArrayGetSize(paramList); ++i) {
tSqlExprItem* param = taosArrayGet(paramList, i);
tSqlExpr* paramNode = param->pNode;
int32_t ret = exprTreeFromSqlExpr(pCmd, (*pExpr)->_func.pChilds+i, paramNode, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
}
} else {
// arithmetic expression on the results of aggregation functions
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_COL;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
strncpy((*pExpr)->pSchema->name, pSqlExpr->exprToken.z, pSqlExpr->exprToken.n);
// set the input column data byte and type.
size_t size = taosArrayGetSize(pQueryInfo->exprList);
for (int32_t i = 0; i < size; ++i) {
SExprInfo* p1 = taosArrayGetP(pQueryInfo->exprList, i);
if (strcmp((*pExpr)->pSchema->name, p1->base.aliasName) == 0) {
(*pExpr)->pSchema->type = (uint8_t)p1->base.resType;
(*pExpr)->pSchema->bytes = p1->base.resBytes;
(*pExpr)->pSchema->colId = p1->base.resColId;
if (uid != NULL) {
*uid = p1->base.uid;
}
break;
}
} // endfor each expr
} // end not scalar function
} else if (pSqlExpr->type == SQL_NODE_TABLE_COLUMN) { // column name, normal column arithmetic expression
int32_t ret = getColumnIndexByName(&pSqlExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)); int32_t ret = getColumnIndexByName(&pSqlExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd));
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
return ret; return ret;
...@@ -9368,14 +9300,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -9368,14 +9300,14 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
pQueryInfo->curTableIdx = index.tableIndex; pQueryInfo->curTableIdx = index.tableIndex;
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta; STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
int32_t numOfColumns = tscGetNumOfColumns(pTableMeta); int32_t numOfColumns = tscGetNumOfColumns(pTableMeta);
*pExpr = calloc(1, sizeof(tExprNode)); *pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_COL; (*pExpr)->nodeType = TSQL_NODE_COL;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema)); (*pExpr)->pSchema = calloc(1, sizeof(SSchema));
SSchema* pSchema = NULL; SSchema* pSchema = NULL;
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
pSchema = (*pExpr)->pSchema; pSchema = (*pExpr)->pSchema;
strcpy(pSchema->name, TSQL_TBNAME_L); strcpy(pSchema->name, TSQL_TBNAME_L);
...@@ -9386,17 +9318,16 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -9386,17 +9318,16 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
*(*pExpr)->pSchema = *pSchema; *(*pExpr)->pSchema = *pSchema;
} }
if (pCols != NULL) { // record the involved columns if (pCols != NULL) { // record the involved columns
SColIndex colIndex = {0}; SColIndex colIndex = {0};
tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name)); tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
colIndex.colId = pSchema->colId; colIndex.colId = pSchema->colId;
colIndex.colIndex = index.columnIndex; colIndex.colIndex = index.columnIndex;
colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0; colIndex.flag = (index.columnIndex >= numOfColumns) ? 1 : 0;
taosArrayPush(pCols, &colIndex); taosArrayPush(pCols, &colIndex);
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} else if (pSqlExpr->tokenId == TK_SET) { } else if (pSqlExpr->tokenId == TK_SET) {
int32_t colType = -1; int32_t colType = -1;
...@@ -9430,21 +9361,44 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -9430,21 +9361,44 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
*pExpr = calloc(1, sizeof(tExprNode)); *pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_VALUE; (*pExpr)->nodeType = TSQL_NODE_VALUE;
(*pExpr)->pVal = pVal; (*pExpr)->pVal = pVal;
return TSDB_CODE_SUCCESS;
} else if (pSqlExpr->tokenId == 0) {
*pExpr = calloc(1, sizeof(tExprNode));
return TSDB_CODE_SUCCESS;
} else { } else {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression"); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression");
} }
}
} else {
if (pSqlExpr->type == SQL_NODE_EXPR) {
tExprNode* pLeft = NULL;
tExprNode* pRight= NULL;
if (pSqlExpr->pLeft != NULL) {
int32_t ret = exprTreeFromSqlExpr(pCmd, &pLeft, pSqlExpr->pLeft, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
}
if (pSqlExpr->pRight != NULL) {
int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(pLeft, NULL);
return ret;
}
}
*pExpr = (tExprNode *)calloc(1, sizeof(tExprNode)); *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_EXPR; (*pExpr)->nodeType = TSQL_NODE_EXPR;
(*pExpr)->_node.hasPK = false; (*pExpr)->_node.hasPK = false;
(*pExpr)->_node.pLeft = pLeft; (*pExpr)->_node.pLeft = pLeft;
(*pExpr)->_node.pRight = pRight; (*pExpr)->_node.pRight = pRight;
SStrToken t = {.type = pSqlExpr->tokenId}; SStrToken t = {.type = pSqlExpr->tokenId};
(*pExpr)->_node.optr = convertRelationalOperator(&t); (*pExpr)->_node.optr = convertRelationalOperator(&t);
assert((*pExpr)->_node.optr != 0); assert((*pExpr)->_node.optr != 0);
// check for dividing by 0 // check for dividing by 0
...@@ -9466,8 +9420,52 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS ...@@ -9466,8 +9420,52 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS
} }
} }
} }
} else if (pSqlExpr->type == SQL_NODE_SQLFUNCTION) {
if (TSDB_FUNC_IS_SCALAR(pSqlExpr->functionId)) {
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_FUNC;
(*pExpr)->_func.functionId = pSqlExpr->functionId;
SArray* paramList = pSqlExpr->Expr.paramList;
size_t paramSize = taosArrayGetSize(paramList);
if (paramSize > 0) {
(*pExpr)->_func.numChildren = paramSize;
(*pExpr)->_func.pChildren = (tExprNode**)calloc(paramSize, sizeof(tExprNode*));
}
for (int i = 0; i < taosArrayGetSize(paramList); ++i) {
tSqlExprItem* param = taosArrayGet(paramList, i);
tSqlExpr* paramNode = param->pNode;
int32_t ret = exprTreeFromSqlExpr(pCmd, (*pExpr)->_func.pChildren+i, paramNode, pQueryInfo, pCols, uid);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
}
} else {
// arithmetic expression on the results of aggregation functions
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TSQL_NODE_COL;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
strncpy((*pExpr)->pSchema->name, pSqlExpr->exprToken.z, pSqlExpr->exprToken.n);
// set the input column data byte and type.
size_t size = taosArrayGetSize(pQueryInfo->exprList);
for (int32_t i = 0; i < size; ++i) {
SExprInfo* p1 = taosArrayGetP(pQueryInfo->exprList, i);
if (strcmp((*pExpr)->pSchema->name, p1->base.aliasName) == 0) {
(*pExpr)->pSchema->type = (uint8_t)p1->base.resType;
(*pExpr)->pSchema->bytes = p1->base.resBytes;
(*pExpr)->pSchema->colId = p1->base.resColId;
if (uid != NULL) {
*uid = p1->base.uid;
}
break;
}
} // endfor each expr
} // end not scalar function
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
......
...@@ -80,8 +80,8 @@ typedef struct tExprNode { ...@@ -80,8 +80,8 @@ typedef struct tExprNode {
struct { struct {
int16_t functionId; int16_t functionId;
uint8_t numChilds; uint8_t numChildren;
struct tExprNode** pChilds; struct tExprNode** pChildren;
} _func; } _func;
}; };
} tExprNode; } tExprNode;
......
...@@ -144,8 +144,8 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { ...@@ -144,8 +144,8 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
} else if ((*pExpr)->nodeType == TSQL_NODE_COL) { } else if ((*pExpr)->nodeType == TSQL_NODE_COL) {
free((*pExpr)->pSchema); free((*pExpr)->pSchema);
} else if ((*pExpr)->nodeType == TSQL_NODE_FUNC) { } else if ((*pExpr)->nodeType == TSQL_NODE_FUNC) {
for (int i = 0; i < (*pExpr)->_func.numChilds; ++i) { for (int i = 0; i < (*pExpr)->_func.numChildren; ++i) {
doExprTreeDestroy((*pExpr)->_func.pChilds + i, fp); doExprTreeDestroy((*pExpr)->_func.pChildren + i, fp);
} }
} }
...@@ -315,9 +315,9 @@ static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) { ...@@ -315,9 +315,9 @@ static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) {
exprTreeToBinaryImpl(bw, expr->_node.pRight); exprTreeToBinaryImpl(bw, expr->_node.pRight);
} else if (expr->nodeType == TSQL_NODE_FUNC) { } else if (expr->nodeType == TSQL_NODE_FUNC) {
tbufWriteInt16(bw, expr->_func.functionId); tbufWriteInt16(bw, expr->_func.functionId);
tbufWriteUint8(bw, expr->_func.numChilds); tbufWriteUint8(bw, expr->_func.numChildren);
for (int i = 0; i < expr->_func.numChilds; ++i) { for (int i = 0; i < expr->_func.numChildren; ++i) {
exprTreeToBinaryImpl(bw, expr->_func.pChilds[i]); exprTreeToBinaryImpl(bw, expr->_func.pChildren[i]);
} }
} }
} }
...@@ -386,10 +386,10 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) { ...@@ -386,10 +386,10 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) {
assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL); assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL);
} else if (pExpr->nodeType == TSQL_NODE_FUNC) { } else if (pExpr->nodeType == TSQL_NODE_FUNC) {
pExpr->_func.functionId = tbufReadInt16(br); pExpr->_func.functionId = tbufReadInt16(br);
pExpr->_func.numChilds = tbufReadUint8(br); pExpr->_func.numChildren = tbufReadUint8(br);
pExpr->_func.pChilds = (tExprNode**)calloc(pExpr->_func.numChilds, sizeof(tExprNode*)); pExpr->_func.pChildren = (tExprNode**)calloc(pExpr->_func.numChildren, sizeof(tExprNode*));
for (int i = 0; i < pExpr->_func.numChilds; ++i) { for (int i = 0; i < pExpr->_func.numChildren; ++i) {
pExpr->_func.pChilds[i] = exprTreeFromBinaryImpl(br); pExpr->_func.pChildren[i] = exprTreeFromBinaryImpl(br);
} }
} }
...@@ -641,9 +641,9 @@ tExprNode* exprdup(tExprNode* pNode) { ...@@ -641,9 +641,9 @@ tExprNode* exprdup(tExprNode* pNode) {
*pCloned->pSchema = *pNode->pSchema; *pCloned->pSchema = *pNode->pSchema;
} else if (pNode->nodeType == TSQL_NODE_FUNC) { } else if (pNode->nodeType == TSQL_NODE_FUNC) {
pCloned->_func.functionId = pNode->_func.functionId; pCloned->_func.functionId = pNode->_func.functionId;
pCloned->_func.numChilds = pNode->_func.numChilds; pCloned->_func.numChildren = pNode->_func.numChildren;
for (int i = 0; i < pNode->_func.numChilds; ++i) { for (int i = 0; i < pNode->_func.numChildren; ++i) {
pCloned->_func.pChilds[i] = exprdup(pNode->_func.pChilds[i]); pCloned->_func.pChildren[i] = exprdup(pNode->_func.pChildren[i]);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册