提交 55f3ac17 编写于 作者: H Haojun Liao

[td-10564] refactor and add test cases.

上级 89e324c8
......@@ -68,6 +68,13 @@ typedef struct SColumnInfoData {
//======================================================================================================================
// the following structure shared by parser and executor
typedef struct SColumn {
uint64_t uid;
char name[TSDB_COL_NAME_LEN];
int8_t flag; // column type: normal column, tag, or user-input column (integer/float/string)
SColumnInfo info;
} SColumn;
typedef struct SLimit {
int64_t limit;
int64_t offset;
......@@ -89,8 +96,9 @@ typedef struct SGroupbyExpr {
typedef struct SSqlExpr {
char token[TSDB_COL_NAME_LEN]; // original token
SSchema resSchema;
SColIndex colInfo; // there may be mutiple input columns
uint64_t uid; // table uid, todo refactor use the pointer
int32_t numOfCols;
SColumn* pColumns; // data columns that are required by query
int32_t interBytes; // inter result buffer size
int16_t numOfParams; // argument value of each function
SVariant param[3]; // parameters are not more than 3
......
......@@ -161,6 +161,7 @@ enum {
TEXPR_NODE_DUMMY = 0x0,
TEXPR_BINARYEXPR_NODE= 0x1,
TEXPR_UNARYEXPR_NODE = 0x2,
TEXPR_FUNCTION_NODE = 0x3,
TEXPR_COL_NODE = 0x4,
TEXPR_VALUE_NODE = 0x8,
};
......@@ -169,10 +170,7 @@ typedef struct tExprNode {
uint8_t nodeType;
union {
struct {
union {
int32_t optr; // binary operator
int32_t functionId;// unary operator
};
int32_t optr; // binary operator
void *info; // support filter operation on this expression only available for leaf node
struct tExprNode *pLeft; // left child pointer
struct tExprNode *pRight; // right child pointer
......@@ -180,18 +178,32 @@ typedef struct tExprNode {
SSchema *pSchema;// column node
struct SVariant *pVal; // value node
struct {// function node
char *functionName;
int32_t functionId;
int32_t num;
// Note that the attribute of pChild is not the parameter of function, it is the columns that involved in the
// calculation instead.
// E.g., Cov(col1, col2), the column information, w.r.t. the col1 and col2, is kept in pChild nodes.
// The concat function, concat(col1, col2), is a binary scalar
// operator and is kept in the attribute of _node.
struct tExprNode **pChild;
} _function;
};
} tExprNode;
//TODO create?
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *));
typedef struct SAggFunctionInfo {
char name[FUNCTIONS_NAME_MAX_LENGTH];
int8_t type; // Scalar function or aggregation function
uint8_t functionId; // Function Id
int8_t sFunctionId; // Transfer function for super table query
uint16_t status;
char name[FUNCTIONS_NAME_MAX_LENGTH];
int8_t type; // Scalar function or aggregation function
uint32_t functionId; // Function Id
int8_t sFunctionId; // Transfer function for super table query
uint16_t status;
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
void (*addInput)(SQLFunctionCtx *pCtx);
......@@ -203,13 +215,13 @@ typedef struct SAggFunctionInfo {
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId);
} SAggFunctionInfo;
typedef struct SScalarFunctionInfo {
char name[FUNCTIONS_NAME_MAX_LENGTH];
int8_t type; // scalar function or aggregation function
uint8_t functionId; // index of scalar function
struct SScalarFuncParam;
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
void (*addInput)(SQLFunctionCtx *pCtx);
typedef struct SScalarFunctionInfo {
char name[FUNCTIONS_NAME_MAX_LENGTH];
int8_t type; // scalar function or aggregation function
uint32_t functionId; // index of scalar function
void (*process)(const struct SScalarFuncParam *pInput, struct SScalarFuncParam* pOutput);
} SScalarFunctionInfo;
typedef struct SMultiFunctionsDesc {
......@@ -241,7 +253,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
* @param len
* @return
*/
int32_t qIsBuiltinFunction(const char* name, int32_t len);
int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction);
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId);
......
......@@ -26,29 +26,6 @@ extern "C" {
#include "tvariant.h"
#include "function.h"
typedef struct SColumn {
uint64_t tableUid;
int32_t columnIndex;
SColumnInfo info;
} SColumn;
//typedef struct SInterval {
// int32_t tz; // query client timezone
// char intervalUnit;
// char slidingUnit;
// char offsetUnit;
// int64_t interval;
// int64_t sliding;
// int64_t offset;
//} SInterval;
//
//typedef struct SSessionWindow {
// int64_t gap; // gap between two session window(in microseconds)
// int32_t primaryColId; // primary timestamp column
//} SSessionWindow;
typedef struct SField {
char name[TSDB_COL_NAME_LEN];
uint8_t type;
......@@ -89,12 +66,6 @@ typedef struct STagCond {
typedef struct STableMetaInfo {
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
SVgroupsInfo *vgroupList;
/*
* 1. keep the vgroup index during the multi-vnode super table projection query
* 2. keep the vgroup index for multi-vnode insertion
*/
int32_t vgroupIndex;
SName name;
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
SArray *tagColList; // SArray<SColumn*>, involved tag columns
......
......@@ -134,14 +134,14 @@ do { \
#define TSDB_BINARY_OP_REMAINDER 4004
#define TSDB_BINARY_OP_CONCAT 4005
#define TSDB_UNARY_OP_CEIL 4500
#define TSDB_UNARY_OP_FLOOR 4501
#define TSDB_UNARY_OP_ABS 4502
#define TSDB_UNARY_OP_ROUND 4503
#define TSDB_UNARY_OP_LEN 4600
#define TSDB_UNARY_OP_LTRIM 4601
#define TSDB_UNARY_OP_RTRIM 4601
#define FUNCTION_CEIL 4500
#define FUNCTION_FLOOR 4501
#define FUNCTION_ABS 4502
#define FUNCTION_ROUND 4503
#define FUNCTION_LENGTH 4800
#define FUNCTION_LTRIM 4801
#define FUNCTION_RTRIM 4802
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
......
......@@ -1040,13 +1040,14 @@ static TSKEY getStartTsKey(SQueryAttr* pQueryAttr, STimeWindow* win, const TSKEY
}
static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order);
static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) {
for (int32_t i = 0; i < pOperator->numOfOutput; ++i) {
pCtx[i].order = order;
pCtx[i].size = pBlock->info.rows;
pCtx[i].currentStage = (uint8_t)pOperator->pRuntimeEnv->scanFlag;
setBlockStatisInfo(&pCtx[i], pBlock, &pOperator->pExpr[i].base.colInfo);
setBlockStatisInfo(&pCtx[i], pBlock, NULL/*&pOperator->pExpr[i].base.colInfo*/);
}
}
......@@ -2358,8 +2359,8 @@ bool onlyQueryTags(SQueryAttr* pQueryAttr) {
if (functionId != FUNCTION_TAGPRJ &&
functionId != FUNCTION_TID_TAG &&
(!(functionId == FUNCTION_COUNT && pExprInfo->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX)) &&
(!(functionId == FUNCTION_PRJ && TSDB_COL_IS_UD_COL(pExprInfo->base.colInfo.flag)))) {
(!(functionId == FUNCTION_COUNT && pExprInfo->base.pColumns->colId == TSDB_TBNAME_COLUMN_INDEX)) &&
(!(functionId == FUNCTION_PRJ && TSDB_COL_IS_UD_COL(pExprInfo->base.pColumns->flag)))) {
return false;
}
}
......@@ -2878,7 +2879,7 @@ static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSData
int32_t numOfOutput = pTableScanInfo->numOfOutput;
for (int32_t i = 0; i < numOfOutput; ++i) {
int32_t functionId = pCtx[i].functionId;
int32_t colId = pTableScanInfo->pExpr[i].base.colInfo.colId;
int32_t colId = pTableScanInfo->pExpr[i].base.pColumns->colId;
// group by + first/last should not apply the first/last block filter
if (functionId < 0) {
......@@ -3205,12 +3206,12 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt
SExprInfo* pLocalExprInfo = &pExpr[idx];
// ts_comp column required the tag value for join filter
if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.colInfo.flag)) {
if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.pColumns->flag)) {
continue;
}
// todo use tag column index to optimize performance
doSetTagValueInParam(pTable, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->base.resSchema.type,
doSetTagValueInParam(pTable, pLocalExprInfo->base.pColumns->colId, &pCtx[idx].tag, pLocalExprInfo->base.resSchema.type,
pLocalExprInfo->base.resSchema.bytes);
if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resSchema.type)
......@@ -5071,7 +5072,7 @@ SArray* getResultGroupCheckColumns(SQueryAttr* pQuery) {
int32_t functionId = getExprFunctionId(&pQuery->pExpr1[j]);
// FUNCTION_TAG_DUMMY function needs to be ignored
if (index->colId == pExpr->colInfo.colId &&
if (index->colId == pExpr->pColumns->info.colId &&
((TSDB_COL_IS_TAG(pExpr->colInfo.flag) && functionId == FUNCTION_TAG) ||
(TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && functionId == FUNCTION_PRJ))) {
index->colIndex = j;
......@@ -5290,7 +5291,7 @@ SOperatorInfo *createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI
pDataBlock->pDataBlock = taosArrayInit(numOfOutput, sizeof(SColumnInfoData));
for(int32_t i = 0; i < numOfOutput; ++i) {
SColumnInfoData col = {{0}};
col.info.colId = pExpr[i].base.colInfo.colId;
col.info.colId = pExpr[i].base.pColumns->colId;
// col.info.bytes = pExpr[i].base.colBytes;
// col.info.type = pExpr[i].base.colType;
taosArrayPush(pDataBlock->pDataBlock, &col);
......@@ -6776,7 +6777,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
int16_t type = pExprInfo->base.resSchema.type;
for(int32_t i = 0; i < pQueryAttr->numOfTags; ++i) {
if (pQueryAttr->tagColList[i].colId == pExprInfo->base.colInfo.colId) {
if (pQueryAttr->tagColList[i].colId == pExprInfo->base.pColumns->colId) {
bytes = pQueryAttr->tagColList[i].bytes;
type = pQueryAttr->tagColList[i].type;
break;
......@@ -6808,10 +6809,10 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
output += sizeof(pQueryAttr->vgId);
char* data = NULL;
if (pExprInfo->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) {
if (pExprInfo->base.pColumns->colId == TSDB_TBNAME_COLUMN_INDEX) {
data = tsdbGetTableName(item->pTable);
} else {
data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.colInfo.colId, type, bytes);
data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.pColumns->colId, type, bytes);
}
doSetTagValueToResultBuf(output, data, type, bytes);
......@@ -6839,7 +6840,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
int16_t type = 0, bytes = 0;
for(int32_t j = 0; j < pOperator->numOfOutput; ++j) {
// not assign value in case of user defined constant output column
if (TSDB_COL_IS_UD_COL(pExprInfo[j].base.colInfo.flag)) {
if (TSDB_COL_IS_UD_COL(pExprInfo[j].base.pColumns->flag)) {
continue;
}
......@@ -6847,10 +6848,10 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
type = pExprInfo[j].base.resSchema.type;
bytes = pExprInfo[j].base.resSchema.bytes;
if (pExprInfo[j].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) {
if (pExprInfo[j].base.pColumns->colId == TSDB_TBNAME_COLUMN_INDEX) {
data = tsdbGetTableName(item->pTable);
} else {
data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.colInfo.colId, type, bytes);
data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.pColumns->colId, type, bytes);
}
dst = pColInfo->pData + count * pExprInfo[j].base.resSchema.bytes;
......@@ -7310,9 +7311,9 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
for (int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) {
param->pExpr[i] = pExprMsg;
pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag);
// pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
// pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
// pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag);
// pExprMsg->colBytes = htons(pExprMsg->colBytes);
// pExprMsg->colType = htons(pExprMsg->colType);
......@@ -7361,9 +7362,9 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
for (int32_t i = 0; i < pQueryMsg->secondStageOutput; ++i) {
param->pSecExpr[i] = pExprMsg;
pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag);
// pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
// pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
// pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag);
// pExprMsg->resType = htons(pExprMsg->resType);
// pExprMsg->resBytes = htons(pExprMsg->resBytes);
// pExprMsg->colBytes = htons(pExprMsg->colBytes);
......@@ -7677,11 +7678,11 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
SSchema s = {.type=TSDB_DATA_TYPE_BINARY, .bytes=TSDB_MAX_BINARY_LEN};
type = s.type;
bytes = s.bytes;
} else if (pExprs[i].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX && functionId == FUNCTION_TAGPRJ) { // parse the normal column
} else if (pExprs[i].base.pColumns->info.colId == TSDB_TBNAME_COLUMN_INDEX && functionId == FUNCTION_TAGPRJ) { // parse the normal column
SSchema* s = tGetTbnameColumnSchema();
type = s->type;
bytes = s->bytes;
} else if (pExprs[i].base.colInfo.colId <= TSDB_UD_COLUMN_INDEX && pExprs[i].base.colInfo.colId > TSDB_RES_COL_ID) {
} else if (pExprs[i].base.pColumns->info.colId <= TSDB_UD_COLUMN_INDEX && pExprs[i].base.pColumns->info.colId > TSDB_RES_COL_ID) {
// it is a user-defined constant value column
assert(functionId == FUNCTION_PRJ);
......@@ -7692,7 +7693,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
}
} else {
int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols);
if (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag)) {
if (TSDB_COL_IS_TAG(pExprs[i].base.pColumns->flag)) {
if (j < TSDB_TBNAME_COLUMN_INDEX || j >= pTableInfo->numOfTags) {
tfree(pExprs);
return TSDB_CODE_QRY_INVALID_MSG;
......@@ -7704,8 +7705,8 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
}
}
if (pExprs[i].base.colInfo.colId != TSDB_TBNAME_COLUMN_INDEX && j >= 0) {
SColumnInfo* pCol = (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag))? &pTagCols[j]:&pTableInfo->colList[j];
if (pExprs[i].base.pColumns->info.colId != TSDB_TBNAME_COLUMN_INDEX && j >= 0) {
SColumnInfo* pCol = (TSDB_COL_IS_TAG(pExprs[i].base.pColumns->flag))? &pTagCols[j]:&pTableInfo->colList[j];
type = pCol->type;
bytes = pCol->bytes;
} else {
......@@ -7814,7 +7815,7 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu
// bytes = tDataTypes[type].bytes;
// } else {
// int32_t index = pExprs[i].base.colInfo.colIndex;
// assert(prevExpr[index].base.resSchema.colId == pExprs[i].base.colInfo.colId);
// assert(prevExpr[index].base.resSchema.colId == pExprs[i].base.pColumns->colId);
//
// type = prevExpr[index].base.resSchema.type;
// bytes = prevExpr[index].base.resSchema.bytes;
......@@ -8083,7 +8084,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
pQueryAttr->resultRowSize += pExprs[col].base.resSchema.bytes;
// keep the tag length
if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) {
if (TSDB_COL_IS_TAG(pExprs[col].base.pColumns->flag)) {
pQueryAttr->tagLen += pExprs[col].base.resSchema.bytes;
}
......
......@@ -37,7 +37,7 @@ typedef struct SScalarFunctionSupport {
char** data;
} SScalarFunctionSupport;
extern struct SScalarFunctionInfo scalarFunc[1];
extern struct SScalarFunctionInfo scalarFunc[5];
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput,
void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t));
......
......@@ -543,8 +543,8 @@ struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, co
pFillCol[i].col.offset = offset;
pFillCol[i].col.colId = pExprInfo->base.resSchema.colId;
pFillCol[i].tagIndex = -2;
pFillCol[i].flag = pExprInfo->base.colInfo.flag; // always be the normal column for table query
pFillCol[i].functionId = pExprInfo->pExpr->_node.functionId;
pFillCol[i].flag = pExprInfo->base.pColumns->flag; // always be the normal column for table query
pFillCol[i].functionId = pExprInfo->pExpr->_function.functionId;
pFillCol[i].fillVal.i = fillVal[i];
offset += pExprInfo->base.resSchema.bytes;
......
......@@ -30,11 +30,12 @@ static void doInitFunctionHashTable() {
static pthread_once_t functionHashTableInit = PTHREAD_ONCE_INIT;
int32_t qIsBuiltinFunction(const char* name, int32_t len) {
int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction) {
pthread_once(&functionHashTableInit, doInitFunctionHashTable);
SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, name, len);
if (pInfo != NULL) {
*scalarFunction = ((*pInfo)->type == FUNCTION_TYPE_SCALAR);
return (*pInfo)->functionId;
} else {
return -1;
......
......@@ -2,6 +2,156 @@
#include "tbinoperator.h"
#include "tunaryoperator.h"
static void assignBasicParaInfo(struct SScalarFuncParam* dst, const struct SScalarFuncParam* src) {
dst->type = src->type;
dst->bytes = src->bytes;
dst->num = src->num;
}
static void tceil(const SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = ceilf(p[i]);
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*)pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = ceil(p[i]);
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void tfloor(const SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = floorf(p[i]);
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = floor(p[i]);
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void _tabs(const SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_TINYINT: {
int8_t* p = (int8_t*) pLeft->data;
int8_t* out = (int8_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_SMALLINT: {
int16_t* p = (int16_t*) pLeft->data;
int16_t* out = (int16_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_INT: {
int32_t* p = (int32_t*) pLeft->data;
int32_t* out = (int32_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_BIGINT: {
int64_t* p = (int64_t*) pLeft->data;
int64_t* out = (int64_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void tround(const SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = roundf(p[i]);
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = round(p[i]);
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void tlength(const SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
int64_t* out = (int64_t*) pOutput->data;
char* s = pLeft->data;
for(int32_t i = 0; i < pLeft->num; ++i) {
out[i] = varDataLen(POINTER_SHIFT(s, i * pLeft->bytes));
}
}
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
switch(type) {
case TSDB_DATA_TYPE_TINYINT:
......@@ -168,11 +318,12 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa
return 0;
}
SScalarFunctionInfo scalarFunc[1] = {
{
},
SScalarFunctionInfo scalarFunc[5] = {
{"ceil", FUNCTION_TYPE_SCALAR, FUNCTION_CEIL, tceil},
{"floor", FUNCTION_TYPE_SCALAR, FUNCTION_FLOOR, tfloor},
{"abs", FUNCTION_TYPE_SCALAR, FUNCTION_ABS, _tabs},
{"round", FUNCTION_TYPE_SCALAR, FUNCTION_ROUND, tround},
{"length", FUNCTION_TYPE_SCALAR, FUNCTION_LENGTH, tlength},
};
void setScalarFunctionSupp(struct SScalarFunctionSupport* sas, SExprInfo *pExprInfo, SSDataBlock* pSDataBlock) {
......
#include "tunaryoperator.h"
static void assignBasicParaInfo(struct SScalarFuncParam* dst, const struct SScalarFuncParam* src) {
dst->type = src->type;
dst->bytes = src->bytes;
dst->num = src->num;
}
static void tceil(SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = ceilf(p[i]);
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*)pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = ceil(p[i]);
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void tfloor(SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = floorf(p[i]);
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = floor(p[i]);
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void _tabs(SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_TINYINT: {
int8_t* p = (int8_t*) pLeft->data;
int8_t* out = (int8_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_SMALLINT: {
int16_t* p = (int16_t*) pLeft->data;
int16_t* out = (int16_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_INT: {
int32_t* p = (int32_t*) pLeft->data;
int32_t* out = (int32_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
case TSDB_DATA_TYPE_BIGINT: {
int64_t* p = (int64_t*) pLeft->data;
int64_t* out = (int64_t*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = (p[i] > 0)? p[i]:-p[i];
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void tround(SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
assignBasicParaInfo(pOutput, pLeft);
switch (pLeft->bytes) {
case TSDB_DATA_TYPE_FLOAT: {
float* p = (float*) pLeft->data;
float* out = (float*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = roundf(p[i]);
}
}
case TSDB_DATA_TYPE_DOUBLE: {
double* p = (double*) pLeft->data;
double* out = (double*) pOutput->data;
for (int32_t i = 0; i < pLeft->num; ++i) {
out[i] = round(p[i]);
}
}
default:
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
}
}
static void tlen(SScalarFuncParam *pLeft, SScalarFuncParam* pOutput) {
int64_t* out = (int64_t*) pOutput->data;
char* s = pLeft->data;
for(int32_t i = 0; i < pLeft->num; ++i) {
out[i] = varDataLen(POINTER_SHIFT(s, i * pLeft->bytes));
}
}
// TODO dynamic define these functions
_unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t operator) {
switch(operator) {
case TSDB_UNARY_OP_CEIL:
return tceil;
case TSDB_UNARY_OP_FLOOR:
return tfloor;
case TSDB_UNARY_OP_ROUND:
return tround;
case TSDB_UNARY_OP_ABS:
return _tabs;
case TSDB_UNARY_OP_LEN:
return tlen;
default:
assert(0);
}
assert(0);
}
bool isStringOperatorFn(int32_t op) {
return op == TSDB_UNARY_OP_LEN;
return op == FUNCTION_LENGTH;
}
......@@ -38,6 +38,7 @@ extern "C" {
TAOS_FIELD createField(const SSchema* pSchema);
SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name);
void setColumn(SColumn* pColumn, uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema);
SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* field);
int32_t getNumOfFields(SFieldInfo* pFieldInfo);
......@@ -51,7 +52,7 @@ STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
void columnListCopyAll(SArray* dst, const SArray* src);
SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
SColumn* columnListInsert(SArray* pColumnList, uint64_t uid, SSchema* pSchema, int32_t flag);
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid);
void cleanupTagCond(STagCond* pTagCond);
......
......@@ -177,7 +177,8 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
}
// Let's assume that it is an UDF/UDAF, if it is not a built-in function.
if (qIsBuiltinFunction(t->z, t->n) < 0) {
bool scalarFunc = false;
if (qIsBuiltinFunction(t->z, t->n, &scalarFunc) < 0) {
char* fname = strndup(t->z, t->n);
taosArrayPush(pMetaInfo->pUdf, &fname);
}
......
......@@ -513,6 +513,20 @@ SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* nam
return s;
}
void setColumn(SColumn* pColumn, uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema) {
pColumn->uid = uid;
pColumn->flag = flag;
pColumn->info.colId = pSchema->colId;
pColumn->info.bytes = pSchema->bytes;
pColumn->info.type = pSchema->type;
if (tableName != NULL) {
snprintf(pColumn->name, tListLen(pColumn->name), "%s.%s", tableName, pSchema->name);
} else {
tstrncpy(pColumn->name, pSchema->name, tListLen(pColumn->name));
}
}
int32_t getNumOfFields(SFieldInfo* pFieldInfo) {
return pFieldInfo->numOfOutput;
}
......@@ -701,7 +715,7 @@ int32_t columnExists(SArray* pColumnList, int32_t columnId, uint64_t uid) {
int32_t i = 0;
while (i < numOfCols) {
SColumn* pCol = taosArrayGetP(pColumnList, i);
if ((pCol->info.colId != columnId) || (pCol->tableUid != uid)) {
if ((pCol->info.colId != columnId) || (pCol->uid != uid)) {
++i;
continue;
} else {
......@@ -716,64 +730,60 @@ int32_t columnExists(SArray* pColumnList, int32_t columnId, uint64_t uid) {
return i;
}
SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema) {
// ignore the tbname columnIndex to be inserted into source list
if (columnIndex < 0) {
return NULL;
}
static int32_t doFindPosition(const SArray* pColumnList, uint64_t uid, const SSchema* pSchema) {
int32_t i = 0;
size_t numOfCols = taosArrayGetSize(pColumnList);
int32_t i = 0;
while (i < numOfCols) {
SColumn* pCol = taosArrayGetP(pColumnList, i);
if (pCol->columnIndex < columnIndex) {
if (pCol->uid < uid) {
i++;
} else if (pCol->tableUid < uid) {
i++;
} else {
break;
continue;
}
}
if (i >= numOfCols || numOfCols == 0) {
SColumn* b = calloc(1, sizeof(SColumn));
if (b == NULL) {
return NULL;
if (pCol->info.colId < pSchema->colId) {
i++;
continue;
}
b->columnIndex = columnIndex;
b->tableUid = uid;
b->info.colId = pSchema->colId;
b->info.bytes = pSchema->bytes;
b->info.type = pSchema->type;
taosArrayInsert(pColumnList, i, &b);
} else {
SColumn* pCol = taosArrayGetP(pColumnList, i);
break;
}
if (i < numOfCols && (pCol->columnIndex > columnIndex || pCol->tableUid != uid)) {
SColumn* b = calloc(1, sizeof(SColumn));
if (b == NULL) {
return NULL;
}
return i;
}
b->columnIndex = columnIndex;
b->tableUid = uid;
b->info.colId = pSchema->colId;
b->info.bytes = pSchema->bytes;
b->info.type = pSchema->type;
SColumn* columnListInsert(SArray* pColumnList, uint64_t uid, SSchema* pSchema, int32_t flag) {
// ignore the tbname columnIndex to be inserted into source list
assert(pSchema != NULL && pColumnList != NULL);
taosArrayInsert(pColumnList, i, &b);
int32_t i = doFindPosition(pColumnList, uid, pSchema);
size_t size = taosArrayGetSize(pColumnList);
if (size > 0 && i < size) {
SColumn* pCol = taosArrayGetP(pColumnList, i);
if (pCol->uid == uid && pCol->info.colId == pSchema->colId) {
return pCol;
}
}
return taosArrayGetP(pColumnList, i);
SColumn* b = calloc(1, sizeof(SColumn));
if (b == NULL) {
return NULL;
}
b->uid = uid;
b->flag = flag;
b->info.colId = pSchema->colId;
b->info.bytes = pSchema->bytes;
b->info.type = pSchema->type;
tstrncpy(b->name, pSchema->name, tListLen(b->name));
taosArrayInsert(pColumnList, i, &b);
return b;
}
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid) {
SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_ID};
return columnListInsert(pColumnList, PRIMARYKEY_TIMESTAMP_COL_ID, tableUid, &s);
return columnListInsert(pColumnList, tableUid, &s, TSDB_COL_NORMAL);
}
void columnCopy(SColumn* pDest, const SColumn* pSrc);
......@@ -817,8 +827,7 @@ SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFil
void columnCopy(SColumn* pDest, const SColumn* pSrc) {
destroyFilterInfo(&pDest->info.flist);
pDest->columnIndex = pSrc->columnIndex;
pDest->tableUid = pSrc->tableUid;
pDest->uid = pSrc->uid;
pDest->info.flist.numOfFilters = pSrc->info.flist.numOfFilters;
pDest->info.flist.filterInfo = tFilterInfoDup(pSrc->info.flist.filterInfo, pSrc->info.flist.numOfFilters);
pDest->info.type = pSrc->info.type;
......@@ -844,7 +853,7 @@ void columnListCopy(SArray* dst, const SArray* src, uint64_t uid) {
for (int32_t i = 0; i < num; ++i) {
SColumn* pCol = taosArrayGetP(src, i);
if (pCol->tableUid == uid) {
if (pCol->uid == uid) {
SColumn* p = columnClone(pCol);
taosArrayPush(dst, &p);
}
......
......@@ -55,7 +55,7 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns);
}
static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode) {
static tExprNode* createFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode, int32_t numOfCols) {
if (pColumnNode == NULL) {
pColumnNode = calloc(1, sizeof(tExprNode));
pColumnNode->nodeType = TEXPR_COL_NODE;
......@@ -66,9 +66,10 @@ static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSche
}
tExprNode* pNode = calloc(1, sizeof(tExprNode));
pNode->nodeType = TEXPR_UNARYEXPR_NODE;
pNode->_node.functionId = functionId;
pNode->_node.pLeft = pColumnNode;
pNode->nodeType = TEXPR_FUNCTION_NODE;
pNode->_function.functionId = functionId;
pNode->_function.pChild = pColumnNode;
pNode->_function.num = numOfCols;
return pNode;
}
......@@ -92,48 +93,50 @@ SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SC
return NULL;
}
uint64_t uid = 0;
if (pTableMetaInfo->pTableMeta) {
uid = pTableMetaInfo->pTableMeta->uid;
}
SSqlExpr* p = &pExpr->base;
p->pColumns = calloc(1, sizeof(SColumn));
p->numOfCols = 1;
if (pParamExpr != NULL) {
pExpr->pExpr = createUnaryFunctionExprNode(functionId, NULL, pParamExpr);
pExpr->pExpr = createFunctionExprNode(functionId, NULL, pParamExpr, 1);
// pExpr->base.pColumns
// todo set the correct number of columns
} else if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
assert(pParamExpr == NULL);
SSchema* s = getTbnameColumnSchema();
p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
pExpr->pExpr = createUnaryFunctionExprNode(functionId, s, pParamExpr);
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_TAG, s);
pExpr->pExpr = createFunctionExprNode(functionId, s, pParamExpr, 1);
} else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX || functionId == FUNCTION_BLKINFO) {
assert(pParamExpr == NULL);
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_UDC, pResSchema);
p->colInfo.colId = pColIndex->columnIndex;
SSchema s = createSchema(pResSchema->type, pResSchema->bytes, pColIndex->columnIndex, pResSchema->name);
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s, pParamExpr);
pExpr->pExpr = createFunctionExprNode(functionId, &s, pParamExpr, 1);
} else {
int32_t len = tListLen(p->colInfo.name);
if (TSDB_COL_IS_TAG(pColIndex->type)) {
SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta);
p->colInfo.colId = pSchema[pColIndex->columnIndex].colId;
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex], pParamExpr);
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema[pColIndex->columnIndex].name);
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_TAG, &pSchema[pColIndex->columnIndex]);
pExpr->pExpr = createFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex], pParamExpr, 1);
} else if (pTableMetaInfo->pTableMeta != NULL) {
// in handling select database/version/server_status(), the pTableMeta is NULL
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex);
p->colInfo.colId = pSchema->colId;
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema->name);
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_NORMAL, pSchema);
pExpr->pExpr = createUnaryFunctionExprNode(functionId, pSchema, pParamExpr);
pExpr->pExpr = createFunctionExprNode(functionId, pSchema, pParamExpr, 1);
}
}
p->colInfo.flag = pColIndex->type;
p->colInfo.colIndex = pColIndex->columnIndex;
p->pColumns->flag = pColIndex->type;
p->interBytes = interSize;
memcpy(&p->resSchema, pResSchema, sizeof(SSchema));
if (pTableMetaInfo->pTableMeta) {
p->uid = pTableMetaInfo->pTableMeta->uid;
}
return pExpr;
}
......@@ -152,10 +155,9 @@ void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int
assert(pExprInfo != NULL);
SSqlExpr* pse = &pExprInfo->base;
pExprInfo->pExpr->_node.functionId = functionId;
pExprInfo->pExpr->_function.functionId = functionId;
assert(0);
pse->colInfo.colIndex = srcColumnIndex;
pse->colInfo.colId = colId;
pse->resSchema.type = resType;
pse->resSchema.bytes = resSize;
}
......@@ -198,7 +200,7 @@ void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t byt
int32_t getExprFunctionId(SExprInfo *pExprInfo) {
assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
return pExprInfo->pExpr->_node.functionId;
return pExprInfo->pExpr->_function.functionId;
}
void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
......@@ -225,8 +227,9 @@ int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deep
size_t size = taosArrayGetSize(src);
for (int32_t i = 0; i < size; ++i) {
SExprInfo* pExpr = taosArrayGetP(src, i);
uint64_t exprUid = pExpr->base.pColumns->uid;
if (pExpr->base.uid == uid) {
if (exprUid == uid) {
if (deepcopy) {
SExprInfo* p1 = calloc(1, sizeof(SExprInfo));
assignExprInfo(p1, pExpr);
......@@ -300,7 +303,7 @@ SArray* extractFunctionIdList(SArray* pExprInfoList) {
SArray* p = taosArrayInit(len, sizeof(int32_t));
for(int32_t i = 0; i < len; ++i) {
SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i);
taosArrayPush(p, &pExprInfo->pExpr->_node.functionId);
taosArrayPush(p, &pExprInfo->pExpr->_function.functionId);
}
return p;
......
......@@ -95,16 +95,16 @@ TEST(testCase, planner_test) {
ASSERT_EQ(taosArrayGetSize(pExprList), 2);
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1);
ASSERT_EQ(p1->base.uid, 110);
ASSERT_EQ(p1->base.pColumns->uid, 110);
ASSERT_EQ(p1->base.numOfParams, 1);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)");
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)");
ASSERT_EQ(p1->base.interBytes, 16);
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_TOP);
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
ASSERT_EQ(p1->pExpr->_function.functionId, FUNCTION_TOP);
ASSERT_TRUE(p1->pExpr->_node.pRight == NULL);
tExprNode* pParam = p1->pExpr->_node.pLeft;
......
......@@ -186,7 +186,7 @@ static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMe
for (int32_t i = 0; i < numOfCols; ++i) {
SColumn* pCol = taosArrayGetP(tableCols, i);
SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex};
SColumnIndex index = {.tableIndex = 0, /*.columnIndex = pCol->columnIndex*/};
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, i);
SSchema resultSchema = *pSchema;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册