[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);
|
||||
|
||||
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->functionId = pExpr->functionId;
|
||||
|
||||
|
@ -321,6 +321,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList);
|
||||
pReducer->resColModel = finalmodel;
|
||||
pReducer->resColModel->capacity = pReducer->nResultBufSize;
|
||||
|
||||
assert(pReducer->finalRowSize > 0);
|
||||
if (pReducer->finalRowSize > 0) {
|
||||
pReducer->resColModel->capacity /= pReducer->finalRowSize;
|
||||
|
@ -328,10 +329,9 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
assert(pReducer->finalRowSize <= pReducer->rowSize);
|
||||
|
||||
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 ||
|
||||
/*pReducer->pBufForInterpo == NULL || */pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
tfree(pReducer->pTempBuffer);
|
||||
tfree(pReducer->discardData);
|
||||
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 setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
|
||||
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 validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type);
|
||||
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) {
|
||||
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* msg3 = "not support query expression";
|
||||
const char* msg4 = "columns from different table mixed up in arithmetic expression";
|
||||
const char* msg5 = "invalid function name";
|
||||
|
||||
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) {
|
||||
// arithmetic function in select clause
|
||||
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 code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
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 {
|
||||
/*
|
||||
* 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 +/-/*/
|
||||
int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
||||
int32_t doArithmeticExprToString(tSQLExpr* pExpr, char** exprString) {
|
||||
tSQLExpr* pLeft = pExpr->pLeft;
|
||||
tSQLExpr* pRight = pExpr->pRight;
|
||||
|
||||
*(*exprString)++ = '(';
|
||||
|
||||
if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
|
||||
buildArithmeticExprString(pLeft, exprString);
|
||||
doArithmeticExprToString(pLeft, exprString);
|
||||
} else {
|
||||
int32_t ret = tSQLExprNodeToString(pLeft, exprString);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3108,7 +3130,7 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
|||
optrToString(pExpr, exprString);
|
||||
|
||||
if (pRight->nSQLOptr >= TK_PLUS && pRight->nSQLOptr <= TK_REM) {
|
||||
buildArithmeticExprString(pRight, exprString);
|
||||
doArithmeticExprToString(pRight, exprString);
|
||||
} else {
|
||||
int32_t ret = tSQLExprNodeToString(pRight, exprString);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3121,6 +3143,19 @@ int32_t buildArithmeticExprString(tSQLExpr* pExpr, char** exprString) {
|
|||
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) {
|
||||
if (pExpr->nSQLOptr == TK_ID) {
|
||||
if (*type == NON_ARITHMEIC_EXPR) {
|
||||
|
|
|
@ -1461,7 +1461,7 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
|
||||
if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) {
|
||||
tscSetResultPointer(pQueryInfo, pRes);
|
||||
tscCreateResPointerInfo(pRes, pQueryInfo);
|
||||
}
|
||||
|
||||
pRes->row = 0;
|
||||
|
@ -2115,21 +2115,6 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
|
|||
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);
|
||||
|
||||
static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||
|
|
|
@ -249,23 +249,25 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) {
|
|||
}
|
||||
|
||||
int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
|
||||
if (pRes->tsrow == NULL) {
|
||||
int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput;
|
||||
pRes->numOfCols = numOfOutput;
|
||||
|
||||
pRes->tsrow = calloc(numOfOutput, POINTER_BYTES);
|
||||
pRes->length = calloc(numOfOutput, sizeof(int32_t)); // todo refactor
|
||||
pRes->buffer = calloc(numOfOutput, POINTER_BYTES);
|
||||
|
||||
// not enough memory
|
||||
if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) {
|
||||
tfree(pRes->tsrow);
|
||||
tfree(pRes->buffer);
|
||||
tfree(pRes->length);
|
||||
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRes->code;
|
||||
}
|
||||
if (pRes->tsrow != NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput;
|
||||
pRes->numOfCols = numOfOutput;
|
||||
|
||||
pRes->tsrow = calloc(numOfOutput, POINTER_BYTES);
|
||||
pRes->length = calloc(numOfOutput, sizeof(int32_t)); // todo refactor
|
||||
pRes->buffer = calloc(numOfOutput, POINTER_BYTES);
|
||||
|
||||
// not enough memory
|
||||
if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) {
|
||||
tfree(pRes->tsrow);
|
||||
tfree(pRes->buffer);
|
||||
tfree(pRes->length);
|
||||
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -858,12 +860,13 @@ void tscFieldInfoCopy(SFieldInfo* dst, const SFieldInfo* src) {
|
|||
}
|
||||
|
||||
TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) {
|
||||
assert(index < pFieldInfo->numOfOutput);
|
||||
return TARRAY_GET_ELEM(pFieldInfo->pFields, index);
|
||||
}
|
||||
|
||||
int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) {
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, index);
|
||||
assert(pInfo != NULL);
|
||||
assert(pInfo != NULL && pInfo->pSqlExpr != NULL);
|
||||
|
||||
return pInfo->pSqlExpr->offset;
|
||||
}
|
||||
|
@ -1773,11 +1776,36 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
if (pExpr->uid == uid) {
|
||||
TAOS_FIELD* p = tscFieldInfoGetField(pFieldInfo, i);
|
||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(pFieldInfo, i);
|
||||
|
||||
SFieldSupInfo* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, p);
|
||||
*pInfo1 = *pInfo;
|
||||
if (i < pFieldInfo->numOfOutput) {
|
||||
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);
|
||||
*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