[td-225] fix bug in aggregation function in arithmetic expression.
This commit is contained in:
parent
f86022f6c1
commit
6fd03c905d
|
@ -68,7 +68,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
|
||||||
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i);
|
SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||||
|
|
||||||
pCtx->aOutputBuf =
|
pCtx->aOutputBuf =
|
||||||
pReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pReducer->resColModel->capacity;
|
pReducer->pResultBuf->data + pExpr->offset * pReducer->resColModel->capacity;
|
||||||
pCtx->order = pQueryInfo->order.order;
|
pCtx->order = pQueryInfo->order.order;
|
||||||
pCtx->functionId = pExpr->functionId;
|
pCtx->functionId = pExpr->functionId;
|
||||||
|
|
||||||
|
@ -321,6 +321,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList);
|
pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList);
|
||||||
pReducer->resColModel = finalmodel;
|
pReducer->resColModel = finalmodel;
|
||||||
pReducer->resColModel->capacity = pReducer->nResultBufSize;
|
pReducer->resColModel->capacity = pReducer->nResultBufSize;
|
||||||
|
|
||||||
assert(pReducer->finalRowSize > 0);
|
assert(pReducer->finalRowSize > 0);
|
||||||
if (pReducer->finalRowSize > 0) {
|
if (pReducer->finalRowSize > 0) {
|
||||||
pReducer->resColModel->capacity /= pReducer->finalRowSize;
|
pReducer->resColModel->capacity /= pReducer->finalRowSize;
|
||||||
|
@ -328,10 +329,9 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
assert(pReducer->finalRowSize <= pReducer->rowSize);
|
assert(pReducer->finalRowSize <= pReducer->rowSize);
|
||||||
|
|
||||||
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
|
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
|
||||||
// pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize);
|
|
||||||
|
|
||||||
if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
||||||
/*pReducer->pBufForInterpo == NULL || */pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||||
tfree(pReducer->pTempBuffer);
|
tfree(pReducer->pTempBuffer);
|
||||||
tfree(pReducer->discardData);
|
tfree(pReducer->discardData);
|
||||||
tfree(pReducer->pResultBuf);
|
tfree(pReducer->pResultBuf);
|
||||||
|
|
|
@ -87,7 +87,7 @@ static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQueryS
|
||||||
static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||||
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
|
static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
|
||||||
static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
static int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||||
static int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString);
|
static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** exprString);
|
||||||
static int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
static int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||||
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
|
static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
|
||||||
static int32_t validateEp(char* ep);
|
static int32_t validateEp(char* ep);
|
||||||
|
@ -1107,13 +1107,128 @@ static void extractColumnNameFromString(tSQLExprItem* pItem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
|
||||||
|
const char* msg1 = "invalid column name, or illegal column type";
|
||||||
|
const char* msg2 = "invalid arithmetic expression in select clause";
|
||||||
|
const char* msg3 = "tag columns can not be used in arithmetic expression";
|
||||||
|
const char* msg4 = "columns from different table mixed up in arithmetic expression";
|
||||||
|
|
||||||
|
// arithmetic function in select clause
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||||
|
|
||||||
|
SColumnList columnList = {0};
|
||||||
|
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
||||||
|
|
||||||
|
if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tableIndex = columnList.ids[0].tableIndex;
|
||||||
|
|
||||||
|
// todo potential data overflow
|
||||||
|
char arithmeticExprStr[1024*12];
|
||||||
|
char* p = arithmeticExprStr;
|
||||||
|
|
||||||
|
if (arithmeticType == NORMAL_ARITHMETIC) {
|
||||||
|
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
||||||
|
|
||||||
|
// all columns in arithmetic expression must belong to the same table
|
||||||
|
for (int32_t f = 1; f < columnList.num; ++f) {
|
||||||
|
if (columnList.ids[f].tableIndex != tableIndex) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// expr string is set as the parameter of function
|
||||||
|
SColumnIndex index = {.tableIndex = tableIndex};
|
||||||
|
|
||||||
|
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double),
|
||||||
|
sizeof(double), false);
|
||||||
|
|
||||||
|
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
|
||||||
|
tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
|
||||||
|
|
||||||
|
tExprNode* pNode = NULL;
|
||||||
|
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||||
|
|
||||||
|
int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
tExprTreeDestroy(&pNode, NULL);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t numOfNode = taosArrayGetSize(colList);
|
||||||
|
for(int32_t k = 0; k < numOfNode; ++k) {
|
||||||
|
SColIndex* pIndex = taosArrayGet(colList, k);
|
||||||
|
if (pIndex->flag == 1) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SBufferWriter bw = tbufInitWriter(NULL, false);
|
||||||
|
|
||||||
|
TRY(0) {
|
||||||
|
exprTreeToBinary(&bw, pNode);
|
||||||
|
} CATCH(code) {
|
||||||
|
tbufCloseWriter(&bw);
|
||||||
|
UNUSED(code);
|
||||||
|
// TODO: other error handling
|
||||||
|
} END_TRY
|
||||||
|
|
||||||
|
size_t len = tbufTell(&bw);
|
||||||
|
char* c = tbufGetData(&bw, true);
|
||||||
|
|
||||||
|
// set the serialized binary string as the parameter of arithmetic expression
|
||||||
|
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, len, index.tableIndex);
|
||||||
|
|
||||||
|
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
|
||||||
|
|
||||||
|
taosArrayDestroy(colList);
|
||||||
|
tExprTreeDestroy(&pNode, NULL);
|
||||||
|
} else {
|
||||||
|
if (arithmeticExprToString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
}
|
||||||
|
|
||||||
|
columnList.num = 0;
|
||||||
|
columnList.ids[0] = (SColumnIndex) {0, 0};
|
||||||
|
|
||||||
|
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
|
||||||
|
insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, name, NULL);
|
||||||
|
|
||||||
|
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
|
||||||
|
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
|
||||||
|
|
||||||
|
if (pInfo->pSqlExpr == NULL) {
|
||||||
|
SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
|
||||||
|
|
||||||
|
// arithmetic expression always return result in the format of double float
|
||||||
|
pArithExprInfo->bytes = sizeof(double);
|
||||||
|
pArithExprInfo->interBytes = sizeof(double);
|
||||||
|
pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
|
|
||||||
|
int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pArithExprInfo = pArithExprInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) {
|
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) {
|
||||||
assert(pSelection != NULL && pCmd != NULL);
|
assert(pSelection != NULL && pCmd != NULL);
|
||||||
|
|
||||||
const char* msg1 = "invalid column name, or illegal column type";
|
|
||||||
const char* msg2 = "functions can not be mixed up";
|
const char* msg2 = "functions can not be mixed up";
|
||||||
const char* msg3 = "not support query expression";
|
const char* msg3 = "not support query expression";
|
||||||
const char* msg4 = "columns from different table mixed up in arithmetic expression";
|
|
||||||
const char* msg5 = "invalid function name";
|
const char* msg5 = "invalid function name";
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
|
||||||
|
@ -1148,104 +1263,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
|
} else if (pItem->pNode->nSQLOptr >= TK_PLUS && pItem->pNode->nSQLOptr <= TK_REM) {
|
||||||
// arithmetic function in select clause
|
int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
|
||||||
SColumnList columnList = {0};
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
return code;
|
||||||
|
|
||||||
if (validateArithmeticSQLExpr(pCmd, pItem->pNode, pQueryInfo, &columnList, &arithmeticType) != TSDB_CODE_SUCCESS) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tableIndex = columnList.ids[0].tableIndex;
|
|
||||||
char arithmeticExprStr[1024] = {0};
|
|
||||||
char* p = arithmeticExprStr;
|
|
||||||
|
|
||||||
if (arithmeticType == NORMAL_ARITHMETIC) {
|
|
||||||
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
|
||||||
|
|
||||||
// all columns in arithmetic expression must belong to the same table
|
|
||||||
for (int32_t f = 1; f < columnList.num; ++f) {
|
|
||||||
if (columnList.ids[f].tableIndex != tableIndex) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buildArithmeticExprString(pItem->pNode, &p) != TSDB_CODE_SUCCESS) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// expr string is set as the parameter of function
|
|
||||||
SColumnIndex index = {.tableIndex = tableIndex};
|
|
||||||
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE,
|
|
||||||
sizeof(double), sizeof(double), false);
|
|
||||||
|
|
||||||
/* todo alias name should use the original sql string */
|
|
||||||
char* name = (pItem->aliasName != NULL)? pItem->aliasName:arithmeticExprStr;
|
|
||||||
tstrncpy(pExpr->aliasName, name, sizeof(pExpr->aliasName));
|
|
||||||
|
|
||||||
tExprNode* pNode = NULL;
|
|
||||||
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
|
||||||
|
|
||||||
int32_t ret = exprTreeFromSqlExpr(pCmd, &pNode, pItem->pNode, pQueryInfo->exprList, pQueryInfo, colList);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
tExprTreeDestroy(&pNode, NULL);
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid arithmetic expression in select clause");
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t numOfNode = taosArrayGetSize(colList);
|
|
||||||
for(int32_t k = 0; k < numOfNode; ++k) {
|
|
||||||
SColIndex* pIndex = taosArrayGet(colList, k);
|
|
||||||
if (pIndex->flag == 1) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "tag columns can not be used in arithmetic expression");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SBufferWriter bw = tbufInitWriter(NULL, false);
|
|
||||||
|
|
||||||
TRY(0) {
|
|
||||||
exprTreeToBinary(&bw, pNode);
|
|
||||||
} CATCH(code) {
|
|
||||||
tbufCloseWriter(&bw);
|
|
||||||
UNUSED(code);
|
|
||||||
// TODO: other error handling
|
|
||||||
} END_TRY
|
|
||||||
|
|
||||||
size_t len = tbufTell(&bw);
|
|
||||||
char* c = tbufGetData(&bw, true);
|
|
||||||
|
|
||||||
// set the serialized binary string as the parameter of arithmetic expression
|
|
||||||
addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, len, index.tableIndex);
|
|
||||||
|
|
||||||
insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr);
|
|
||||||
|
|
||||||
taosArrayDestroy(colList);
|
|
||||||
tExprTreeDestroy(&pNode, NULL);
|
|
||||||
} else {
|
|
||||||
columnList.num = 0;
|
|
||||||
columnList.ids[0] = (SColumnIndex) {0, 0};
|
|
||||||
|
|
||||||
insertResultField(pQueryInfo, i, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, "dummy_column", NULL);
|
|
||||||
|
|
||||||
int32_t slot = tscNumOfFields(pQueryInfo) - 1;
|
|
||||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, slot);
|
|
||||||
|
|
||||||
if (pInfo->pSqlExpr == NULL) {
|
|
||||||
SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo));
|
|
||||||
|
|
||||||
// arithmetic expression always return result in the format of double float
|
|
||||||
pArithExprInfo->bytes = sizeof(double);
|
|
||||||
pArithExprInfo->interBytes = sizeof(double);
|
|
||||||
pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
|
||||||
|
|
||||||
int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo->exprList, pQueryInfo, NULL);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
tExprTreeDestroy(&pArithExprInfo->pExpr, NULL);
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause");
|
|
||||||
}
|
|
||||||
|
|
||||||
pInfo->pArithExprInfo = pArithExprInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* not support such expression
|
* not support such expression
|
||||||
|
@ -3090,14 +3112,14 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExpr*
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo error handle / such as and /or mixed with +/-/*/
|
// todo error handle / such as and /or mixed with +/-/*/
|
||||||
int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
int32_t doArithmeticExprToString(tSQLExpr* pExpr, char** exprString) {
|
||||||
tSQLExpr* pLeft = pExpr->pLeft;
|
tSQLExpr* pLeft = pExpr->pLeft;
|
||||||
tSQLExpr* pRight = pExpr->pRight;
|
tSQLExpr* pRight = pExpr->pRight;
|
||||||
|
|
||||||
*(*exprString)++ = '(';
|
*(*exprString)++ = '(';
|
||||||
|
|
||||||
if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
|
if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
|
||||||
buildArithmeticExprString(pLeft, exprString);
|
doArithmeticExprToString(pLeft, exprString);
|
||||||
} else {
|
} else {
|
||||||
int32_t ret = tSQLExprNodeToString(pLeft, exprString);
|
int32_t ret = tSQLExprNodeToString(pLeft, exprString);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -3108,7 +3130,7 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
||||||
optrToString(pExpr, exprString);
|
optrToString(pExpr, exprString);
|
||||||
|
|
||||||
if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
|
if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
|
||||||
buildArithmeticExprString(pRight, exprString);
|
doArithmeticExprToString(pRight, exprString);
|
||||||
} else {
|
} else {
|
||||||
int32_t ret = tSQLExprNodeToString(pRight, exprString);
|
int32_t ret = tSQLExprNodeToString(pRight, exprString);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -3121,6 +3143,19 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t arithmeticExprToString(tSQLExpr* pExpr, char** str) {
|
||||||
|
char* start = *str;
|
||||||
|
|
||||||
|
int32_t code = doArithmeticExprToString(pExpr, str);
|
||||||
|
if (code == TSDB_CODE_SUCCESS) { // remove out the parenthesis
|
||||||
|
int32_t len = strlen(start);
|
||||||
|
memmove(start, start + 1, len - 2);
|
||||||
|
start[len - 2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
|
static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
|
||||||
if (pExpr->nSQLOptr == TK_ID) {
|
if (pExpr->nSQLOptr == TK_ID) {
|
||||||
if (*type == NON_ARITHMEIC_EXPR) {
|
if (*type == NON_ARITHMEIC_EXPR) {
|
||||||
|
|
|
@ -1461,7 +1461,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
|
|
||||||
if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) {
|
if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) {
|
||||||
tscSetResultPointer(pQueryInfo, pRes);
|
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
pRes->row = 0;
|
pRes->row = 0;
|
||||||
|
@ -2115,21 +2115,6 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessRetrieveRspFromLocal(SSqlObj *pSql) {
|
|
||||||
SSqlRes * pRes = &pSql->res;
|
|
||||||
SSqlCmd * pCmd = &pSql->cmd;
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
|
||||||
|
|
||||||
SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp;
|
|
||||||
|
|
||||||
pRes->numOfRows = htonl(pRetrieve->numOfRows);
|
|
||||||
pRes->data = pRetrieve->data;
|
|
||||||
|
|
||||||
tscSetResultPointer(pQueryInfo, pRes);
|
|
||||||
pRes->row = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code);
|
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code);
|
||||||
|
|
||||||
static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||||
|
|
|
@ -249,7 +249,10 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
||||||
if (pRes->tsrow == NULL) {
|
if (pRes->tsrow != NULL) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput;
|
int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput;
|
||||||
pRes->numOfCols = numOfOutput;
|
pRes->numOfCols = numOfOutput;
|
||||||
|
|
||||||
|
@ -266,7 +269,6 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -858,12 +860,13 @@ void tscFieldInfoCopy(SFieldInfo* dst, const SFieldInfo* src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) {
|
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) {
|
||||||
|
assert(index < pFieldInfo->numOfOutput);
|
||||||
return TARRAY_GET_ELEM(pFieldInfo->pFields, index);
|
return TARRAY_GET_ELEM(pFieldInfo->pFields, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
|
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
|
||||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, index);
|
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, index);
|
||||||
assert(pInfo != NULL);
|
assert(pInfo != NULL && pInfo->pSqlExpr != NULL);
|
||||||
|
|
||||||
return pInfo->pSqlExpr->offset;
|
return pInfo->pSqlExpr->offset;
|
||||||
}
|
}
|
||||||
|
@ -1773,11 +1776,36 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||||
|
|
||||||
if (pExpr->uid == uid) {
|
if (pExpr->uid == uid) {
|
||||||
TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i);
|
if (i < pFieldInfo->numOfOutput) {
|
||||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i);
|
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i);
|
||||||
|
if (pInfo->pSqlExpr != NULL) {
|
||||||
|
TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i);
|
||||||
|
assert(strcmp(p->name, pExpr->aliasName) == 0 && pInfo->pSqlExpr == pExpr);
|
||||||
|
|
||||||
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p);
|
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p);
|
||||||
*pInfo1 = *pInfo;
|
*pInfo1 = *pInfo;
|
||||||
|
} else {
|
||||||
|
// current sql function is not direct output result, so create a dummy output field
|
||||||
|
assert(pInfo->pArithExprInfo != NULL);
|
||||||
|
|
||||||
|
TAOS_FIELD f = {.type = pExpr->resType, .bytes = pExpr->resBytes};
|
||||||
|
tstrncpy(f.name, pExpr->aliasName, sizeof(f.name));
|
||||||
|
|
||||||
|
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f);
|
||||||
|
|
||||||
|
pInfo1->pSqlExpr = pExpr;
|
||||||
|
pInfo1->visible = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// current sql function is not direct output result, so create a dummy output field
|
||||||
|
TAOS_FIELD f = {.type = pExpr->resType, .bytes = pExpr->resBytes};
|
||||||
|
tstrncpy(f.name, pExpr->aliasName, sizeof(f.name));
|
||||||
|
|
||||||
|
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f);
|
||||||
|
|
||||||
|
pInfo1->pSqlExpr = pExpr;
|
||||||
|
pInfo1->visible = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue