提交 7d34d0a4 编写于 作者: S shenglian zhou

separate scalar function with aggregate function

上级 9ee2e032
...@@ -1740,124 +1740,123 @@ void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t tableUid) { ...@@ -1740,124 +1740,123 @@ void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t tableUid) {
tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s); tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s);
} }
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem) { static int32_t handleScalarExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem,
const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables"; SColumnList* columnList, bool finalResult) {
const char* msg2 = "invalid arithmetic expression in select clause"; const char* msg2 = "invalid arithmetic expression in select clause";
const char* msg3 = "tag columns can not be used in arithmetic expression"; const char* msg3 = "tag columns can not be used in arithmetic expression";
const char* msg4 = "columns from different table mixed up in arithmetic expression"; const char* msg4 = "columns from different table mixed up in arithmetic expression";
SColumnList columnList = {0}; int32_t tableIndex = columnList->ids[0].tableIndex;
int32_t arithmeticType = NON_ARITHMEIC_EXPR; pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
uint64_t uid; // all columns in arithmetic expression must belong to the same table
if (validateSQLExprTerm(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType, &uid) != TSDB_CODE_SUCCESS) { for (int32_t f = 1; f < columnList->num; ++f) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); if (columnList->ids[f].tableIndex != tableIndex) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
} }
int32_t tableIndex = columnList.ids[0].tableIndex; // expr string is set as the parameter of function
if (arithmeticType == NORMAL_ARITHMETIC) { SColumnIndex index = {.tableIndex = tableIndex};
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
// all columns in arithmetic expression must belong to the same table SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double),
for (int32_t f = 1; f < columnList.num; ++f) { getNewResColId(pCmd), sizeof(double), false);
if (columnList.ids[f].tableIndex != tableIndex) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
}
// expr string is set as the parameter of function
SColumnIndex index = {.tableIndex = tableIndex};
SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double), char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->exprToken.z;
getNewResColId(pCmd), sizeof(double), false); size_t len = MIN(sizeof(pExpr->base.aliasName), pItem->pNode->exprToken.n + 1);
tstrncpy(pExpr->base.aliasName, name, len);
char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->exprToken.z; tExprNode* pNode = NULL;
size_t len = MIN(sizeof(pExpr->base.aliasName), pItem->pNode->exprToken.n + 1); SArray* colList = taosArrayInit(10, sizeof(SColIndex));
tstrncpy(pExpr->base.aliasName, name, len);
tExprNode* pNode = NULL; int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo, colList, NULL);
SArray* colList = taosArrayInit(10, sizeof(SColIndex)); if (ret != TSDB_CODE_SUCCESS) {
taosArrayDestroy(colList);
tExprTreeDestroy(pNode, NULL);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo, colList, NULL); // check for if there is a tag in the arithmetic express
if (ret != TSDB_CODE_SUCCESS) { size_t numOfNode = taosArrayGetSize(colList);
taosArrayDestroy(colList); for(int32_t k = 0; k < numOfNode; ++k) {
SColIndex* pIndex = taosArrayGet(colList, k);
if (TSDB_COL_IS_TAG(pIndex->flag)) {
tExprTreeDestroy(pNode, NULL); tExprTreeDestroy(pNode, NULL);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); taosArrayDestroy(colList);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
} }
}
// check for if there is a tag in the arithmetic express SBufferWriter bw = tbufInitWriter(NULL, false);
size_t numOfNode = taosArrayGetSize(colList);
for(int32_t k = 0; k < numOfNode; ++k) {
SColIndex* pIndex = taosArrayGet(colList, k);
if (TSDB_COL_IS_TAG(pIndex->flag)) {
tExprTreeDestroy(pNode, NULL);
taosArrayDestroy(colList);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); TRY(0) {
} exprTreeToBinary(&bw, pNode);
} } CATCH(code) {
tbufCloseWriter(&bw);
UNUSED(code);
// TODO: other error handling
} END_TRY
SBufferWriter bw = tbufInitWriter(NULL, false); len = tbufTell(&bw);
char* c = tbufGetData(&bw, false);
TRY(0) { // set the serialized binary string as the parameter of arithmetic expression
exprTreeToBinary(&bw, pNode); tscExprAddParams(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len);
} CATCH(code) { if (finalResult) {
tbufCloseWriter(&bw); insertResultField(pQueryInfo, exprIndex, columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->base.aliasName,
UNUSED(code); pExpr);
// TODO: other error handling }
} END_TRY
len = tbufTell(&bw); // add ts column
char* c = tbufGetData(&bw, false); tscInsertPrimaryTsSourceColumn(pQueryInfo, pExpr->base.uid);
// set the serialized binary string as the parameter of arithmetic expression tbufCloseWriter(&bw);
tscExprAddParams(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len); taosArrayDestroy(colList);
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->base.aliasName, pExpr); tExprTreeDestroy(pNode, NULL);
// add ts column return TSDB_CODE_SUCCESS;
tscInsertPrimaryTsSourceColumn(pQueryInfo, pExpr->base.uid); }
tbufCloseWriter(&bw); static int32_t handleAggregateExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem,
taosArrayDestroy(colList); SColumnList* columnList, bool finalResult) {
tExprTreeDestroy(pNode, NULL); columnList->num = 0;
} else { columnList->ids[0] = (SColumnIndex) {0, 0};
columnList.num = 0;
columnList.ids[0] = (SColumnIndex) {0, 0};
char rawName[TSDB_COL_NAME_LEN] = {0}; char rawName[TSDB_COL_NAME_LEN] = {0};
char aliasName[TSDB_COL_NAME_LEN] = {0}; char aliasName[TSDB_COL_NAME_LEN] = {0};
getColumnName(pItem, aliasName, rawName, TSDB_COL_NAME_LEN); getColumnName(pItem, aliasName, rawName, TSDB_COL_NAME_LEN);
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL); insertResultField(pQueryInfo, exprIndex, columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, aliasName, NULL);
int32_t slot = tscNumOfFields(pQueryInfo) - 1; int32_t slot = tscNumOfFields(pQueryInfo) - 1;
SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot); SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot);
assert(pInfo->pExpr == NULL); assert(pInfo->pExpr == NULL);
SExprInfo* pExprInfo = calloc(1, sizeof(SExprInfo)); SExprInfo* pExprInfo = calloc(1, sizeof(SExprInfo));
// arithmetic expression always return result in the format of double float // arithmetic expression always return result in the format of double float
pExprInfo->base.resBytes = sizeof(double); pExprInfo->base.resBytes = sizeof(double);
pExprInfo->base.interBytes = 0; pExprInfo->base.interBytes = 0;
pExprInfo->base.resType = TSDB_DATA_TYPE_DOUBLE; pExprInfo->base.resType = TSDB_DATA_TYPE_DOUBLE;
pExprInfo->base.functionId = TSDB_FUNC_ARITHM; pExprInfo->base.functionId = TSDB_FUNC_ARITHM;
pExprInfo->base.numOfParams = 1; pExprInfo->base.numOfParams = 1;
pExprInfo->base.resColId = getNewResColId(pCmd); pExprInfo->base.resColId = getNewResColId(pCmd);
strncpy(pExprInfo->base.aliasName, aliasName, tListLen(pExprInfo->base.aliasName)); strncpy(pExprInfo->base.aliasName, aliasName, tListLen(pExprInfo->base.aliasName));
strncpy(pExprInfo->base.token, rawName, tListLen(pExprInfo->base.token)); strncpy(pExprInfo->base.token, rawName, tListLen(pExprInfo->base.token));
int32_t ret = exprTreeFromSqlExpr(pCmd, &pExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExprInfo->base.uid)); int32_t ret = exprTreeFromSqlExpr(pCmd, &pExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExprInfo->base.uid));
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(pExprInfo->pExpr, NULL); tExprTreeDestroy(pExprInfo->pExpr, NULL);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause"); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
} }
pInfo->pExpr = pExprInfo; pInfo->pExpr = pExprInfo;
SBufferWriter bw = tbufInitWriter(NULL, false); SBufferWriter bw = tbufInitWriter(NULL, false);
TRY(0) { TRY(0) {
exprTreeToBinary(&bw, pInfo->pExpr->pExpr); exprTreeToBinary(&bw, pInfo->pExpr->pExpr);
} CATCH(code) { } CATCH(code) {
tbufCloseWriter(&bw); tbufCloseWriter(&bw);
...@@ -1865,12 +1864,31 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32 ...@@ -1865,12 +1864,31 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32
// TODO: other error handling // TODO: other error handling
} END_TRY } END_TRY
SSqlExpr* pSqlExpr = &pInfo->pExpr->base; SSqlExpr* pSqlExpr = &pInfo->pExpr->base;
pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw); pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw);
pSqlExpr->param[0].pz = tbufGetData(&bw, true); pSqlExpr->param[0].pz = tbufGetData(&bw, true);
pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY; pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY;
// tbufCloseWriter(&bw); // TODO there is a memory leak // tbufCloseWriter(&bw); // TODO there is a memory leak
return TSDB_CODE_SUCCESS;
}
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem) {
const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
SColumnList columnList = {0};
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
uint64_t uid;
if (validateSQLExprTerm(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType, &uid) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
if (arithmeticType == NORMAL_ARITHMETIC) {
handleScalarExpr(pCmd, pQueryInfo, exprIndex, pItem, &columnList, true);
} else {
handleAggregateExpr(pCmd, pQueryInfo, exprIndex, pItem, &columnList, true);
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
...@@ -4321,6 +4339,7 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* ...@@ -4321,6 +4339,7 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
static int32_t validateArithmeticSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr, static int32_t validateArithmeticSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr,
SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type, uint64_t *uid) { SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type, uint64_t *uid) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t functionId = isValidFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n); int32_t functionId = isValidFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n);
if (functionId < 0) { if (functionId < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
...@@ -4335,20 +4354,31 @@ static int32_t validateArithmeticSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr, ...@@ -4335,20 +4354,31 @@ static int32_t validateArithmeticSQLFunc(SSqlCmd* pCmd, tSqlExpr* pExpr,
if (!TSDB_FUNC_IS_SCALAR(functionId)) { if (!TSDB_FUNC_IS_SCALAR(functionId)) {
*type = AGG_ARIGHTMEIC; *type = AGG_ARIGHTMEIC;
} }
} else {
if (!TSDB_FUNC_IS_SCALAR(functionId)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} }
pExpr->functionId = functionId; pExpr->functionId = functionId;
size_t numChilds = taosArrayGetSize(pExpr->Expr.paramList); size_t numChilds = taosArrayGetSize(pExpr->Expr.paramList);
for (int i = 0; i < numChilds; ++i) { for (int i = 0; i < numChilds; ++i) {
tSqlExprItem* pParamElem= taosArrayGet(pExpr->Expr.paramList, i); tSqlExprItem* pParamElem= taosArrayGet(pExpr->Expr.paramList, i);
validateSQLExprTerm(pCmd, pParamElem->pNode, pQueryInfo, pList, type, uid); if (!TSDB_FUNC_IS_SCALAR(functionId) &&
(pParamElem->pNode->type == SQL_NODE_EXPR || pParamElem->pNode->type == SQL_NODE_SQLFUNCTION)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
code = validateSQLExprTerm(pCmd, pParamElem->pNode, pQueryInfo, pList, type, uid);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
} }
if (*type == AGG_ARIGHTMEIC) { if (!TSDB_FUNC_IS_SCALAR(functionId)) {
for (int i = 0; i < numChilds; ++i) {
tSqlExprItem* pParamElem = taosArrayGet(pExpr->Expr.paramList, i);
if (pParamElem->pNode->type == SQL_NODE_EXPR || pParamElem->pNode->type == SQL_NODE_SQLFUNCTION) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo); int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
tSqlExprItem item = {.pNode = pExpr, .aliasName = NULL}; tSqlExprItem item = {.pNode = pExpr, .aliasName = NULL};
...@@ -4406,6 +4436,9 @@ static int32_t validateSQLExprTerm(SSqlCmd* pCmd, tSqlExpr* pExpr, ...@@ -4406,6 +4436,9 @@ static int32_t validateSQLExprTerm(SSqlCmd* pCmd, tSqlExpr* pExpr,
} }
if (pExpr->type == SQL_NODE_EXPR) { if (pExpr->type == SQL_NODE_EXPR) {
if (*type == NON_ARITHMEIC_EXPR) {
*type = NORMAL_ARITHMETIC;
}
uint64_t uidLeft = 0; uint64_t uidLeft = 0;
uint64_t uidRight = 0; uint64_t uidRight = 0;
int32_t ret = validateSQLExprTerm(pCmd, pExpr->pLeft, pQueryInfo, pList, type, &uidLeft); int32_t ret = validateSQLExprTerm(pCmd, pExpr->pLeft, pQueryInfo, pList, type, &uidLeft);
...@@ -4423,7 +4456,10 @@ static int32_t validateSQLExprTerm(SSqlCmd* pCmd, tSqlExpr* pExpr, ...@@ -4423,7 +4456,10 @@ static int32_t validateSQLExprTerm(SSqlCmd* pCmd, tSqlExpr* pExpr,
*uid = uidLeft; *uid = uidLeft;
} else if (pExpr->type == SQL_NODE_SQLFUNCTION) { } else if (pExpr->type == SQL_NODE_SQLFUNCTION) {
validateArithmeticSQLFunc(pCmd, pExpr, pQueryInfo, pList, type, uid); int32_t ret = validateArithmeticSQLFunc(pCmd, pExpr, pQueryInfo, pList, type, uid);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
} else if (pExpr->type == SQL_NODE_TABLE_COLUMN) { } else if (pExpr->type == SQL_NODE_TABLE_COLUMN) {
SColumnIndex index = COLUMN_INDEX_INITIALIZER; SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) !=
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册