提交 3f84c37d 编写于 作者: H Haojun Liao

[td-10564] Add more implementation of parser.

上级 24090f01
...@@ -22,10 +22,12 @@ extern "C" { ...@@ -22,10 +22,12 @@ extern "C" {
#include "common.h" #include "common.h"
#include "tvariant.h" #include "tvariant.h"
#include "tbuffer.h"
#define FUNCTION_SCALAR 1 #define FUNCTION_SCALAR 1
#define FUNCTION_AGG 2 #define FUNCTION_AGG 2
#define TOP_BOTTOM_QUERY_LIMIT 100
#define FUNCTIONS_NAME_MAX_LENGTH 16 #define FUNCTIONS_NAME_MAX_LENGTH 16
#define FUNCTION_INVALID_ID -1 #define FUNCTION_INVALID_ID -1
...@@ -121,6 +123,35 @@ typedef struct SQLFunctionCtx { ...@@ -121,6 +123,35 @@ typedef struct SQLFunctionCtx {
SPoint1 end; SPoint1 end;
} SQLFunctionCtx; } SQLFunctionCtx;
enum {
TEXPR_NODE_DUMMY = 0x0,
TEXPR_BINARYEXPR_NODE= 0x1,
TEXPR_UNARYEXPR_NODE = 0x2,
TEXPR_COL_NODE = 0x4,
TEXPR_VALUE_NODE = 0x8,
};
typedef struct tExprNode {
uint8_t nodeType;
union {
struct {
union {
int32_t optr; // binary operator
int32_t functionId;// unary 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
} _node;
SSchema *pSchema;// column node
struct SVariant *pVal; // value node
};
} tExprNode;
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *));
typedef struct SAggFunctionInfo { typedef struct SAggFunctionInfo {
char name[FUNCTIONS_NAME_MAX_LENGTH]; char name[FUNCTIONS_NAME_MAX_LENGTH];
int8_t type; // Scalar function or aggregation function int8_t type; // Scalar function or aggregation function
...@@ -158,6 +189,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI ...@@ -158,6 +189,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*/ */
int32_t qIsBuiltinFunction(const char* name, int32_t len); int32_t qIsBuiltinFunction(const char* name, int32_t len);
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId);
const char* qGetFunctionName(int32_t functionId);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -24,8 +24,8 @@ extern "C" { ...@@ -24,8 +24,8 @@ extern "C" {
#define QUERY_TYPE_PARTIAL 2 #define QUERY_TYPE_PARTIAL 2
struct SEpSet; struct SEpSet;
struct SQueryNode; struct SQueryPlanNode;
struct SQueryPhyNode; struct SQueryDistPlanNode;
struct SQueryStmtInfo; struct SQueryStmtInfo;
typedef struct SSubquery { typedef struct SSubquery {
...@@ -33,7 +33,7 @@ typedef struct SSubquery { ...@@ -33,7 +33,7 @@ typedef struct SSubquery {
int32_t type; // QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL int32_t type; // QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL
int32_t level; // the execution level of current subquery, starting from 0. int32_t level; // the execution level of current subquery, starting from 0.
SArray *pUpstream; // the upstream,from which to fetch the result SArray *pUpstream; // the upstream,from which to fetch the result
struct SQueryPhyNode *pNode; // physical plan of current subquery struct SQueryDistPlanNode *pNode; // physical plan of current subquery
} SSubquery; } SSubquery;
typedef struct SQueryJob { typedef struct SQueryJob {
...@@ -48,7 +48,7 @@ typedef struct SQueryJob { ...@@ -48,7 +48,7 @@ typedef struct SQueryJob {
* @param pQueryNode * @param pQueryNode
* @return * @return
*/ */
int32_t qOptimizeQueryPlan(struct SQueryNode* pQueryNode); int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode);
/** /**
* Create the query plan according to the bound AST, which is in the form of pQueryInfo * Create the query plan according to the bound AST, which is in the form of pQueryInfo
...@@ -56,14 +56,14 @@ int32_t qOptimizeQueryPlan(struct SQueryNode* pQueryNode); ...@@ -56,14 +56,14 @@ int32_t qOptimizeQueryPlan(struct SQueryNode* pQueryNode);
* @param pQueryNode * @param pQueryNode
* @return * @return
*/ */
int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryNode* pQueryNode); int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode* pQueryNode);
/** /**
* Convert the query plan to string, in order to display it in the shell. * Convert the query plan to string, in order to display it in the shell.
* @param pQueryNode * @param pQueryNode
* @return * @return
*/ */
int32_t qQueryPlanToString(struct SQueryNode* pQueryNode, char** str); int32_t qQueryPlanToString(struct SQueryPlanNode* pQueryNode, char** str);
/** /**
* Restore the SQL statement according to the logic query plan. * Restore the SQL statement according to the logic query plan.
...@@ -71,7 +71,7 @@ int32_t qQueryPlanToString(struct SQueryNode* pQueryNode, char** str); ...@@ -71,7 +71,7 @@ int32_t qQueryPlanToString(struct SQueryNode* pQueryNode, char** str);
* @param sql * @param sql
* @return * @return
*/ */
int32_t qQueryPlanToSql(struct SQueryNode* pQueryNode, char** sql); int32_t qQueryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql);
/** /**
* Create the physical plan for the query, according to the logic plan. * Create the physical plan for the query, according to the logic plan.
...@@ -79,7 +79,7 @@ int32_t qQueryPlanToSql(struct SQueryNode* pQueryNode, char** sql); ...@@ -79,7 +79,7 @@ int32_t qQueryPlanToSql(struct SQueryNode* pQueryNode, char** sql);
* @param pPhyNode * @param pPhyNode
* @return * @return
*/ */
int32_t qCreatePhysicalPlan(struct SQueryNode* pQueryNode, struct SEpSet* pQnode, struct SQueryPhyNode *pPhyNode); int32_t qCreatePhysicalPlan(struct SQueryPlanNode* pQueryNode, struct SEpSet* pQnode, struct SQueryDistPlanNode *pPhyNode);
/** /**
* Convert to physical plan to string to enable to print it out in the shell. * Convert to physical plan to string to enable to print it out in the shell.
...@@ -87,20 +87,20 @@ int32_t qCreatePhysicalPlan(struct SQueryNode* pQueryNode, struct SEpSet* pQnode ...@@ -87,20 +87,20 @@ int32_t qCreatePhysicalPlan(struct SQueryNode* pQueryNode, struct SEpSet* pQnode
* @param str * @param str
* @return * @return
*/ */
int32_t qPhyPlanToString(struct SQueryPhyNode *pPhyNode, char** str); int32_t qPhyPlanToString(struct SQueryDistPlanNode *pPhyNode, char** str);
/** /**
* Destroy the query plan object. * Destroy the query plan object.
* @return * @return
*/ */
void* qDestroyQueryPlan(struct SQueryNode* pQueryNode); void* qDestroyQueryPlan(struct SQueryPlanNode* pQueryNode);
/** /**
* Destroy the physical plan. * Destroy the physical plan.
* @param pQueryPhyNode * @param pQueryPhyNode
* @return * @return
*/ */
void* qDestroyQueryPhyPlan(struct SQueryPhyNode* pQueryPhyNode); void* qDestroyQueryPhyPlan(struct SQueryDistPlanNode* pQueryPhyNode);
/** /**
* Create the query job from the physical execution plan * Create the query job from the physical execution plan
...@@ -108,7 +108,7 @@ void* qDestroyQueryPhyPlan(struct SQueryPhyNode* pQueryPhyNode); ...@@ -108,7 +108,7 @@ void* qDestroyQueryPhyPlan(struct SQueryPhyNode* pQueryPhyNode);
* @param pJob * @param pJob
* @return * @return
*/ */
int32_t qCreateQueryJob(const struct SQueryPhyNode* pPhyNode, struct SQueryJob** pJob); int32_t qCreateQueryJob(const struct SQueryDistPlanNode* pPhyNode, struct SQueryJob** pJob);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -125,11 +125,12 @@ do { \ ...@@ -125,11 +125,12 @@ do { \
#define TSDB_RELATION_MATCH 14 #define TSDB_RELATION_MATCH 14
#define TSDB_RELATION_NMATCH 15 #define TSDB_RELATION_NMATCH 15
#define TSDB_BINARY_OP_ADD 30 #define TSDB_BINARY_OP_ADD 4000
#define TSDB_BINARY_OP_SUBTRACT 31 #define TSDB_BINARY_OP_SUBTRACT 4001
#define TSDB_BINARY_OP_MULTIPLY 32 #define TSDB_BINARY_OP_MULTIPLY 4002
#define TSDB_BINARY_OP_DIVIDE 33 #define TSDB_BINARY_OP_DIVIDE 4003
#define TSDB_BINARY_OP_REMAINDER 34 #define TSDB_BINARY_OP_REMAINDER 4004
#define TSDB_BINARY_OP_CONCAT 4005
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN)) #define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
......
...@@ -18,3 +18,7 @@ ...@@ -18,3 +18,7 @@
struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) { struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) {
return NULL; return NULL;
} }
int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData) {
return 0;
}
...@@ -25,7 +25,7 @@ extern "C" { ...@@ -25,7 +25,7 @@ extern "C" {
#include "taosmsg.h" #include "taosmsg.h"
#include "taosdef.h" #include "taosdef.h"
#include "tskiplist.h" #include "tskiplist.h"
#include "tbuffer.h" #include "function.h"
struct tExprNode; struct tExprNode;
struct SSchema; struct SSchema;
...@@ -43,13 +43,6 @@ struct SSchema; ...@@ -43,13 +43,6 @@ struct SSchema;
typedef bool (*__result_filter_fn_t)(const void *, void *); typedef bool (*__result_filter_fn_t)(const void *, void *);
typedef void (*__do_filter_suppl_fn_t)(void *, void *); typedef void (*__do_filter_suppl_fn_t)(void *, void *);
enum {
TSQL_NODE_DUMMY = 0x0,
TSQL_NODE_EXPR = 0x1,
TSQL_NODE_COL = 0x2,
TSQL_NODE_VALUE = 0x4,
};
/** /**
* this structure is used to filter data in tags, so the offset of filtered tag column in tagdata string is required * this structure is used to filter data in tags, so the offset of filtered tag column in tagdata string is required
*/ */
...@@ -61,37 +54,16 @@ typedef struct tQueryInfo { ...@@ -61,37 +54,16 @@ typedef struct tQueryInfo {
bool indexed; // indexed columns bool indexed; // indexed columns
} tQueryInfo; } tQueryInfo;
typedef struct tExprNode {
uint8_t nodeType;
union {
struct {
uint8_t optr; // filter operator
uint8_t hasPK; // 0: do not contain primary filter, 1: contain
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
} _node;
SSchema *pSchema;
struct SVariant *pVal;
};
} tExprNode;
typedef struct SExprTraverseSupp { typedef struct SExprTraverseSupp {
__result_filter_fn_t nodeFilterFn; __result_filter_fn_t nodeFilterFn;
__do_filter_suppl_fn_t setupInfoFn; __do_filter_suppl_fn_t setupInfoFn;
void *pExtInfo; void *pExtInfo;
} SExprTraverseSupp; } SExprTraverseSupp;
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *));
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
tExprNode* exprTreeFromBinary(const void* data, size_t size); tExprNode* exprTreeFromBinary(const void* data, size_t size);
tExprNode* exprTreeFromTableName(const char* tbnameCond); tExprNode* exprTreeFromTableName(const char* tbnameCond);
tExprNode* exprdup(tExprNode* pTree); tExprNode* exprdup(tExprNode* pTree);
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param);
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "os.h" #include "os.h"
#include "texpr.h"
#include "exception.h" #include "exception.h"
#include "taosdef.h" #include "taosdef.h"
#include "taosmsg.h" #include "taosmsg.h"
...@@ -26,21 +25,21 @@ ...@@ -26,21 +25,21 @@
#include "thash.h" #include "thash.h"
#include "tskiplist.h" #include "tskiplist.h"
#include "texpr.h" #include "texpr.h"
#include "tarithoperator.h" //#include "tarithoperator.h"
#include "tvariant.h" #include "tvariant.h"
static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) { //static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
if (pLeft->nodeType == TSQL_NODE_COL) { // if (pLeft->nodeType == TEXPR_COL_NODE) {
// if left node is the primary column,return true // // if left node is the primary column,return true
return (strcmp(primaryColumnName, pLeft->pSchema->name) == 0) ? 1 : 0; // return (strcmp(primaryColumnName, pLeft->pSchema->name) == 0) ? 1 : 0;
} else { // } else {
// if any children have query on primary key, their parents are also keep this value // // if any children have query on primary key, their parents are also keep this value
return ((pLeft->nodeType == TSQL_NODE_EXPR && pLeft->_node.hasPK == 1) || // return ((pLeft->nodeType == TEXPR_BINARYEXPR_NODE && pLeft->_node.hasPK == 1) ||
(pRight->nodeType == TSQL_NODE_EXPR && pRight->_node.hasPK == 1)) == true // (pRight->nodeType == TEXPR_BINARYEXPR_NODE && pRight->_node.hasPK == 1)) == true
? 1 // ? 1
: 0; // : 0;
} // }
} //}
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) { static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
switch(type) { switch(type) {
...@@ -114,11 +113,11 @@ void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) { ...@@ -114,11 +113,11 @@ void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) {
return; return;
} }
if (pNode->nodeType == TSQL_NODE_EXPR) { if (pNode->nodeType == TEXPR_BINARYEXPR_NODE || pNode->nodeType == TEXPR_UNARYEXPR_NODE) {
doExprTreeDestroy(&pNode, fp); doExprTreeDestroy(&pNode, fp);
} else if (pNode->nodeType == TSQL_NODE_VALUE) { } else if (pNode->nodeType == TEXPR_VALUE_NODE) {
taosVariantDestroy(pNode->pVal); taosVariantDestroy(pNode->pVal);
} else if (pNode->nodeType == TSQL_NODE_COL) { } else if (pNode->nodeType == TEXPR_COL_NODE) {
tfree(pNode->pSchema); tfree(pNode->pSchema);
} }
...@@ -130,17 +129,17 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { ...@@ -130,17 +129,17 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
return; return;
} }
if ((*pExpr)->nodeType == TSQL_NODE_EXPR) { if ((*pExpr)->nodeType == TEXPR_BINARYEXPR_NODE) {
doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp); doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp);
doExprTreeDestroy(&(*pExpr)->_node.pRight, fp); doExprTreeDestroy(&(*pExpr)->_node.pRight, fp);
if (fp != NULL) { if (fp != NULL) {
fp((*pExpr)->_node.info); fp((*pExpr)->_node.info);
} }
} else if ((*pExpr)->nodeType == TSQL_NODE_VALUE) { } else if ((*pExpr)->nodeType == TEXPR_VALUE_NODE) {
taosVariantDestroy((*pExpr)->pVal); taosVariantDestroy((*pExpr)->pVal);
free((*pExpr)->pVal); free((*pExpr)->pVal);
} else if ((*pExpr)->nodeType == TSQL_NODE_COL) { } else if ((*pExpr)->nodeType == TEXPR_COL_NODE) {
free((*pExpr)->pSchema); free((*pExpr)->pSchema);
} }
...@@ -153,7 +152,7 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp ...@@ -153,7 +152,7 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp
tExprNode *pRight = pExpr->_node.pRight; tExprNode *pRight = pExpr->_node.pRight;
//non-leaf nodes, recursively traverse the expression tree in the post-root order //non-leaf nodes, recursively traverse the expression tree in the post-root order
if (pLeft->nodeType == TSQL_NODE_EXPR && pRight->nodeType == TSQL_NODE_EXPR) { if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE && pRight->nodeType == TEXPR_BINARYEXPR_NODE) {
if (pExpr->_node.optr == TSDB_RELATION_OR) { // or if (pExpr->_node.optr == TSDB_RELATION_OR) { // or
if (exprTreeApplyFilter(pLeft, pItem, param)) { if (exprTreeApplyFilter(pLeft, pItem, param)) {
return true; return true;
...@@ -180,26 +179,26 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, ...@@ -180,26 +179,26 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
if (pExprs == NULL) { if (pExprs == NULL) {
return; return;
} }
#if 0
tExprNode *pLeft = pExprs->_node.pLeft; tExprNode *pLeft = pExprs->_node.pLeft;
tExprNode *pRight = pExprs->_node.pRight; tExprNode *pRight = pExprs->_node.pRight;
/* the left output has result from the left child syntax tree */ /* the left output has result from the left child syntax tree */
char *pLeftOutput = (char*)malloc(sizeof(int64_t) * numOfRows); char *pLeftOutput = (char*)malloc(sizeof(int64_t) * numOfRows);
if (pLeft->nodeType == TSQL_NODE_EXPR) { if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE) {
arithmeticTreeTraverse(pLeft, numOfRows, pLeftOutput, param, order, getSourceDataBlock); arithmeticTreeTraverse(pLeft, numOfRows, pLeftOutput, param, order, getSourceDataBlock);
} }
/* the right output has result from the right child syntax tree */ // the right output has result from the right child syntax tree
char *pRightOutput = malloc(sizeof(int64_t) * numOfRows); char *pRightOutput = malloc(sizeof(int64_t) * numOfRows);
char *pdata = malloc(sizeof(int64_t) * numOfRows); char *pdata = malloc(sizeof(int64_t) * numOfRows);
if (pRight->nodeType == TSQL_NODE_EXPR) { if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) {
arithmeticTreeTraverse(pRight, numOfRows, pRightOutput, param, order, getSourceDataBlock); arithmeticTreeTraverse(pRight, numOfRows, pRightOutput, param, order, getSourceDataBlock);
} }
if (pLeft->nodeType == TSQL_NODE_EXPR) { if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE) {
if (pRight->nodeType == TSQL_NODE_EXPR) { if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) {
/* /*
* exprLeft + exprRight * exprLeft + exprRight
* the type of returned value of one expression is always double float precious * the type of returned value of one expression is always double float precious
...@@ -207,7 +206,7 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, ...@@ -207,7 +206,7 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC); OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC);
} else if (pRight->nodeType == TSQL_NODE_COL) { // exprLeft + columnRight } else if (pRight->nodeType == TEXPR_COL_NODE) { // exprLeft + columnRight
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
// set input buffer // set input buffer
...@@ -219,14 +218,14 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, ...@@ -219,14 +218,14 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC); OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC);
} }
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // exprLeft + 12 } else if (pRight->nodeType == TEXPR_VALUE_NODE) { // exprLeft + 12
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC);
} }
} else if (pLeft->nodeType == TSQL_NODE_COL) { } else if (pLeft->nodeType == TEXPR_COL_NODE) {
// column data specified on left-hand-side // column data specified on left-hand-side
char *pLeftInputData = getSourceDataBlock(param, pLeft->pSchema->name, pLeft->pSchema->colId); char *pLeftInputData = getSourceDataBlock(param, pLeft->pSchema->name, pLeft->pSchema->colId);
if (pRight->nodeType == TSQL_NODE_EXPR) { // columnLeft + expr2 if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) { // columnLeft + expr2
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
if (order == TSDB_ORDER_DESC) { if (order == TSDB_ORDER_DESC) {
...@@ -236,14 +235,14 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, ...@@ -236,14 +235,14 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC); OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC);
} }
} else if (pRight->nodeType == TSQL_NODE_COL) { // columnLeft + columnRight } else if (pRight->nodeType == TEXPR_COL_NODE) { // columnLeft + columnRight
// column data specified on right-hand-side // column data specified on right-hand-side
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId); char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
// both columns are descending order, do not reverse the source data // both columns are descending order, do not reverse the source data
OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, order); OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, order);
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // columnLeft + 12 } else if (pRight->nodeType == TEXPR_VALUE_NODE) { // columnLeft + 12
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
if (order == TSDB_ORDER_DESC) { if (order == TSDB_ORDER_DESC) {
...@@ -255,11 +254,11 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, ...@@ -255,11 +254,11 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
} }
} else { } else {
// column data specified on left-hand-side // column data specified on left-hand-side
if (pRight->nodeType == TSQL_NODE_EXPR) { // 12 + expr2 if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) { // 12 + expr2
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC); OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC);
} else if (pRight->nodeType == TSQL_NODE_COL) { // 12 + columnRight } else if (pRight->nodeType == TEXPR_COL_NODE) { // 12 + columnRight
// column data specified on right-hand-side // column data specified on right-hand-side
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId); char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
...@@ -271,7 +270,7 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, ...@@ -271,7 +270,7 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC); OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC);
} }
} else if (pRight->nodeType == TSQL_NODE_VALUE) { // 12 + 12 } else if (pRight->nodeType == TEXPR_VALUE_NODE) { // 12 + 12
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr); _arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC); OperatorFn(&pLeft->pVal->i64, 1, pLeft->pVal->nType, &pRight->pVal->i64, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC);
} }
...@@ -280,12 +279,14 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, ...@@ -280,12 +279,14 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
tfree(pdata); tfree(pdata);
tfree(pLeftOutput); tfree(pLeftOutput);
tfree(pRightOutput); tfree(pRightOutput);
#endif
} }
static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) { static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) {
tbufWriteUint8(bw, expr->nodeType); tbufWriteUint8(bw, expr->nodeType);
if (expr->nodeType == TSQL_NODE_VALUE) { if (expr->nodeType == TEXPR_VALUE_NODE) {
SVariant* pVal = expr->pVal; SVariant* pVal = expr->pVal;
tbufWriteUint32(bw, pVal->nType); tbufWriteUint32(bw, pVal->nType);
...@@ -296,16 +297,15 @@ static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) { ...@@ -296,16 +297,15 @@ static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) {
tbufWriteInt64(bw, pVal->i64); tbufWriteInt64(bw, pVal->i64);
} }
} else if (expr->nodeType == TSQL_NODE_COL) { } else if (expr->nodeType == TEXPR_COL_NODE) {
SSchema* pSchema = expr->pSchema; SSchema* pSchema = expr->pSchema;
tbufWriteInt16(bw, pSchema->colId); tbufWriteInt16(bw, pSchema->colId);
tbufWriteInt16(bw, pSchema->bytes); tbufWriteInt16(bw, pSchema->bytes);
tbufWriteUint8(bw, pSchema->type); tbufWriteUint8(bw, pSchema->type);
tbufWriteString(bw, pSchema->name); tbufWriteString(bw, pSchema->name);
} else if (expr->nodeType == TSQL_NODE_EXPR) { } else if (expr->nodeType == TEXPR_BINARYEXPR_NODE) {
tbufWriteUint8(bw, expr->_node.optr); tbufWriteUint8(bw, expr->_node.optr);
tbufWriteUint8(bw, expr->_node.hasPK);
exprTreeToBinaryImpl(bw, expr->_node.pLeft); exprTreeToBinaryImpl(bw, expr->_node.pLeft);
exprTreeToBinaryImpl(bw, expr->_node.pRight); exprTreeToBinaryImpl(bw, expr->_node.pRight);
} }
...@@ -353,7 +353,7 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) { ...@@ -353,7 +353,7 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) {
CLEANUP_PUSH_VOID_PTR_PTR(true, tExprTreeDestroy, pExpr, NULL); CLEANUP_PUSH_VOID_PTR_PTR(true, tExprTreeDestroy, pExpr, NULL);
pExpr->nodeType = tbufReadUint8(br); pExpr->nodeType = tbufReadUint8(br);
if (pExpr->nodeType == TSQL_NODE_VALUE) { if (pExpr->nodeType == TEXPR_VALUE_NODE) {
SVariant* pVal = exception_calloc(1, sizeof(SVariant)); SVariant* pVal = exception_calloc(1, sizeof(SVariant));
pExpr->pVal = pVal; pExpr->pVal = pVal;
...@@ -366,7 +366,7 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) { ...@@ -366,7 +366,7 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) {
pVal->i64 = tbufReadInt64(br); pVal->i64 = tbufReadInt64(br);
} }
} else if (pExpr->nodeType == TSQL_NODE_COL) { } else if (pExpr->nodeType == TEXPR_COL_NODE) {
SSchema* pSchema = exception_calloc(1, sizeof(SSchema)); SSchema* pSchema = exception_calloc(1, sizeof(SSchema));
pExpr->pSchema = pSchema; pExpr->pSchema = pSchema;
...@@ -375,9 +375,8 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) { ...@@ -375,9 +375,8 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) {
pSchema->type = tbufReadUint8(br); pSchema->type = tbufReadUint8(br);
tbufReadToString(br, pSchema->name, TSDB_COL_NAME_LEN); tbufReadToString(br, pSchema->name, TSDB_COL_NAME_LEN);
} else if (pExpr->nodeType == TSQL_NODE_EXPR) { } else if (pExpr->nodeType == TEXPR_BINARYEXPR_NODE) {
pExpr->_node.optr = tbufReadUint8(br); pExpr->_node.optr = tbufReadUint8(br);
pExpr->_node.hasPK = tbufReadUint8(br);
pExpr->_node.pLeft = exprTreeFromBinaryImpl(br); pExpr->_node.pLeft = exprTreeFromBinaryImpl(br);
pExpr->_node.pRight = exprTreeFromBinaryImpl(br); pExpr->_node.pRight = exprTreeFromBinaryImpl(br);
assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL); assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL);
...@@ -406,12 +405,12 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { ...@@ -406,12 +405,12 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
tExprNode* expr = exception_calloc(1, sizeof(tExprNode)); tExprNode* expr = exception_calloc(1, sizeof(tExprNode));
CLEANUP_PUSH_VOID_PTR_PTR(true, tExprTreeDestroy, expr, NULL); CLEANUP_PUSH_VOID_PTR_PTR(true, tExprTreeDestroy, expr, NULL);
expr->nodeType = TSQL_NODE_EXPR; expr->nodeType = TEXPR_BINARYEXPR_NODE;
tExprNode* left = exception_calloc(1, sizeof(tExprNode)); tExprNode* left = exception_calloc(1, sizeof(tExprNode));
expr->_node.pLeft = left; expr->_node.pLeft = left;
left->nodeType = TSQL_NODE_COL; left->nodeType = TEXPR_COL_NODE;
SSchema* pSchema = exception_calloc(1, sizeof(SSchema)); SSchema* pSchema = exception_calloc(1, sizeof(SSchema));
left->pSchema = pSchema; left->pSchema = pSchema;
...@@ -421,7 +420,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { ...@@ -421,7 +420,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
expr->_node.pRight = right; expr->_node.pRight = right;
if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN) == 0) { if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN) == 0) {
right->nodeType = TSQL_NODE_VALUE; right->nodeType = TEXPR_VALUE_NODE;
expr->_node.optr = TSDB_RELATION_LIKE; expr->_node.optr = TSDB_RELATION_LIKE;
SVariant* pVal = exception_calloc(1, sizeof(SVariant)); SVariant* pVal = exception_calloc(1, sizeof(SVariant));
right->pVal = pVal; right->pVal = pVal;
...@@ -432,7 +431,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { ...@@ -432,7 +431,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
pVal->nLen = (int32_t)len; pVal->nLen = (int32_t)len;
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_MATCH, QUERY_COND_REL_PREFIX_MATCH_LEN) == 0) { } else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_MATCH, QUERY_COND_REL_PREFIX_MATCH_LEN) == 0) {
right->nodeType = TSQL_NODE_VALUE; right->nodeType = TEXPR_VALUE_NODE;
expr->_node.optr = TSDB_RELATION_MATCH; expr->_node.optr = TSDB_RELATION_MATCH;
SVariant* pVal = exception_calloc(1, sizeof(SVariant)); SVariant* pVal = exception_calloc(1, sizeof(SVariant));
right->pVal = pVal; right->pVal = pVal;
...@@ -442,7 +441,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { ...@@ -442,7 +441,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
pVal->nType = TSDB_DATA_TYPE_BINARY; pVal->nType = TSDB_DATA_TYPE_BINARY;
pVal->nLen = (int32_t)len; pVal->nLen = (int32_t)len;
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_NMATCH, QUERY_COND_REL_PREFIX_NMATCH_LEN) == 0) { } else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_NMATCH, QUERY_COND_REL_PREFIX_NMATCH_LEN) == 0) {
right->nodeType = TSQL_NODE_VALUE; right->nodeType = TEXPR_VALUE_NODE;
expr->_node.optr = TSDB_RELATION_NMATCH; expr->_node.optr = TSDB_RELATION_NMATCH;
SVariant* pVal = exception_calloc(1, sizeof(SVariant)); SVariant* pVal = exception_calloc(1, sizeof(SVariant));
right->pVal = pVal; right->pVal = pVal;
...@@ -452,7 +451,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { ...@@ -452,7 +451,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
pVal->nType = TSDB_DATA_TYPE_BINARY; pVal->nType = TSDB_DATA_TYPE_BINARY;
pVal->nLen = (int32_t)len; pVal->nLen = (int32_t)len;
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) { } else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) {
right->nodeType = TSQL_NODE_VALUE; right->nodeType = TEXPR_VALUE_NODE;
expr->_node.optr = TSDB_RELATION_IN; expr->_node.optr = TSDB_RELATION_IN;
SVariant* pVal = exception_calloc(1, sizeof(SVariant)); SVariant* pVal = exception_calloc(1, sizeof(SVariant));
right->pVal = pVal; right->pVal = pVal;
...@@ -706,18 +705,17 @@ tExprNode* exprdup(tExprNode* pNode) { ...@@ -706,18 +705,17 @@ tExprNode* exprdup(tExprNode* pNode) {
} }
tExprNode* pCloned = calloc(1, sizeof(tExprNode)); tExprNode* pCloned = calloc(1, sizeof(tExprNode));
if (pNode->nodeType == TSQL_NODE_EXPR) { if (pNode->nodeType == TEXPR_BINARYEXPR_NODE) {
tExprNode* pLeft = exprdup(pNode->_node.pLeft); tExprNode* pLeft = exprdup(pNode->_node.pLeft);
tExprNode* pRight = exprdup(pNode->_node.pRight); tExprNode* pRight = exprdup(pNode->_node.pRight);
pCloned->_node.pLeft = pLeft; pCloned->_node.pLeft = pLeft;
pCloned->_node.pRight = pRight; pCloned->_node.pRight = pRight;
pCloned->_node.optr = pNode->_node.optr; pCloned->_node.optr = pNode->_node.optr;
pCloned->_node.hasPK = pNode->_node.hasPK; } else if (pNode->nodeType == TEXPR_VALUE_NODE) {
} else if (pNode->nodeType == TSQL_NODE_VALUE) {
pCloned->pVal = calloc(1, sizeof(SVariant)); pCloned->pVal = calloc(1, sizeof(SVariant));
taosVariantAssign(pCloned->pVal, pNode->pVal); taosVariantAssign(pCloned->pVal, pNode->pVal);
} else if (pNode->nodeType == TSQL_NODE_COL) { } else if (pNode->nodeType == TEXPR_COL_NODE) {
pCloned->pSchema = calloc(1, sizeof(SSchema)); pCloned->pSchema = calloc(1, sizeof(SSchema));
*pCloned->pSchema = *pNode->pSchema; *pCloned->pSchema = *pNode->pSchema;
} }
......
...@@ -35,6 +35,14 @@ int32_t qIsBuiltinFunction(const char* name, int32_t len) { ...@@ -35,6 +35,14 @@ int32_t qIsBuiltinFunction(const char* name, int32_t len) {
} }
} }
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId) {
return true;
}
const char* qGetFunctionName(int32_t functionId) {
}
bool isTagsQuery(SArray* pFunctionIdList) { bool isTagsQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) { for (int32_t i = 0; i < num; ++i) {
......
...@@ -233,7 +233,7 @@ typedef struct tSqlExpr { ...@@ -233,7 +233,7 @@ typedef struct tSqlExpr {
// The complete string of the function(col, param), and the function name is kept in exprToken // The complete string of the function(col, param), and the function name is kept in exprToken
struct { struct {
SToken operand; SToken operand;
struct SArray *paramList; // function parameters list struct SArray *paramList; // function parameters list
} Expr; } Expr;
SToken columnName; // table column info SToken columnName; // table column info
......
...@@ -29,6 +29,7 @@ struct SSqlNode; ...@@ -29,6 +29,7 @@ struct SSqlNode;
typedef struct SColumnIndex { typedef struct SColumnIndex {
int16_t tableIndex; int16_t tableIndex;
int16_t columnIndex; int16_t columnIndex;
int16_t type; // normal column/tag/ user input constant column
} SColumnIndex; } SColumnIndex;
typedef struct SInsertStmtInfo { typedef struct SInsertStmtInfo {
...@@ -42,26 +43,15 @@ typedef struct SInsertStmtInfo { ...@@ -42,26 +43,15 @@ typedef struct SInsertStmtInfo {
// the structure for sql function in select clause // the structure for sql function in select clause
typedef struct SSqlExpr { typedef struct SSqlExpr {
char aliasName[TSDB_COL_NAME_LEN]; // as aliasName
char token[TSDB_COL_NAME_LEN]; // original token char token[TSDB_COL_NAME_LEN]; // original token
SSchema resSchema;
SColIndex colInfo; SColIndex colInfo;
uint64_t uid; // table uid, todo refactor use the pointer uint64_t uid; // table uid, todo refactor use the pointer
int16_t functionId; // function id in aAgg array
int16_t resType; // return value type
int16_t resBytes; // length of return value
int32_t interBytes; // inter result buffer size int32_t interBytes; // inter result buffer size
// int16_t colType; // table column type
int16_t colType; // table column type // int16_t colBytes; // table column bytes
int16_t colBytes; // table column bytes
int16_t numOfParams; // argument value of each function int16_t numOfParams; // argument value of each function
SVariant param[3]; // parameters are not more than 3 SVariant param[3]; // parameters are not more than 3
int32_t offset; // sub result column value of arithmetic expression.
int16_t resColId; // result column id
SColumnFilterList flist;
} SSqlExpr; } SSqlExpr;
typedef struct SExprInfo { typedef struct SExprInfo {
...@@ -81,6 +71,11 @@ typedef struct SInternalField { ...@@ -81,6 +71,11 @@ typedef struct SInternalField {
SExprInfo *pExpr; SExprInfo *pExpr;
} SInternalField; } SInternalField;
typedef struct SMsgBuf {
int32_t len;
char *buf;
} SMsgBuf;
void clearTableMetaInfo(STableMetaInfo* pTableMetaInfo); void clearTableMetaInfo(STableMetaInfo* pTableMetaInfo);
void clearAllTableMetaInfo(SQueryStmtInfo* pQueryInfo, bool removeMeta, uint64_t id); void clearAllTableMetaInfo(SQueryStmtInfo* pQueryInfo, bool removeMeta, uint64_t id);
...@@ -104,7 +99,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ ...@@ -104,7 +99,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ
* @param msgBufLen * @param msgBufLen
* @return * @return
*/ */
int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, char* msg, int32_t msgBufLen); int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf);
/** /**
* Extract request meta info from the sql statement * Extract request meta info from the sql statement
......
...@@ -22,6 +22,7 @@ extern "C" { ...@@ -22,6 +22,7 @@ extern "C" {
#include "os.h" #include "os.h"
#include "ttoken.h" #include "ttoken.h"
#include "parserInt.h"
#define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \ #define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_SUPER_TABLE)) (((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_SUPER_TABLE))
...@@ -35,16 +36,27 @@ extern "C" { ...@@ -35,16 +36,27 @@ extern "C" {
#define UTIL_TABLE_IS_TMP_TABLE(metaInfo) \ #define UTIL_TABLE_IS_TMP_TABLE(metaInfo) \
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE)) (((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
TAOS_FIELD createField(const SSchema* pSchema);
void setSchemaVal(SSchema* pSchema, uint8_t type, int16_t bytes, int16_t colId, const char* name);
SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* field);
int32_t getNumOfFields(SFieldInfo* pFieldInfo);
SInternalField* getInternalField(SFieldInfo* pFieldInfo, int32_t index);
int32_t parserValidateIdToken(SToken* pToken); int32_t parserValidateIdToken(SToken* pToken);
int32_t buildInvalidOperationMsg(char* dst, int32_t dstBufLen, const char* msg); int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
int32_t parserSetSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr); int32_t parserSetSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr);
int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
void columnListCopy(SArray* dst, const SArray* src, uint64_t tableUid); void columnListCopy(SArray* dst, const SArray* src, uint64_t tableUid);
void columnListCopyAll(SArray* dst, const SArray* src); void columnListCopyAll(SArray* dst, const SArray* src);
void columnListDestroy(SArray* pColumnList); void columnListDestroy(SArray* pColumnList);
SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid);
void cleanupTagCond(STagCond* pTagCond); void cleanupTagCond(STagCond* pTagCond);
void cleanupColumnCond(SArray** pCond); void cleanupColumnCond(SArray** pCond);
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef TDENGINE_QUERYINFOUTIL_H #ifndef TDENGINE_QUERYINFOUTIL_H
#define TDENGINE_QUERYINFOUTIL_H #define TDENGINE_QUERYINFOUTIL_H
...@@ -31,8 +30,8 @@ SSchema *getTableTagSchema(const STableMeta* pTableMeta); ...@@ -31,8 +30,8 @@ SSchema *getTableTagSchema(const STableMeta* pTableMeta);
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex); SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo); size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex,
int16_t size, int16_t resColId, int16_t interSize, int32_t colType); SSchema* pResSchema, int16_t interSize);
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo); void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo);
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize); void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
void assignExprInfo(SExprInfo* dst, const SExprInfo* src); void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
...@@ -40,6 +39,8 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src); ...@@ -40,6 +39,8 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index); SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index);
int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy); int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy);
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
void cleanupFieldInfo(SFieldInfo* pFieldInfo); void cleanupFieldInfo(SFieldInfo* pFieldInfo);
STableComInfo getTableInfo(const STableMeta* pTableMeta); STableComInfo getTableInfo(const STableMeta* pTableMeta);
......
...@@ -13,10 +13,16 @@ ...@@ -13,10 +13,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "ttime.h" #include <function.h>
#include "astGenerator.h"
#include "function.h"
#include "parserInt.h" #include "parserInt.h"
#include "parserUtil.h" #include "parserUtil.h"
#include "queryInfoUtil.h" #include "queryInfoUtil.h"
#include "tbuffer.h"
#include "tglobal.h"
#include "tmsgtype.h"
#include "ttime.h"
#define TSQL_TBNAME_L "tbname" #define TSQL_TBNAME_L "tbname"
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0" #define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
...@@ -26,13 +32,28 @@ ...@@ -26,13 +32,28 @@
#define COLUMN_INDEX_INITIAL_VAL (-2) #define COLUMN_INDEX_INITIAL_VAL (-2)
#define COLUMN_INDEX_INITIALIZER { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL } #define COLUMN_INDEX_INITIALIZER { COLUMN_INDEX_INITIAL_VAL, COLUMN_INDEX_INITIAL_VAL }
static int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool joinQuery, bool timeWindowQuery, bool outerQuery, char* msg, int32_t msgBufLen); static int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool outerQuery, SMsgBuf* pMsgBuf);
void getColumnName(tSqlExprItem* pItem, char* resColumnName, char* rawName, int32_t nameLength) {
memset(resColumnName, 0, nameLength);
int32_t len = ((int32_t)pItem->pNode->exprToken.n < nameLength) ? (int32_t)pItem->pNode->exprToken.n : nameLength;
strncpy(rawName, pItem->pNode->exprToken.z, len);
if (pItem->aliasName != NULL) {
int32_t aliasNameLen = (int32_t) strlen(pItem->aliasName);
len = (aliasNameLen < nameLength)? aliasNameLen:nameLength;
strncpy(resColumnName, pItem->aliasName, len);
} else {
strncpy(resColumnName, rawName, len);
}
}
size_t tscNumOfExprs(SQueryStmtInfo* pQueryInfo) { size_t tscNumOfExprs(SQueryStmtInfo* pQueryInfo) {
return taosArrayGetSize(pQueryInfo->exprList); return taosArrayGetSize(pQueryInfo->exprList);
} }
static int32_t evaluateImpl(tSqlExpr* pExpr, int32_t tsPrecision) { static int32_t evaluateImpl(tSqlExpr* pExpr, int32_t tsPrecision) {
int32_t code = 0; int32_t code = 0;
if (pExpr->type == SQL_NODE_EXPR) { if (pExpr->type == SQL_NODE_EXPR) {
code = evaluateImpl(pExpr->pLeft, tsPrecision); code = evaluateImpl(pExpr->pLeft, tsPrecision);
...@@ -171,22 +192,8 @@ void clearTableMetaInfo(STableMetaInfo* pTableMetaInfo) { ...@@ -171,22 +192,8 @@ void clearTableMetaInfo(STableMetaInfo* pTableMetaInfo) {
free(pTableMetaInfo); free(pTableMetaInfo);
} }
void clearAllTableMetaInfo(SQueryStmtInfo* pQueryInfo, bool removeMeta, uint64_t id) {
for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, i);
if (removeMeta) {
// todo
// removeCachedTableMeta(pTableMetaInfo, id);
}
clearTableMetaInfo(pTableMetaInfo);
}
tfree(pQueryInfo->pTableMetaInfo);
}
static STableMeta* extractTempTableMetaFromSubquery(SQueryStmtInfo* pUpstream) { static STableMeta* extractTempTableMetaFromSubquery(SQueryStmtInfo* pUpstream) {
STableMetaInfo* pUpstreamTableMetaInfo /*= tscGetMetaInfo(pUpstream, 0)*/; STableMetaInfo* pUpstreamTableMetaInfo /*= getMetaInfo(pUpstream, 0)*/;
int32_t numOfColumns = pUpstream->fieldsInfo.numOfOutput; int32_t numOfColumns = pUpstream->fieldsInfo.numOfOutput;
STableMeta *meta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * numOfColumns); STableMeta *meta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * numOfColumns);
...@@ -236,73 +243,17 @@ void initQueryInfo(SQueryStmtInfo* pQueryInfo) { ...@@ -236,73 +243,17 @@ void initQueryInfo(SQueryStmtInfo* pQueryInfo) {
pQueryInfo->slimit.offset = 0; pQueryInfo->slimit.offset = 0;
pQueryInfo->pUpstream = taosArrayInit(4, POINTER_BYTES); pQueryInfo->pUpstream = taosArrayInit(4, POINTER_BYTES);
pQueryInfo->window = TSWINDOW_INITIALIZER; pQueryInfo->window = TSWINDOW_INITIALIZER;
// pQueryInfo->multigroupResult = true;
} }
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* msg, int32_t msgBufLen); int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
SColumn* tscColumnListInsert(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;
}
size_t numOfCols = taosArrayGetSize(pColumnList);
int32_t i = 0;
while (i < numOfCols) {
SColumn* pCol = taosArrayGetP(pColumnList, i);
if (pCol->columnIndex < columnIndex) {
i++;
} else if (pCol->tableUid < uid) {
i++;
} else {
break;
}
}
if (i >= numOfCols || numOfCols == 0) {
SColumn* b = calloc(1, sizeof(SColumn));
if (b == NULL) {
return NULL;
}
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);
if (i < numOfCols && (pCol->columnIndex > columnIndex || pCol->tableUid != uid)) {
SColumn* b = calloc(1, sizeof(SColumn));
if (b == NULL) {
return NULL;
}
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);
}
}
return taosArrayGetP(pColumnList, i);
}
static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtInfo* pQueryInfo, char* msgBuf, int32_t msgBufLen) { static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index); SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index);
// union all is not support currently // union all is not support currently
SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0); SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0);
if (taosArrayGetSize(subInfo->pSubquery) >= 2) { if (taosArrayGetSize(subInfo->pSubquery) >= 2) {
return buildInvalidOperationMsg(msgBuf, msgBufLen, "not support union in subquery"); return buildInvalidOperationMsg(pMsgBuf, "not support union in subquery");
} }
SQueryStmtInfo* pSub = calloc(1, sizeof(SQueryStmtInfo)); SQueryStmtInfo* pSub = calloc(1, sizeof(SQueryStmtInfo));
...@@ -315,7 +266,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI ...@@ -315,7 +266,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI
pSub->pUdfInfo = pUdfInfo; pSub->pUdfInfo = pUdfInfo;
pSub->pDownstream = pQueryInfo; pSub->pDownstream = pQueryInfo;
int32_t code = validateSqlNode(p, pSub, msgBuf, msgBufLen); int32_t code = validateSqlNode(p, pSub, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
...@@ -331,7 +282,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI ...@@ -331,7 +282,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI
if (subInfo->aliasName.n > 0) { if (subInfo->aliasName.n > 0) {
if (subInfo->aliasName.n >= TSDB_TABLE_FNAME_LEN) { if (subInfo->aliasName.n >= TSDB_TABLE_FNAME_LEN) {
tfree(pTableMetaInfo1); tfree(pTableMetaInfo1);
return buildInvalidOperationMsg(msgBuf, msgBufLen, "subquery alias name too long"); return buildInvalidOperationMsg(pMsgBuf, "subquery alias name too long");
} }
tstrncpy(pTableMetaInfo1->aliasName, subInfo->aliasName.z, subInfo->aliasName.n + 1); tstrncpy(pTableMetaInfo1->aliasName, subInfo->aliasName.z, subInfo->aliasName.n + 1);
...@@ -358,179 +309,12 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI ...@@ -358,179 +309,12 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI
int32_t startOffset = (int32_t) taosArrayGetSize(pQueryInfo->colList); int32_t startOffset = (int32_t) taosArrayGetSize(pQueryInfo->colList);
for(int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) { for(int32_t i = 0; i < pMeta->tableInfo.numOfColumns; ++i) {
tscColumnListInsert(pQueryInfo->colList, i + startOffset, pMeta->uid, &pMeta->schema[i]); columnListInsert(pQueryInfo->colList, i + startOffset, pMeta->uid, &pMeta->schema[i]);
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *vgroupList) {
if (vgroupList == NULL) {
return NULL;
}
size_t size = sizeof(SVgroupsInfo) + sizeof(SVgroupMsg) * vgroupList->numOfVgroups;
SVgroupsInfo* pNew = malloc(size);
if (pNew == NULL) {
return NULL;
}
pNew->numOfVgroups = vgroupList->numOfVgroups;
for(int32_t i = 0; i < vgroupList->numOfVgroups; ++i) {
SVgroupMsg* pNewVInfo = &pNew->vgroups[i];
SVgroupMsg* pvInfo = &vgroupList->vgroups[i];
pNewVInfo->vgId = pvInfo->vgId;
pNewVInfo->numOfEps = pvInfo->numOfEps;
for(int32_t j = 0; j < pvInfo->numOfEps; ++j) {
pNewVInfo->epAddr[j].port = pvInfo->epAddr[j].port;
tstrncpy(pNewVInfo->epAddr[j].fqdn, pvInfo->epAddr[j].fqdn, TSDB_FQDN_LEN);
}
}
return pNew;
}
void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo) {
memset(info, 0, sizeof(SVgroupTableInfo));
info->vgInfo = pInfo->vgInfo;
if (pInfo->itemList) {
info->itemList = taosArrayDup(pInfo->itemList);
}
}
SArray* tscVgroupTableInfoDup(SArray* pVgroupTables) {
if (pVgroupTables == NULL) {
return NULL;
}
size_t num = taosArrayGetSize(pVgroupTables);
SArray* pa = taosArrayInit(num, sizeof(SVgroupTableInfo));
SVgroupTableInfo info;
for (size_t i = 0; i < num; i++) {
SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTables, i);
tscVgroupTableCopy(&info, pInfo);
taosArrayPush(pa, &info);
}
return pa;
}
SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFilters) {
if (numOfFilters == 0 || src == NULL) {
assert(src == NULL);
return NULL;
}
SColumnFilterInfo* pFilter = calloc(1, numOfFilters * sizeof(SColumnFilterInfo));
memcpy(pFilter, src, sizeof(SColumnFilterInfo) * numOfFilters);
for (int32_t j = 0; j < numOfFilters; ++j) {
if (pFilter[j].filterstr) {
size_t len = (size_t) pFilter[j].len + 1 * TSDB_NCHAR_SIZE;
pFilter[j].pz = (int64_t) calloc(1, len);
memcpy((char*)pFilter[j].pz, (char*)src[j].pz, (size_t) pFilter[j].len);
}
}
assert(src->filterstr == 0 || src->filterstr == 1);
assert(!(src->lowerRelOptr == TSDB_RELATION_INVALID && src->upperRelOptr == TSDB_RELATION_INVALID));
return pFilter;
}
void tscColumnCopy(SColumn* pDest, const SColumn* pSrc) {
destroyFilterInfo(&pDest->info.flist);
pDest->columnIndex = pSrc->columnIndex;
pDest->tableUid = pSrc->tableUid;
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;
pDest->info.colId = pSrc->info.colId;
pDest->info.bytes = pSrc->info.bytes;
}
SColumn* tscColumnClone(const SColumn* src) {
assert(src != NULL);
SColumn* dst = calloc(1, sizeof(SColumn));
if (dst == NULL) {
return NULL;
}
tscColumnCopy(dst, src);
return dst;
}
void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid) {
assert(src != NULL && dst != NULL);
size_t num = taosArrayGetSize(src);
for (int32_t i = 0; i < num; ++i) {
SColumn* pCol = taosArrayGetP(src, i);
if (pCol->tableUid == tableUid) {
SColumn* p = tscColumnClone(pCol);
taosArrayPush(dst, &p);
}
}
}
STableMetaInfo* tscAddTableMetaInfo(SQueryStmtInfo* pQueryInfo, char* name, STableMeta* pTableMeta,
SVgroupsInfo* vgroupList, SArray* pTagCols, SArray* pVgroupTables) {
void* tmp = realloc(pQueryInfo->pTableMetaInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES);
if (tmp == NULL) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
return NULL;
}
pQueryInfo->pTableMetaInfo = tmp;
STableMetaInfo* pTableMetaInfo = calloc(1, sizeof(STableMetaInfo));
if (pTableMetaInfo == NULL) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
return NULL;
}
pQueryInfo->pTableMetaInfo[pQueryInfo->numOfTables] = pTableMetaInfo;
if (name != NULL) {
tNameAssign(&pTableMetaInfo->name, name);
}
pTableMetaInfo->pTableMeta = pTableMeta;
// pTableMetaInfo->tableMetaSize = (pTableMetaInfo->pTableMeta == NULL)? 0:tscGetTableMetaSize(pTableMeta);
// pTableMetaInfo->tableMetaCapacity = (size_t)(pTableMetaInfo->tableMetaSize);
if (vgroupList != NULL) {
pTableMetaInfo->vgroupList = tscVgroupInfoClone(vgroupList);
}
// TODO handle malloc failure
pTableMetaInfo->tagColList = taosArrayInit(4, POINTER_BYTES);
if (pTableMetaInfo->tagColList == NULL) {
return NULL;
}
if (pTagCols != NULL && pTableMetaInfo->pTableMeta != NULL) {
tscColumnListCopy(pTableMetaInfo->tagColList, pTagCols, pTableMetaInfo->pTableMeta->uid);
}
pQueryInfo->numOfTables += 1;
return pTableMetaInfo;
}
STableMetaInfo* tscAddEmptyMetaInfo(SQueryStmtInfo* pQueryInfo) {
return tscAddTableMetaInfo(pQueryInfo, NULL, NULL, NULL, NULL, NULL);
}
int32_t getTableIndexImpl(SToken* pTableToken, SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex) { int32_t getTableIndexImpl(SToken* pTableToken, SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex) {
if (pTableToken->n == 0) { // only one table and no table name prefix in column name if (pTableToken->n == 0) { // only one table and no table name prefix in column name
if (pQueryInfo->numOfTables == 1) { if (pQueryInfo->numOfTables == 1) {
...@@ -544,25 +328,17 @@ int32_t getTableIndexImpl(SToken* pTableToken, SQueryStmtInfo* pQueryInfo, SColu ...@@ -544,25 +328,17 @@ int32_t getTableIndexImpl(SToken* pTableToken, SQueryStmtInfo* pQueryInfo, SColu
pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL; pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL;
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo* pTableMetaInfo /*= tscGetMetaInfo(pQueryInfo, i)*/; STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, i);
char* name = pTableMetaInfo->aliasName; char* name = pTableMetaInfo->aliasName;
if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) { if (strncasecmp(name, pTableToken->z, pTableToken->n) == 0 && strlen(name) == pTableToken->n) {
pIndex->tableIndex = i; pIndex->tableIndex = i;
break; return TSDB_CODE_SUCCESS;
} }
} }
if (pIndex->tableIndex < 0) { return TSDB_CODE_TSC_INVALID_OPERATION;
return TSDB_CODE_TSC_INVALID_OPERATION;
}
return TSDB_CODE_SUCCESS;
} }
/*
* tablePrefix.columnName
* extract table name and save it in pTable, with only column name in pToken
*/
void extractTableNameFromToken(SToken* pToken, SToken* pTable) { void extractTableNameFromToken(SToken* pToken, SToken* pTable) {
const char sep = TS_PATH_DELIMITER[0]; const char sep = TS_PATH_DELIMITER[0];
...@@ -593,7 +369,7 @@ int32_t getTableIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColumnI ...@@ -593,7 +369,7 @@ int32_t getTableIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColumnI
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int16_t doGetColumnIndex(SQueryStmtInfo* pQueryInfo, int32_t index, SToken* pToken) { static int16_t doGetColumnIndex(SQueryStmtInfo* pQueryInfo, int32_t index, const SToken* pToken, int16_t* type) {
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index)->pTableMeta; STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index)->pTableMeta;
int32_t numOfCols = getNumOfColumns(pTableMeta) + getNumOfTags(pTableMeta); int32_t numOfCols = getNumOfColumns(pTableMeta) + getNumOfTags(pTableMeta);
...@@ -612,6 +388,7 @@ static int16_t doGetColumnIndex(SQueryStmtInfo* pQueryInfo, int32_t index, SToke ...@@ -612,6 +388,7 @@ static int16_t doGetColumnIndex(SQueryStmtInfo* pQueryInfo, int32_t index, SToke
} }
} }
*type = (columnIndex >= getNumOfColumns(pTableMeta))? TSDB_COL_TAG:TSDB_COL_NORMAL;
return columnIndex; return columnIndex;
} }
...@@ -623,12 +400,15 @@ static bool isTablenameToken(SToken* token) { ...@@ -623,12 +400,15 @@ static bool isTablenameToken(SToken* token) {
return (tmpToken.n == strlen(TSQL_TBNAME_L) && strncasecmp(TSQL_TBNAME_L, tmpToken.z, tmpToken.n) == 0); return (tmpToken.n == strlen(TSQL_TBNAME_L) && strncasecmp(TSQL_TBNAME_L, tmpToken.z, tmpToken.n) == 0);
} }
int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, char* msg, int32_t msgBufLen) { int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, SMsgBuf* pMsgBuf) {
const char* msg0 = "ambiguous column name"; const char* msg0 = "ambiguous column name";
const char* msg1 = "invalid column name"; const char* msg1 = "invalid column name";
pIndex->type = TSDB_COL_NORMAL;
if (isTablenameToken(pToken)) { if (isTablenameToken(pToken)) {
pIndex->columnIndex = TSDB_TBNAME_COLUMN_INDEX; pIndex->columnIndex = TSDB_TBNAME_COLUMN_INDEX;
pIndex->type = TSDB_COL_TAG;
} else if (strlen(DEFAULT_PRIMARY_TIMESTAMP_COL_NAME) == pToken->n && } else if (strlen(DEFAULT_PRIMARY_TIMESTAMP_COL_NAME) == pToken->n &&
strncasecmp(pToken->z, DEFAULT_PRIMARY_TIMESTAMP_COL_NAME, pToken->n) == 0) { strncasecmp(pToken->z, DEFAULT_PRIMARY_TIMESTAMP_COL_NAME, pToken->n) == 0) {
pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX; // just make runtime happy, need fix java test case InsertSpecialCharacterJniTest pIndex->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX; // just make runtime happy, need fix java test case InsertSpecialCharacterJniTest
...@@ -638,11 +418,11 @@ int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColu ...@@ -638,11 +418,11 @@ int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColu
// not specify the table name, try to locate the table index by column name // not specify the table name, try to locate the table index by column name
if (pIndex->tableIndex == COLUMN_INDEX_INITIAL_VAL) { if (pIndex->tableIndex == COLUMN_INDEX_INITIAL_VAL) {
for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) { for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) {
int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken); int16_t colIndex = doGetColumnIndex(pQueryInfo, i, pToken, &pIndex->type);
if (colIndex != COLUMN_INDEX_INITIAL_VAL) { if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) { if (pIndex->columnIndex != COLUMN_INDEX_INITIAL_VAL) {
return buildInvalidOperationMsg(msg, msgBufLen, msg0); return buildInvalidOperationMsg(pMsgBuf, msg0);
} else { } else {
pIndex->tableIndex = i; pIndex->tableIndex = i;
pIndex->columnIndex = colIndex; pIndex->columnIndex = colIndex;
...@@ -650,14 +430,11 @@ int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColu ...@@ -650,14 +430,11 @@ int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColu
} }
} }
} else { // table index is valid, get the column index } else { // table index is valid, get the column index
int16_t colIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken); pIndex->columnIndex = doGetColumnIndex(pQueryInfo, pIndex->tableIndex, pToken, &pIndex->type);
if (colIndex != COLUMN_INDEX_INITIAL_VAL) {
pIndex->columnIndex = colIndex;
}
} }
if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) { if (pIndex->columnIndex == COLUMN_INDEX_INITIAL_VAL) {
return buildInvalidOperationMsg(msg, msgBufLen, msg1); return buildInvalidOperationMsg(pMsgBuf, msg1);
} }
} }
...@@ -668,21 +445,20 @@ int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColu ...@@ -668,21 +445,20 @@ int32_t doGetColumnIndexByName(SToken* pToken, SQueryStmtInfo* pQueryInfo, SColu
} }
} }
int32_t getColumnIndexByName(const SToken* pToken, SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, char* msg, int32_t msgBufLen) { int32_t getColumnIndexByName(const SToken* pToken, SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, SMsgBuf* pMsgBuf) {
if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) { if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
SToken tmpToken = *pToken; SToken tmpToken = *pToken;
if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) { if (getTableIndexByName(&tmpToken, pQueryInfo, pIndex) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
return doGetColumnIndexByName(&tmpToken, pQueryInfo, pIndex, msg, msgBufLen); return doGetColumnIndexByName(&tmpToken, pQueryInfo, pIndex, pMsgBuf);
} }
int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg, int32_t msgBufLen) { int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf* pMsgBuf) {
const char* msg1 = "too many columns in group by clause"; const char* msg1 = "too many columns in group by clause";
const char* msg2 = "invalid column name in group by clause"; const char* msg2 = "invalid column name in group by clause";
const char* msg3 = "columns from one table allowed as group by columns"; const char* msg3 = "columns from one table allowed as group by columns";
...@@ -699,7 +475,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg ...@@ -699,7 +475,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg
} }
if (pQueryInfo->numOfTables > 1) { if (pQueryInfo->numOfTables > 1) {
return buildInvalidOperationMsg(msg, msgBufLen, msg4); return buildInvalidOperationMsg(pMsgBuf, msg4);
} }
SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr; SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
...@@ -717,7 +493,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg ...@@ -717,7 +493,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg
int32_t numOfGroupCols = (int16_t) taosArrayGetSize(pList); int32_t numOfGroupCols = (int16_t) taosArrayGetSize(pList);
if (numOfGroupCols > TSDB_MAX_TAGS) { if (numOfGroupCols > TSDB_MAX_TAGS) {
return buildInvalidOperationMsg(msg, msgBufLen, msg1); return buildInvalidOperationMsg(pMsgBuf, msg1);
} }
SSchema *pSchema = NULL; SSchema *pSchema = NULL;
...@@ -731,14 +507,14 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg ...@@ -731,14 +507,14 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg
SToken token = {pVar->nLen, pVar->nType, pVar->pz}; SToken token = {pVar->nLen, pVar->nType, pVar->pz};
SColumnIndex index = COLUMN_INDEX_INITIALIZER; SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&token, pQueryInfo, &index, msg, msgBufLen) != TSDB_CODE_SUCCESS) { if (getColumnIndexByName(&token, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(msg, msgBufLen, msg2); return buildInvalidOperationMsg(pMsgBuf, msg2);
} }
if (tableIndex == COLUMN_INDEX_INITIAL_VAL) { if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
tableIndex = index.tableIndex; tableIndex = index.tableIndex;
} else if (tableIndex != index.tableIndex) { } else if (tableIndex != index.tableIndex) {
return buildInvalidOperationMsg(msg, msgBufLen, msg3); return buildInvalidOperationMsg(pMsgBuf, msg3);
} }
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
...@@ -755,7 +531,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg ...@@ -755,7 +531,7 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg
if (groupTag) { if (groupTag) {
if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
return buildInvalidOperationMsg(msg, msgBufLen, msg6); return buildInvalidOperationMsg(pMsgBuf, msg6);
} }
int32_t relIndex = index.columnIndex; int32_t relIndex = index.columnIndex;
...@@ -768,14 +544,14 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg ...@@ -768,14 +544,14 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg
taosArrayPush(pGroupExpr->columnInfo, &colIndex); taosArrayPush(pGroupExpr->columnInfo, &colIndex);
index.columnIndex = relIndex; index.columnIndex = relIndex;
tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->uid, pSchema); columnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->uid, pSchema);
} else { } else {
// check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
return buildInvalidOperationMsg(msg, msgBufLen, msg5); return buildInvalidOperationMsg(pMsgBuf, msg5);
} }
tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->uid, pSchema); columnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->uid, pSchema);
SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name)); strncpy(colIndex.name, pSchema->name, tListLen(colIndex.name));
...@@ -789,13 +565,13 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg ...@@ -789,13 +565,13 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg
// 1. only one normal column allowed in the group by clause // 1. only one normal column allowed in the group by clause
// 2. the normal column in the group by clause can only located in the end position // 2. the normal column in the group by clause can only located in the end position
if (numOfGroupCols > 1) { if (numOfGroupCols > 1) {
return buildInvalidOperationMsg(msg, msgBufLen, msg7); return buildInvalidOperationMsg(pMsgBuf, msg7);
} }
for(int32_t i = 0; i < num; ++i) { for(int32_t i = 0; i < num; ++i) {
SColIndex* pIndex = taosArrayGet(pGroupExpr->columnInfo, i); SColIndex* pIndex = taosArrayGet(pGroupExpr->columnInfo, i);
if (TSDB_COL_IS_NORMAL_COL(pIndex->flag) && i != num - 1) { if (TSDB_COL_IS_NORMAL_COL(pIndex->flag) && i != num - 1) {
return buildInvalidOperationMsg(msg, msgBufLen, msg8); return buildInvalidOperationMsg(pMsgBuf, msg8);
} }
} }
...@@ -803,7 +579,69 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg ...@@ -803,7 +579,69 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, char* msg
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* msg, int32_t msgBufLen) { int32_t filterUnsupportedQueryFunction(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
// todo NOT support yet
const char* msg6 = "not support stddev/percentile/interp in the outer query yet";
const char* msg9 = "not support 3 level select";
for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) {
SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
assert(pExpr->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
int32_t f = pExpr->pExpr->_node.functionId;
if (f == FUNCTION_STDDEV || f == FUNCTION_PERCT || f == FUNCTION_INTERP) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
if (f == FUNCTION_BLKINFO && taosArrayGetSize(pQueryInfo->pUpstream) > 0) {
return buildInvalidOperationMsg(pMsgBuf, msg9);
}
if (/*(timeWindowQuery || pQueryInfo->stateWindow) &&*/ f == FUNCTION_LAST) {
pExpr->base.numOfParams = 1;
pExpr->base.param[0].i64 = TSDB_ORDER_ASC;
pExpr->base.param[0].nType = TSDB_DATA_TYPE_INT;
}
}
}
int32_t validateWhereNode(SQueryStmtInfo *pQueryInfo, tSqlExpr* pWhereExpr, SMsgBuf* pMsgBuf) {
return 0;
}
// validate the interval info
int32_t validateIntervalNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
return 0;
}
int32_t validateSessionNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
return 0;
}
// parse the window_state
int32_t validateStateWindowNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
return 0;
}
// parse the having clause in the first place
int32_t validateHavingNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
return 0;
}
int32_t validateLimitNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
return 0;
}
// set order by info
int32_t validateOrderbyNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
return 0;
}
int32_t validateFillNode(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, SMsgBuf* pMsgBuf) {
return 0;
}
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
assert(pSqlNode != NULL && (pSqlNode->from == NULL || taosArrayGetSize(pSqlNode->from->list) > 0)); assert(pSqlNode != NULL && (pSqlNode->from == NULL || taosArrayGetSize(pSqlNode->from->list) > 0));
const char* msg1 = "point interpolation query needs timestamp"; const char* msg1 = "point interpolation query needs timestamp";
...@@ -811,14 +649,11 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -811,14 +649,11 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
const char* msg3 = "start(end) time of query range required or time range too large"; const char* msg3 = "start(end) time of query range required or time range too large";
const char* msg4 = "interval query not supported, since the result of sub query not include valid timestamp column"; const char* msg4 = "interval query not supported, since the result of sub query not include valid timestamp column";
const char* msg5 = "only tag query not compatible with normal column filter"; const char* msg5 = "only tag query not compatible with normal column filter";
const char* msg6 = "not support stddev/percentile/interp in the outer query yet";
const char* msg7 = "derivative/twa/irate requires timestamp column exists in subquery"; const char* msg7 = "derivative/twa/irate requires timestamp column exists in subquery";
const char* msg8 = "condition missing for join query"; const char* msg8 = "condition missing for join query";
const char* msg9 = "not support 3 level select";
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
STableMetaInfo *pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo); STableMetaInfo *pTableMetaInfo = addEmptyMetaInfo(pQueryInfo);
/* /*
* handle the sql expression without from subclause * handle the sql expression without from subclause
...@@ -840,14 +675,8 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -840,14 +675,8 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
// parse the subquery in the first place // parse the subquery in the first place
int32_t numOfSub = (int32_t)taosArrayGetSize(pSqlNode->from->list); int32_t numOfSub = (int32_t)taosArrayGetSize(pSqlNode->from->list);
for (int32_t i = 0; i < numOfSub; ++i) { for (int32_t i = 0; i < numOfSub; ++i) {
// check if there is 3 level select
SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, i); SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, i);
SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0); code = doValidateSubquery(pSqlNode, i, pQueryInfo, pMsgBuf);
if (p->from->type == SQL_NODE_FROM_SUBQUERY) {
return buildInvalidOperationMsg(msg, msgBufLen, msg9);
}
code = doValidateSubquery(pSqlNode, i, pQueryInfo, msg, msgBufLen);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
...@@ -858,30 +687,16 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -858,30 +687,16 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
// TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY); // TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY);
// parse the group by clause in the first place // parse the group by clause in the first place
if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, msg, msgBufLen) != TSDB_CODE_SUCCESS) { if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, true, pMsgBuf) !=
if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, false, timeWindowQuery, true, msg, msgBufLen) !=
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
// todo NOT support yet code = filterUnsupportedQueryFunction(pQueryInfo, pMsgBuf);
for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) {
SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
int32_t f = pExpr->base.functionId;
if (f == TSDB_FUNC_STDDEV || f == TSDB_FUNC_PERCT || f == TSDB_FUNC_INTERP) {
return buildInvalidOperationMsg(msg, msgBufLen, msg6);
}
if ((timeWindowQuery || pQueryInfo->stateWindow) && f == TSDB_FUNC_LAST) {
pExpr->base.numOfParams = 1;
pExpr->base.param[0].i64 = TSDB_ORDER_ASC;
pExpr->base.param[0].nType = TSDB_DATA_TYPE_INT;
}
}
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, 0)->pTableMeta; STableMeta* pTableMeta = getMetaInfo(pQueryInfo, 0)->pTableMeta;
SSchema* pSchema = getOneColumnSchema(pTableMeta, 0); SSchema* pSchema = getOneColumnSchema(pTableMeta, 0);
...@@ -892,83 +707,83 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -892,83 +707,83 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
for (int32_t i = 0; i < numOfExprs; ++i) { for (int32_t i = 0; i < numOfExprs; ++i) {
SExprInfo* pExpr = getExprInfo(pQueryInfo, i); SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
int32_t f = pExpr->base.functionId; int32_t f = pExpr->pExpr->_node.functionId;
if (f == TSDB_FUNC_DERIVATIVE || f == TSDB_FUNC_TWA || f == TSDB_FUNC_IRATE) { if (f == FUNCTION_DERIVATIVE || f == FUNCTION_TWA || f == FUNCTION_IRATE) {
return buildInvalidOperationMsg(msg, msgBufLen, msg7); return buildInvalidOperationMsg(pMsgBuf, msg7);
} }
} }
} }
// validate the query filter condition info // validate the query filter condition info
if (pSqlNode->pWhere != NULL) { if (pSqlNode->pWhere != NULL) {
if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { if (validateWhereNode(pQueryInfo, pSqlNode->pWhere, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
} else { } else {
if (pQueryInfo->numOfTables > 1) { if (pQueryInfo->numOfTables > 1) {
return buildInvalidOperationMsg(msg, msgBufLen, msg8); return buildInvalidOperationMsg(pMsgBuf, msg8);
} }
} }
// validate the interval info // validate the interval info
if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { if (validateIntervalNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} else { } else {
if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { if (validateSessionNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
// parse the window_state // parse the window_state
if (validateStateWindowNode(pCmd, pQueryInfo, pSqlNode, false) != TSDB_CODE_SUCCESS) { if (validateStateWindowNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (isTimeWindowQuery(pQueryInfo)) { // if (isTimeWindowQuery(pQueryInfo)) {
// check if the first column of the nest query result is timestamp column // // check if the first column of the nest query result is timestamp column
SColumn* pCol = taosArrayGetP(pQueryInfo->colList, 0); // SColumn* pCol = taosArrayGetP(pQueryInfo->colList, 0);
if (pCol->info.type != TSDB_DATA_TYPE_TIMESTAMP) { // if (pCol->info.type != TSDB_DATA_TYPE_TIMESTAMP) {
return buildInvalidOperationMsg(msg, msgBufLen, msg4); // return buildInvalidOperationMsg(pMsgBuf, msg4);
} // }
//
if (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { // if (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; // return TSDB_CODE_TSC_INVALID_OPERATION;
} // }
} // }
} }
// disable group result mixed up if interval/session window query exists. // disable group result mixed up if interval/session window query exists.
if (isTimeWindowQuery(pQueryInfo)) { // if (isTimeWindowQuery(pQueryInfo)) {
size_t num = taosArrayGetSize(pQueryInfo->pUpstream); // size_t num = taosArrayGetSize(pQueryInfo->pUpstream);
for(int32_t i = 0; i < num; ++i) { // for(int32_t i = 0; i < num; ++i) {
SQueryStmtInfo* pUp = taosArrayGetP(pQueryInfo->pUpstream, i); // SQueryStmtInfo* pUp = taosArrayGetP(pQueryInfo->pUpstream, i);
pUp->multigroupResult = false; // pUp->multigroupResult = false;
} // }
} // }
// parse the having clause in the first place // parse the having clause in the first place
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
if (validateHavingClause(pQueryInfo, pSqlNode->pHaving, pCmd, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery) != if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if ((code = validateLimitNode(pCmd, pQueryInfo, pSqlNode, pSql)) != TSDB_CODE_SUCCESS) { if ((code = validateLimitNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
return code; return code;
} }
// set order by info // set order by info
if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMeta)) != TSDB_CODE_SUCCESS) { if (validateOrderbyNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo, tscGetErrorMsgPayload(pCmd))) != TSDB_CODE_SUCCESS) { // if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) {
return code; // return code;
} // }
// updateFunctionInterBuf(pQueryInfo, false); // updateFunctionInterBuf(pQueryInfo, false);
updateLastScanOrderIfNeeded(pQueryInfo); // updateLastScanOrderIfNeeded(pQueryInfo);
if ((code = validateFillNode(pCmd, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) { if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
return code; return code;
} }
} else { } else {
...@@ -976,13 +791,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -976,13 +791,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
size_t numOfTables = taosArrayGetSize(pSqlNode->from->list); size_t numOfTables = taosArrayGetSize(pSqlNode->from->list);
if (numOfTables > TSDB_MAX_JOIN_TABLE_NUM) { if (numOfTables > TSDB_MAX_JOIN_TABLE_NUM) {
return buildInvalidOperationMsg(msg, msgBufLen, msg2); return buildInvalidOperationMsg(pMsgBuf, msg2);
}
// set all query tables, which are maybe more than one.
code = doLoadAllTableMeta(pSql, pQueryInfo, pSqlNode, (int32_t) numOfTables);
if (code != TSDB_CODE_SUCCESS) {
return code;
} }
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
...@@ -991,20 +800,20 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -991,20 +800,20 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
TSDB_QUERY_SET_TYPE(pQueryInfo->type, type); TSDB_QUERY_SET_TYPE(pQueryInfo->type, type);
// parse the group by clause in the first place // parse the group by clause in the first place
if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
pQueryInfo->onlyHasTagCond = true; pQueryInfo->onlyHasTagCond = true;
// set where info // set where info
if (pSqlNode->pWhere != NULL) { if (pSqlNode->pWhere != NULL) {
if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { if (validateWhereNode(pQueryInfo, pSqlNode->pWhere, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
pSqlNode->pWhere = NULL; pSqlNode->pWhere = NULL;
} else { } else {
if (taosArrayGetSize(pSqlNode->from->list) > 1) { // Cross join not allowed yet if (taosArrayGetSize(pSqlNode->from->list) > 1) { // Cross join not allowed yet
return buildInvalidOperationMsg(msg, msgBufLen, "cross join not supported yet"); return buildInvalidOperationMsg(pMsgBuf, "cross join not supported yet");
} }
} }
...@@ -1012,43 +821,43 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -1012,43 +821,43 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
int32_t timeWindowQuery = int32_t timeWindowQuery =
(TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap));
if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery, false, msg, msgBufLen) != if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, false, pMsgBuf) !=
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (isSTable && tscQueryTags(pQueryInfo) && pQueryInfo->distinct && !pQueryInfo->onlyHasTagCond) { if (isSTable && (pQueryInfo) && pQueryInfo->distinct && !pQueryInfo->onlyHasTagCond) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
// parse the window_state // parse the window_state
if (validateStateWindowNode(pCmd, pQueryInfo, pSqlNode, isSTable) != TSDB_CODE_SUCCESS) { if (validateStateWindowNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
// set order by info // set order by info
if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != if (validateOrderbyNode(pQueryInfo, pSqlNode, pMsgBuf) !=
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
// set interval value // set interval value
if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { if (validateIntervalNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (tscQueryTags(pQueryInfo)) { // if (tscQueryTags(pQueryInfo)) {
SExprInfo* pExpr1 = getExprInfo(pQueryInfo, 0); // SExprInfo* pExpr1 = getExprInfo(pQueryInfo, 0);
//
if (pExpr1->base.functionId != TSDB_FUNC_TID_TAG) { // if (pExpr1->base.functionId != FUNCTION_TID_TAG) {
if ((pQueryInfo->colCond && taosArrayGetSize(pQueryInfo->colCond) > 0) || IS_TSWINDOW_SPECIFIED(pQueryInfo->window)) { // if ((pQueryInfo->colCond && taosArrayGetSize(pQueryInfo->colCond) > 0) || IS_TSWINDOW_SPECIFIED(pQueryInfo->window)) {
return buildInvalidOperationMsg(msg, msgBufLen, msg5); // return buildInvalidOperationMsg(pMsgBuf, msg5);
} // }
} // }
} // }
// parse the having clause in the first place // parse the having clause in the first place
if (validateHavingClause(pQueryInfo, pSqlNode->pHaving, pCmd, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery) != if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
TSDB_CODE_SUCCESS) { TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
...@@ -1057,20 +866,13 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -1057,20 +866,13 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
* transfer sql functions that need secondary merge into another format * transfer sql functions that need secondary merge into another format
* in dealing with super table queries such as: count/first/last * in dealing with super table queries such as: count/first/last
*/ */
if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { if (validateSessionNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (isSTable) { // if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
tscTansformFuncForSTableQuery(pQueryInfo); // return TSDB_CODE_TSC_INVALID_OPERATION;
if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) { // }
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
// no result due to invalid query time range // no result due to invalid query time range
if (pQueryInfo->window.skey > pQueryInfo->window.ekey) { if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
...@@ -1078,181 +880,1429 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms ...@@ -1078,181 +880,1429 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, char* ms
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
if (!hasTimestampForPointInterpQuery(pQueryInfo)) { // if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
return buildInvalidOperationMsg(msg, msgBufLen, msg1); // return buildInvalidOperationMsg(pMsgBuf, msg1);
} // }
// in case of join query, time range is required.
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
uint64_t timeRange = (uint64_t)pQueryInfo->window.ekey - pQueryInfo->window.skey;
if (timeRange == 0 && pQueryInfo->window.skey == 0) {
return buildInvalidOperationMsg(msg, msgBufLen, msg3);
}
}
if ((code = validateLimitNode(pCmd, pQueryInfo, pSqlNode, pSql)) != TSDB_CODE_SUCCESS) { // // in case of join query, time range is required.
return code; // if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
} // uint64_t timeRange = (uint64_t)pQueryInfo->window.ekey - pQueryInfo->window.skey;
// if (timeRange == 0 && pQueryInfo->window.skey == 0) {
// return buildInvalidOperationMsg(pMsgBuf, msg3);
// }
// }
if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo,tscGetErrorMsgPayload(pCmd))) != TSDB_CODE_SUCCESS) { if ((code = validateLimitNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
return code; return code;
} }
updateLastScanOrderIfNeeded(pQueryInfo); // if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo,pMsgBuf)) != TSDB_CODE_SUCCESS) {
tscFieldInfoUpdateOffset(pQueryInfo); // return code;
// }
// updateLastScanOrderIfNeeded(pQueryInfo);
// tscFieldInfoUpdateOffset(pQueryInfo);
// updateFunctionInterBuf(pQueryInfo, isSTable); // updateFunctionInterBuf(pQueryInfo, isSTable);
if ((code = validateFillNode(pCmd, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) { if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
return code; return code;
} }
} }
{ // set the query info // set the query info
pQueryInfo->projectionQuery = tscIsProjectionQuery(pQueryInfo); SExprInfo** p = NULL;
pQueryInfo->hasFilter = tscHasColumnFilter(pQueryInfo); int32_t numOfExpr = 0;
pQueryInfo->simpleAgg = isSimpleAggregateRv(pQueryInfo); pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
pQueryInfo->onlyTagQuery = onlyTagPrjFunction(pQueryInfo); code = createProjectionExpr(pQueryInfo, pTableMetaInfo, &p, &numOfExpr);
pQueryInfo->groupbyColumn = tscGroupbyColumn(pQueryInfo); if (pQueryInfo->exprList1 == NULL) {
pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo); pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES);
pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0);
SExprInfo** p = NULL;
int32_t numOfExpr = 0;
pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
code = createProjectionExpr(pQueryInfo, pTableMetaInfo, &p, &numOfExpr);
if (pQueryInfo->exprList1 == NULL) {
pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES);
}
taosArrayAddBatch(pQueryInfo->exprList1, (void*) p, numOfExpr);
tfree(p);
} }
taosArrayAddBatch(pQueryInfo->exprList1, (void*) p, numOfExpr);
tfree(p);
return TSDB_CODE_SUCCESS; // Does not build query message here return TSDB_CODE_SUCCESS; // Does not build query message here
} }
int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool joinQuery, bool timeWindowQuery, bool outerQuery, char* msg, int32_t msgBufLen) { static int32_t distinctCompatibleCheck(SQueryStmtInfo* pQueryInfo, bool joinQuery, SMsgBuf* pMsgBuf) {
assert(pSelNodeList != NULL);
const char* msg1 = "too many items in selection clause";
const char* msg2 = "functions or others can not be mixed up";
const char* msg3 = "not support query expression";
const char* msg4 = "not support distinct mixed with proj/agg func";
const char* msg5 = "invalid function name";
const char* msg6 = "not support distinct mixed with join"; const char* msg6 = "not support distinct mixed with join";
const char* msg7 = "not support distinct mixed with groupby"; const char* msg7 = "not support distinct mixed with groupby";
const char* msg8 = "not support distinct in nest query"; const char* msg8 = "not support distinct in nest query";
const char* msg9 = "_block_dist not support subquery, only support stable/table";
// too many result columns not support order by in query if (pQueryInfo->distinct) {
if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) { if (joinQuery) {
return buildInvalidOperationMsg(msg, msgBufLen, msg1); return buildInvalidOperationMsg(pMsgBuf, msg6);
} }
if (pQueryInfo->colList == NULL) { if (taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo) != 0) {
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); return buildInvalidOperationMsg(pMsgBuf, msg7);
}
if (pQueryInfo->pDownstream != NULL) {
return buildInvalidOperationMsg(pMsgBuf, msg8);
}
} }
}
static int32_t resColId = 5000;
static int32_t getNewResColId() {
return resColId++;
}
bool hasDistinct = false; int32_t addResColumnInfo(SQueryStmtInfo* pQueryInfo, int32_t outputIndex, SColumnIndex* pColIndex, SSchema* pSchema, SExprInfo* pSqlExpr) {
bool hasAgg = false; int32_t tableIndex = pColIndex->tableIndex;
size_t numOfExpr = taosArrayGetSize(pSelNodeList); STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[tableIndex]->pTableMeta;
int32_t distIdx = -1;
for (int32_t i = 0; i < numOfExpr; ++i) {
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i);
if (hasDistinct == false) {
hasDistinct = (pItem->distinct == true);
distIdx = hasDistinct ? i : -1;
}
int32_t type = pItem->pNode->type; assert(pColIndex->columnIndex < getNumOfColumns(pTableMeta));
if (type == SQL_NODE_SQLFUNCTION) {
hasAgg = true;
if (hasDistinct) break;
pItem->functionId = qIsBuiltinFunction(pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n); uint64_t uid = pTableMeta->uid;
SSchema* pSchema1 = getOneColumnSchema(pTableMeta, pColIndex->columnIndex);
columnListInsert(pQueryInfo->colList, pColIndex->columnIndex, uid, pSchema1);
if (pItem->pNode->functionId == TSDB_FUNC_BLKINFO && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { SInternalField* pInfo = insertFieldInfo(&pQueryInfo->fieldsInfo, outputIndex, pSchema);
return buildInvalidOperationMsg(msg, msgBufLen, msg9);
}
SUdfInfo* pUdfInfo = NULL; pInfo->pExpr = pSqlExpr;
if (pItem->pNode->functionId < 0) { return TSDB_CODE_SUCCESS;
pUdfInfo = isValidUdf(pQueryInfo->pUdfInfo, pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n); }
if (pUdfInfo == NULL) {
return buildInvalidOperationMsg(msg, msgBufLen, msg5);
}
pItem->pNode->functionId = pUdfInfo->functionId; void setResultColName(char* name, tSqlExprItem* pItem, SToken* pToken, SToken* functionToken, bool multiCols) {
} if (pItem->aliasName != NULL) {
tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN);
} else if (multiCols) {
char uname[TSDB_COL_NAME_LEN] = {0};
int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN);
tstrncpy(uname, pToken->z, len);
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially if (tsKeepOriginalColumnName) { // keep the original column name
if (addExprAndResultField(pCmd, pQueryInfo, outputIndex, pItem, true, pUdfInfo) != TSDB_CODE_SUCCESS) { tstrncpy(name, uname, TSDB_COL_NAME_LEN);
return TSDB_CODE_TSC_INVALID_OPERATION; } else {
} const int32_t size = TSDB_COL_NAME_LEN + FUNCTIONS_NAME_MAX_LENGTH + 2 + 1;
} else if (type == SQL_NODE_TABLE_COLUMN || type == SQL_NODE_VALUE) { char tmp[TSDB_COL_NAME_LEN + FUNCTIONS_NAME_MAX_LENGTH + 2 + 1] = {0};
// use the dynamic array list to decide if the function is valid or not
// select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2 char f[FUNCTIONS_NAME_MAX_LENGTH] = {0};
if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem, outerQuery) != TSDB_CODE_SUCCESS) { strncpy(f, functionToken->z, functionToken->n);
snprintf(tmp, size, "%s(%s)", f, uname);
tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
}
} else { // use the user-input result column name
int32_t len = MIN(pItem->pNode->exprToken.n + 1, TSDB_COL_NAME_LEN);
tstrncpy(name, pItem->pNode->exprToken.z, len);
}
}
SExprInfo* addExprInSelect(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex,
SSchema* pColSchema) {
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex);
SSchema resultSchema = {0};
setSchemaVal(&resultSchema, pColSchema->type, pColSchema->bytes, getNewResColId(), pColSchema->name);
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, &resultSchema, 0);
addExprInfo(pQueryInfo, outputColIndex, pExpr);
tstrncpy(pExpr->base.token, pColSchema->name, sizeof(pExpr->base.token));
pExpr->base.colInfo.flag = pIndex->type;
if (TSDB_COL_IS_TAG(pIndex->type)) {
columnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->uid, pColSchema);
} else {
addResColumnInfo(pQueryInfo, outputColIndex, pIndex, pColSchema, pExpr);
}
return pExpr;
}
void doAddResColumnOrSourceColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* index, int32_t outputIndex, SExprInfo* pExpr, SSchema* pColSchema, bool finalResult) {
if (finalResult) {
addResColumnInfo(pQueryInfo, outputIndex, index, &pExpr->base.resSchema, pExpr);
} else {
columnListInsert(pQueryInfo->colList, index->columnIndex, pExpr->base.uid, pColSchema);
}
if (TSDB_COL_IS_NORMAL_COL(index->type)) {
insertPrimaryTsColumn(pQueryInfo->colList, pExpr->base.uid);
}
}
static int32_t setExprInfoForFunctions(SQueryStmtInfo* pQueryInfo, SSchema* pSchema, int32_t functionId,
const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult,
SMsgBuf* pMsgBuf) {
const char* msg1 = "not support column types";
if (functionId == FUNCTION_SPREAD) {
if (IS_VAR_DATA_TYPE(pSchema->type) || pSchema->type == TSDB_DATA_TYPE_BOOL) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
}
int16_t resType = 0;
int16_t resBytes = 0;
int32_t interBufSize = 0;
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resType, &resBytes, &interBufSize, 0, false);
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
SSchema resultSchema = {0};
setSchemaVal(&resultSchema, resType, resBytes, getNewResColId(), name);
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pColIndex, &resultSchema, interBufSize);
addExprInfo(pQueryInfo, resColIdx, pExpr);
doAddResColumnOrSourceColumn(pQueryInfo, pColIndex, resColIdx, pExpr, pSchema, finalResult);
return TSDB_CODE_SUCCESS;
}
int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult, SMsgBuf* pMsgBuf) {
STableMetaInfo* pTableMetaInfo = NULL;
int32_t functionId = pItem->functionId;
const char* msg1 = "not support column types";
const char* msg2 = "invalid parameters";
const char* msg3 = "illegal column name";
const char* msg4 = "invalid table name";
const char* msg5 = "parameter is out of range [0, 100]";
const char* msg6 = "functions applied to tags are not allowed";
const char* msg7 = "normal table can not apply this function";
const char* msg8 = "multi-columns selection does not support alias column name";
const char* msg9 = "diff/derivative can no be applied to unsigned numeric type";
const char* msg10 = "derivative duration should be greater than 1 Second";
const char* msg11 = "third parameter in derivative should be 0 or 1";
const char* msg12 = "parameter is out of range [1, 100]";
switch (functionId) {
case FUNCTION_COUNT: {
// more than one parameter for count() function
SArray* pParamList = pItem->pNode->Expr.paramList;
if (pParamList != NULL && taosArrayGetSize(pParamList) != 1) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
SExprInfo* pExpr = NULL;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (pParamList != NULL) {
tSqlExprItem* pParamElem = taosArrayGet(pParamList, 0);
SToken* pToken = &pParamElem->pNode->columnName;
int16_t tokenId = pParamElem->pNode->tokenId;
if ((pToken->z == NULL || pToken->n == 0) && (TK_INTEGER != tokenId)) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
// select count(table.*), select count(1), count(2)
if (tokenId == TK_ALL || tokenId == TK_INTEGER) {
// check if the table name is valid or not
SToken tmpToken = pParamElem->pNode->columnName;
if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg4);
}
index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
} else {
// count the number of table created according to the super table
if (getColumnIndexByName(pToken, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
}
} else { // count(*) is equalled to count(primary_timestamp_key)
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX, false};
}
// todo validate.....
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
SSchema s = {0};
setSchemaVal(&s, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(), "");
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, size);
addExprInfo(pQueryInfo, colIndex, pExpr);
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token,sizeof(pExpr->base.resSchema.name) - 1);
int32_t outputColumnIndex = getNumOfFields(&pQueryInfo->fieldsInfo);
SSchema* ps = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
doAddResColumnOrSourceColumn(pQueryInfo, &index, outputColumnIndex, pExpr, ps, finalResult);
return TSDB_CODE_SUCCESS;
}
case FUNCTION_SUM:
case FUNCTION_AVG:
case FUNCTION_RATE:
case FUNCTION_IRATE:
case FUNCTION_TWA:
case FUNCTION_MIN:
case FUNCTION_MAX:
case FUNCTION_DIFF:
case FUNCTION_DERIVATIVE:
case FUNCTION_STDDEV:
case FUNCTION_LEASTSQR: {
// 1. valid the number of parameters
int32_t numOfParams = (pItem->pNode->Expr.paramList == NULL)? 0: (int32_t) taosArrayGetSize(pItem->pNode->Expr.paramList);
// no parameters or more than one parameter for function
if (pItem->pNode->Expr.paramList == NULL ||
(functionId != FUNCTION_LEASTSQR && functionId != FUNCTION_DERIVATIVE && numOfParams != 1) ||
((functionId == FUNCTION_LEASTSQR || functionId == FUNCTION_DERIVATIVE) && numOfParams != 3)) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0);
if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS)) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
STableComInfo info = getTableInfo(pTableMetaInfo->pTableMeta);
// functions can not be applied to tags
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || (index.columnIndex >= getNumOfColumns(pTableMetaInfo->pTableMeta))) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
// 2. check if sql function can be applied on this column data type
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
if (!IS_NUMERIC_TYPE(pSchema->type)) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
} else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE)) {
return buildInvalidOperationMsg(pMsgBuf, msg9);
}
int16_t resultType = 0;
int16_t resultSize = 0;
int32_t intermediateResSize = 0;
if (getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize,
&intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
} else if (type == SQL_NODE_EXPR) {
int32_t code = handleArithmeticExpr(pCmd, pQueryInfo, i, pItem); // set the first column ts for diff query
if (code != TSDB_CODE_SUCCESS) { int32_t numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo);
return code; if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) {
SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0, .type = TSDB_COL_NORMAL};
SSchema s = {0};
setSchemaVal(&s, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts");
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS_DUMMY, &indexTS, &s, TSDB_KEYSIZE);
addExprInfo(pQueryInfo, numOfOutput, pExpr);
//todo set the correct result field name
assert(numOfOutput == 0);
addResColumnInfo(pQueryInfo, numOfOutput, &index, &pExpr->base.resSchema, pExpr);
numOfOutput += 1;
}
SSchema s = {0};
setSchemaVal(&s, resultType, resultSize, getNewResColId(), "ts");
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, intermediateResSize);
addExprInfo(pQueryInfo, numOfOutput, pExpr);
if (functionId == FUNCTION_LEASTSQR) { // set the leastsquares parameters
char val[8] = {0};
if (taosVariantDump(&pParamElem[1].pNode->value, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES);
memset(val, 0, tListLen(val));
if (taosVariantDump(&pParamElem[2].pNode->value, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES);
} else if (functionId == FUNCTION_IRATE) {
addExprInfoParam(&pExpr->base, (char*) &info.precision, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
} else if (functionId == FUNCTION_DERIVATIVE) {
char val[8] = {0};
int64_t tickPerSec = 0;
if (taosVariantDump(&pParamElem[1].pNode->value, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, true) < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (info.precision == TSDB_TIME_PRECISION_MILLI) {
tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MICRO);
} else if (info.precision == TSDB_TIME_PRECISION_MICRO) {
tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MILLI);
}
if (tickPerSec <= 0 || tickPerSec < TSDB_TICK_PER_SECOND(info.precision)) {
return buildInvalidOperationMsg(pMsgBuf, msg10);
}
addExprInfoParam(&pExpr->base, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
memset(val, 0, tListLen(val));
if (taosVariantDump(&pParamElem[2].pNode->value, val, TSDB_DATA_TYPE_BIGINT, true) < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (GET_INT64_VAL(val) != 0 && GET_INT64_VAL(val) != 1) {
return buildInvalidOperationMsg(pMsgBuf, msg11);
}
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
}
getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo);
doAddResColumnOrSourceColumn(pQueryInfo, &index, numOfOutput, pExpr, pSchema, finalResult);
return TSDB_CODE_SUCCESS;
}
case FUNCTION_FIRST:
case FUNCTION_LAST:
case FUNCTION_SPREAD:
case FUNCTION_LAST_ROW:
case FUNCTION_INTERP: {
bool requireAllFields = (pItem->pNode->Expr.paramList == NULL);
if (!requireAllFields) {
SArray* pParamList = pItem->pNode->Expr.paramList;
if (taosArrayGetSize(pParamList) < 1) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
if (taosArrayGetSize(pParamList) > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) {
return buildInvalidOperationMsg(pMsgBuf, msg8);
}
/* in first/last function, multiple columns can be add to resultset */
for (int32_t i = 0; i < taosArrayGetSize(pParamList); ++i) {
tSqlExprItem* pParamElem = taosArrayGet(pParamList, i);
if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (pParamElem->pNode->tokenId == TK_ALL) { // select table.*
SToken tmpToken = pParamElem->pNode->columnName;
if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg4);
}
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta);
char name[TSDB_COL_NAME_LEN] = {0};
for (int32_t j = 0; j < getNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
index.columnIndex = j;
SToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
setResultColName(name, pItem, &t, &pItem->pNode->exprToken, true);
if (setExprInfoForFunctions(pQueryInfo, &pSchema[j], functionId, name, colIndex++, &index,
finalResult, pMsgBuf) != 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
} else {
if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
// functions can not be applied to tags
if ((index.columnIndex >= getNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
char name[TSDB_COL_NAME_LEN] = {0};
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1;
setResultColName(name, pItem, &pParamElem->pNode->columnName, &pItem->pNode->exprToken, multiColOutput);
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
}
} else { // select * from xxx
int32_t numOfFields = 0;
// multicolumn selection does not support alias name
if (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0) {
return buildInvalidOperationMsg(pMsgBuf, msg8);
}
for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
pTableMetaInfo = getMetaInfo(pQueryInfo, j);
SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta);
for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
SColumnIndex index = {.tableIndex = j, .columnIndex = i};
char name[TSDB_COL_NAME_LEN] = {0};
SToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
setResultColName(name, pItem, &t, &pItem->pNode->exprToken, true);
if (setExprInfoForFunctions(pQueryInfo, &pSchema[index.columnIndex], functionId, name, colIndex, &index,
finalResult, pMsgBuf) != 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
colIndex++;
}
numOfFields += getNumOfColumns(pTableMetaInfo->pTableMeta);
}
}
return TSDB_CODE_SUCCESS;
}
case FUNCTION_TOP:
case FUNCTION_BOTTOM:
case FUNCTION_PERCT:
case FUNCTION_APERCT: {
// 1. valid the number of parameters
// no parameters or more than one parameter for function
if (pItem->pNode->Expr.paramList == NULL || taosArrayGetSize(pItem->pNode->Expr.paramList) != 2) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0);
if (pParamElem->pNode->tokenId != TK_ID) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
// functions can not be applied to tags
if (TSDB_COL_IS_TAG(index.type)) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
// 2. valid the column type
if (!IS_NUMERIC_TYPE(pSchema->type)) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
// 3. valid the parameters
if (pParamElem[1].pNode->tokenId == TK_ID) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
SVariant* pVariant = &pParamElem[1].pNode->value;
int16_t resultType = pSchema->type;
int16_t resultSize = pSchema->bytes;
int32_t interResult = 0;
char val[8] = {0};
SExprInfo* pExpr = NULL;
if (functionId == FUNCTION_PERCT || functionId == FUNCTION_APERCT) {
taosVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
double dp = GET_DOUBLE_VAL(val);
if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize, &interResult, 0, false);
/*
* sql function transformation
* for dp = 0, it is actually min,
* for dp = 100, it is max,
*/
colIndex += 1; // the first column is ts
SSchema s = {0};
setSchemaVal(&s, resultType, resultSize, getNewResColId(), "");
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, interResult);
addExprInfo(pQueryInfo, colIndex, pExpr);
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
} else {
taosVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
int64_t nTop = GET_INT32_VAL(val);
if (nTop <= 0 || nTop > 100) { // todo use macro
return buildInvalidOperationMsg(pMsgBuf, msg12);
}
// set the first column ts for top/bottom query
SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_COL_NORMAL};
SSchema s = {0};
setSchemaVal(&s, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts");
pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS, &index1, &s, 0);
addExprInfo(pQueryInfo, colIndex, pExpr);
addResColumnInfo(pQueryInfo, colIndex, &index1, &pExpr->base.resSchema, pExpr);
colIndex += 1; // the first column is ts
setSchemaVal(&s, resultType, resultSize, getNewResColId(), "");
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, resultSize);
addExprInfo(pQueryInfo, colIndex, pExpr);
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t));
}
getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, pSchema, finalResult);
return TSDB_CODE_SUCCESS;
}
case FUNCTION_TID_TAG: {
pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
return buildInvalidOperationMsg(pMsgBuf, msg7);
}
// no parameters or more than one parameter for function
if (pItem->pNode->Expr.paramList == NULL || taosArrayGetSize(pItem->pNode->Expr.paramList) != 1) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
tSqlExprItem* pParamItem = taosArrayGet(pItem->pNode->Expr.paramList, 0);
tSqlExpr* pParam = pParamItem->pNode;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&pParam->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta);
// functions can not be applied to normal columns
int32_t numOfCols = getNumOfColumns(pTableMetaInfo->pTableMeta);
if (index.columnIndex < numOfCols && index.columnIndex != TSDB_TBNAME_COLUMN_INDEX) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
if (index.columnIndex > 0) {
index.columnIndex -= numOfCols;
}
// 2. valid the column type
int16_t colType = 0;
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
colType = TSDB_DATA_TYPE_BINARY;
} else {
colType = pSchema[index.columnIndex].type;
}
if (colType == TSDB_DATA_TYPE_BOOL) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
columnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->uid, &pSchema[index.columnIndex]);
SSchema* pTagSchema = getTableTagSchema(pTableMetaInfo->pTableMeta);
SSchema s = {0};
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
s = *getTbnameColumnSchema();
} else {
s = pTagSchema[index.columnIndex];
}
int16_t bytes = 0;
int16_t type = 0;
int32_t inter = 0;
int32_t ret = getResultDataInfo(s.type, s.bytes, FUNCTION_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
assert(ret == TSDB_CODE_SUCCESS);
s.type = (uint8_t)type;
s.bytes = bytes;
s.colId = getNewResColId();
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
addExprInSelect(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s);
return TSDB_CODE_SUCCESS;
}
case FUNCTION_BLKINFO: {
// no parameters or more than one parameter for function
if (pItem->pNode->Expr.paramList != NULL && taosArrayGetSize(pItem->pNode->Expr.paramList) != 0) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
SColumnIndex index = {.tableIndex = 0, .columnIndex = 0, .type = TSDB_COL_TAG};
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
int32_t inter = 0;
int16_t resType = 0;
int16_t bytes = 0;
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, 0);
SSchema s = {0};
setSchemaVal(&s, TSDB_DATA_TYPE_BINARY, bytes, getNewResColId(), "block_dist");
SExprInfo* pExpr = addExprInSelect(pQueryInfo, 0, FUNCTION_BLKINFO, &index, &s);
pExpr->base.numOfParams = 1;
pExpr->base.param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize;
pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT;
return TSDB_CODE_SUCCESS;
}
default: {
// pUdfInfo = isValidUdf(pQueryInfo->pUdfInfo, pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
// if (pUdfInfo == NULL) {
// return buildInvalidOperationMsg(pMsgBuf, msg9);
// }
tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0);;
if (pParamElem->pNode->tokenId != TK_ID) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
// functions can not be applied to tags
if (index.columnIndex >= getNumOfColumns(pTableMetaInfo->pTableMeta)) {
return buildInvalidOperationMsg(pMsgBuf, msg6);
}
int32_t inter = 0;
int16_t resType = 0;
int16_t bytes = 0;
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false/*, pUdfInfo*/);
SSchema s = {0};
setSchemaVal(&s, resType, bytes, getNewResColId(), "");
SExprInfo *pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, inter);
addExprInfo(pQueryInfo, colIndex, pExpr);
getColumnName(pItem, s.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
setSchemaVal(&s, resType, bytes, pExpr->base.colInfo.colId, "");
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, &s, finalResult);
return TSDB_CODE_SUCCESS;
}
}
return TSDB_CODE_TSC_INVALID_OPERATION;
}
SExprInfo* doAddProjectCol(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, SColumnIndex* pColIndex, const char* aliasName, int32_t colId) {
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
int32_t numOfCols = getNumOfColumns(pTableMeta);
SSchema* pSchema = getOneColumnSchema(pTableMeta, pColIndex->columnIndex);
SColumnIndex index = *pColIndex;
int16_t functionId = TSDB_COL_IS_TAG(index.type)? FUNCTION_TAGPRJ : FUNCTION_PRJ;
if (functionId == FUNCTION_TAGPRJ) {
index.columnIndex = pColIndex->columnIndex - numOfCols;
columnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->uid, pSchema);
} else {
index.columnIndex = pColIndex->columnIndex;
}
SSchema s = {0};
setSchemaVal(&s, pSchema->type, pSchema->bytes, colId, pSchema->name);
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, 0);
if (aliasName == NULL) {
tstrncpy(pExpr->base.resSchema.name, pSchema->name, sizeof(pExpr->base.resSchema.name));
} else {
tstrncpy(pExpr->base.resSchema.name, aliasName, TSDB_COL_NAME_LEN);
}
addExprInfo(pQueryInfo, outputColIndex, pExpr);
addResColumnInfo(pQueryInfo, outputColIndex, pColIndex, pSchema, pExpr);
}
static int32_t doAddProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
STableComInfo tinfo = getTableInfo(pTableMeta);
int32_t numOfTotalColumns = tinfo.numOfColumns;
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
numOfTotalColumns += tinfo.numOfTags;
}
for (int32_t j = 0; j < numOfTotalColumns; ++j) {
pIndex->columnIndex = j;
doAddProjectCol(pQueryInfo, startPos + j, pIndex, NULL, getNewResColId());
}
return numOfTotalColumns;
}
// User input constant value as a new result column
static SColumnIndex createConstantColumnIndex(int32_t* colId) {
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
index.columnIndex = ((*colId)--);
index.tableIndex = 0;
index.type = TSDB_COL_UDC;
return index;
}
static SSchema createConstantColumnSchema(SVariant* pVal, const SToken* exprStr, const char* name) {
SSchema s = {0};
s.type = pVal->nType;
if (IS_VAR_DATA_TYPE(s.type)) {
s.bytes = (int16_t)(pVal->nLen + VARSTR_HEADER_SIZE);
} else {
s.bytes = tDataTypes[pVal->nType].bytes;
}
s.colId = TSDB_UD_COLUMN_INDEX;
if (name != NULL) {
tstrncpy(s.name, name, sizeof(s.name));
} else {
size_t tlen = MIN(sizeof(s.name), exprStr->n + 1);
tstrncpy(s.name, exprStr->z, tlen);
strdequote(s.name);
}
return s;
}
int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* pItem, bool outerQuery, SMsgBuf* pMsgBuf) {
const char* msg1 = "tag for normal table query is not allowed";
const char* msg2 = "invalid column name";
const char* msg3 = "tbname not allowed in outer query";
int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo);
int32_t tokenId = pItem->pNode->tokenId;
if (tokenId == TK_ALL) { // project on all fields
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY);
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getTableIndexByName(&pItem->pNode->columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
// all columns are required
if (index.tableIndex == COLUMN_INDEX_INITIAL_VAL) { // all table columns are required.
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
index.tableIndex = i;
int32_t inc = doAddProjectionExprAndResColumn(pQueryInfo, &index, startPos);
startPos += inc;
} }
} else { } else {
return buildInvalidOperationMsg(msg, msgBufLen, msg3); doAddProjectionExprAndResColumn(pQueryInfo, &index, startPos);
} }
if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) { // add the primary timestamp column even though it is not required by user
return buildInvalidOperationMsg(msg, msgBufLen, msg1); STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[index.tableIndex]->pTableMeta;
if (pTableMeta->tableType != TSDB_TEMP_TABLE) {
insertPrimaryTsColumn(pQueryInfo->colList, pTableMeta->uid);
}
} else if (tokenId == TK_STRING || tokenId == TK_INTEGER || tokenId == TK_FLOAT) { // simple column projection query
SColumnIndex index = createConstantColumnIndex(&pQueryInfo->udColumnId);
SSchema colSchema = createConstantColumnSchema(&pItem->pNode->value, &pItem->pNode->exprToken, pItem->aliasName);
SExprInfo* pExpr = addExprInSelect(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema);
// NOTE: the first parameter is reserved for the tag column id during join query process.
pExpr->base.numOfParams = 2;
taosVariantAssign(&pExpr->base.param[1], &pItem->pNode->value);
} else if (tokenId == TK_ID) {
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&pItem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
if (outerQuery) { // todo??
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
bool existed = false;
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
int32_t numOfCols = getNumOfColumns(pTableMetaInfo->pTableMeta);
for (int32_t i = 0; i < numOfCols; ++i) {
if (strncasecmp(pSchema[i].name, TSQL_TBNAME_L, tListLen(pSchema[i].name)) == 0) {
existed = true;
index.columnIndex = i;
break;
}
}
if (!existed) {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
SSchema colSchema = pSchema[index.columnIndex];
colSchema.colId = getNewResColId();
char name[TSDB_COL_NAME_LEN] = {0};
getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1);
tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN);
addExprInSelect(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema);
} else {
SSchema colSchema = *getTbnameColumnSchema();
char name[TSDB_COL_NAME_LEN] = {0};
getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1);
tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN);
colSchema.colId = getNewResColId();
addExprInSelect(pQueryInfo, startPos, FUNCTION_TAGPRJ, &index, &colSchema);
}
} else {
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
if (TSDB_COL_IS_TAG(index.type) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
doAddProjectCol(pQueryInfo, startPos, &index, pItem->aliasName, getNewResColId());
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
} }
// add the primary timestamp column even though it is not required by user
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
if (!UTIL_TABLE_IS_TMP_TABLE(pTableMetaInfo)) {
insertPrimaryTsColumn(pQueryInfo->colList, pTableMetaInfo->pTableMeta->uid);
}
} else {
return TSDB_CODE_TSC_INVALID_OPERATION;
} }
//TODO(dengyihao), refactor as function return TSDB_CODE_SUCCESS;
//handle distinct func mixed with other func }
if (hasDistinct == true) {
if (distIdx != 0 || hasAgg) { static int32_t validateExprLeafNode(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pList, int32_t* type, uint64_t* uid,
return buildInvalidOperationMsg(msg, msgBufLen, msg4); SMsgBuf* pMsgBuf) {
if (pExpr->type == SQL_NODE_TABLE_COLUMN) {
if (*type == NON_ARITHMEIC_EXPR) {
*type = NORMAL_ARITHMETIC;
} else if (*type == AGG_ARIGHTMEIC) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (joinQuery) {
return buildInvalidOperationMsg(msg, msgBufLen, msg6); SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&pExpr->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (pQueryInfo->groupbyExpr.numOfGroupCols != 0) {
return buildInvalidOperationMsg(msg, msgBufLen, msg7); // if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
SSchema* pSchema = getOneColumnSchema(pTableMeta, index.columnIndex);
if ((pSchema->type == TSDB_DATA_TYPE_TIMESTAMP) || (pSchema->type == TSDB_DATA_TYPE_BOOL) ||
(pSchema->type == TSDB_DATA_TYPE_BINARY) || (pSchema->type == TSDB_DATA_TYPE_NCHAR)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} }
if (pQueryInfo->pDownstream != NULL) {
return buildInvalidOperationMsg(msg, msgBufLen, msg8); taosArrayPush(pList, &index);
} else if ((pExpr->tokenId == TK_FLOAT && (isnan(pExpr->value.d) || isinf(pExpr->value.d))) ||
pExpr->tokenId == TK_NULL) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else if (pExpr->type == SQL_NODE_SQLFUNCTION) {
if (*type == NON_ARITHMEIC_EXPR) {
*type = AGG_ARIGHTMEIC;
} else if (*type == NORMAL_ARITHMETIC) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
tSqlExprItem item = {.pNode = pExpr, .aliasName = NULL};
// sql function list in selection clause.
// Append the sqlExpr into exprList of pQueryInfo structure sequentially
item.functionId = qIsBuiltinFunction(pExpr->Expr.operand.z, pExpr->Expr.operand.n);
if (item.functionId < 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
if (addExprAndResColumn(pQueryInfo, outputIndex, &item, false, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// It is invalid in case of more than one sqlExpr, such as first(ts, k) - last(ts, k)
int32_t inc = (int32_t) tscNumOfExprs(pQueryInfo) - outputIndex;
if (inc > 1) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// Not supported data type in arithmetic expression
uint64_t id = -1;
for(int32_t i = 0; i < inc; ++i) {
SExprInfo* p1 = getExprInfo(pQueryInfo, i + outputIndex);
int16_t t = p1->base.resSchema.type;
if (IS_VAR_DATA_TYPE(t) || t == TSDB_DATA_TYPE_BOOL || t == TSDB_DATA_TYPE_TIMESTAMP) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (i == 0) {
id = p1->base.uid;
continue;
}
if (id != p1->base.uid) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} }
pQueryInfo->distinct = true; *uid = id;
} }
return TSDB_CODE_SUCCESS;
}
// there is only one user-defined column in the final result field, add the timestamp column. static int32_t validateArithmeticSqlExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pColList, int32_t* type, SMsgBuf* pMsgBuf) {
size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); if (pExpr == NULL) {
if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { return TSDB_CODE_SUCCESS;
addPrimaryTsColIntoResult(pQueryInfo, pCmd);
} }
if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) { tSqlExpr* pLeft = pExpr->pLeft;
return buildInvalidOperationMsg(msg, msgBufLen, msg2); uint64_t uidLeft = 0;
uint64_t uidRight = 0;
if (pLeft->type == SQL_NODE_EXPR) {
int32_t ret = validateArithmeticSqlExpr(pLeft, pQueryInfo, pColList, type, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
} else {
int32_t ret = validateExprLeafNode(pLeft, pQueryInfo, pColList, type, &uidLeft, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
}
tSqlExpr* pRight = pExpr->pRight;
if (pRight->type == SQL_NODE_EXPR) {
int32_t ret = validateArithmeticSqlExpr(pRight, pQueryInfo, pColList, type, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
} else {
int32_t ret = validateExprLeafNode(pRight, pQueryInfo, pColList, type, &uidRight, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, char* msg, int32_t msgBufLen) { int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryStmtInfo* pQueryInfo, SArray* pCols, uint64_t *uid, SMsgBuf* pMsgBuf) {
assert(pNode != NULL && msg != NULL && msgBufLen > 0); tExprNode* pLeft = NULL;
tExprNode* pRight= NULL;
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (pSqlExpr->pLeft != NULL) {
int32_t ret = sqlExprToExprNode(&pLeft, pSqlExpr->pLeft, pQueryInfo, pCols, uid, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
}
if (pSqlExpr->pRight != NULL) {
int32_t ret = sqlExprToExprNode(&pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(pLeft, NULL);
return ret;
}
}
if (pSqlExpr->pLeft == NULL && pSqlExpr->pRight == NULL && pSqlExpr->tokenId == 0) {
*pExpr = calloc(1, sizeof(tExprNode));
return TSDB_CODE_SUCCESS;
}
if (pSqlExpr->pLeft == NULL) { // it is the leaf node
assert(pSqlExpr->pRight == NULL);
if (pSqlExpr->type == SQL_NODE_VALUE) {
int32_t ret = TSDB_CODE_SUCCESS;
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TEXPR_VALUE_NODE;
(*pExpr)->pVal = calloc(1, sizeof(SVariant));
taosVariantAssign((*pExpr)->pVal, &pSqlExpr->value);
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, 0)->pTableMeta;
if (pCols != NULL && taosArrayGetSize(pCols) > 0) {
SColIndex* idx = taosArrayGet(pCols, 0);
SSchema* pSchema = getOneColumnSchema(pTableMeta, idx->colIndex);
// convert time by precision
if (pSchema != NULL && TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && TSDB_DATA_TYPE_BINARY == (*pExpr)->pVal->nType) {
#if 0
ret = setColumnFilterInfoForTimestamp(pCmd, pQueryInfo, (*pExpr)->pVal);
#endif
}
}
return ret;
} else if (pSqlExpr->type == SQL_NODE_SQLFUNCTION) {
// arithmetic expression on the results of aggregation functions
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TEXPR_COL_NODE;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
strncpy((*pExpr)->pSchema->name, pSqlExpr->exprToken.z, pSqlExpr->exprToken.n);
// set the input column data byte and type.
size_t size = taosArrayGetSize(pQueryInfo->exprList);
for (int32_t i = 0; i < size; ++i) {
SExprInfo* p1 = taosArrayGetP(pQueryInfo->exprList, i);
if (strcmp((*pExpr)->pSchema->name, p1->base.resSchema.name) == 0) {
memcpy((*pExpr)->pSchema, &p1->base.resSchema, sizeof(SSchema));
if (uid != NULL) {
*uid = p1->base.uid;
}
break;
}
}
} else if (pSqlExpr->type == SQL_NODE_TABLE_COLUMN) { // column name, normal column arithmetic expression
int32_t ret = getColumnIndexByName(&pSqlExpr->columnName, pQueryInfo, &index, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
pQueryInfo->curTableIdx = index.tableIndex;
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
int32_t numOfColumns = getNumOfColumns(pTableMeta);
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TEXPR_COL_NODE;
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
SSchema* pSchema = getOneColumnSchema(pTableMeta, index.columnIndex);
*(*pExpr)->pSchema = *pSchema;
if (pCols != NULL) { // record the involved columns
SColIndex colIndex = {0};
tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
colIndex.colId = pSchema->colId;
colIndex.colIndex = index.columnIndex;
colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;
taosArrayPush(pCols, &colIndex);
}
return TSDB_CODE_SUCCESS;
} else if (pSqlExpr->tokenId == TK_SET) {
int32_t colType = -1;
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, pQueryInfo->curTableIdx)->pTableMeta;
if (pCols != NULL) {
size_t colSize = taosArrayGetSize(pCols);
if (colSize > 0) {
SColIndex* idx = taosArrayGet(pCols, colSize - 1);
SSchema* pSchema = getOneColumnSchema(pTableMeta, idx->colIndex);
if (pSchema != NULL) {
colType = pSchema->type;
}
}
}
SVariant *pVal;
if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) {
colType = TSDB_DATA_TYPE_BIGINT;
} else if (colType == TSDB_DATA_TYPE_FLOAT || colType == TSDB_DATA_TYPE_DOUBLE) {
colType = TSDB_DATA_TYPE_DOUBLE;
}
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pQueryInfo->curTableIdx);
STableComInfo tinfo = getTableInfo(pTableMetaInfo->pTableMeta);
#if 0
if (serializeExprListToVariant(pSqlExpr->Expr.paramList, &pVal, colType, tinfo.precision) == false) {
return buildInvalidOperationMsg(pMsgBuf, "not support filter expression");
}
#endif
*pExpr = calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TEXPR_VALUE_NODE;
(*pExpr)->pVal = pVal;
} else {
return buildInvalidOperationMsg(pMsgBuf, "not support filter expression");
}
} else {
*pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
(*pExpr)->nodeType = TEXPR_BINARYEXPR_NODE;
(*pExpr)->_node.pLeft = pLeft;
(*pExpr)->_node.pRight = pRight;
SToken t = {.type = pSqlExpr->tokenId};
#if 0
(*pExpr)->_node.optr = convertRelationalOperator(&t);
#endif
assert((*pExpr)->_node.optr != 0);
// check for dividing by 0
if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
if (pRight->nodeType == TEXPR_VALUE_NODE) {
if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64 == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
} else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->d == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
}
// NOTE: binary|nchar data allows the >|< type filter
if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
if (pRight != NULL && pRight->nodeType == TEXPR_VALUE_NODE) {
if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
}
}
return TSDB_CODE_SUCCESS;
}
static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem, SMsgBuf* pMsgBuf) {
const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
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";
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex));
if (validateArithmeticSqlExpr(pItem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
int32_t tableIndex = ((SColumnIndex*)(taosArrayGet(pColumnList, 0)))->tableIndex;
if (arithmeticType == NORMAL_ARITHMETIC) {
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
// expr string is set as the parameter of function
SColumnIndex index = {.tableIndex = tableIndex, .type = TSDB_COL_NORMAL};
SSchema s = {0};
setSchemaVal(&s, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), "");
char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->exprToken.z;
size_t len = MIN(sizeof(s.name), pItem->pNode->exprToken.n + 1);
tstrncpy(s.name, name, len);
SExprInfo* pExpr = createExprInfo(NULL, FUNCTION_ARITHM, &index, &s, sizeof(double));
tExprNode* pNode = NULL;
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
int32_t ret = sqlExprToExprNode(&pNode, pItem->pNode, pQueryInfo, colList, NULL, pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
taosArrayDestroy(colList);
tExprTreeDestroy(pNode, NULL);
return buildInvalidOperationMsg(pMsgBuf, msg2);
}
// check for if there is a tag in the arithmetic express
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 buildInvalidOperationMsg(pMsgBuf, msg3);
}
}
SBufferWriter bw = tbufInitWriter(NULL, false);
// TRY(0) {
exprTreeToBinary(&bw, pNode);
// } CATCH(code) {
// tbufCloseWriter(&bw);
// UNUSED(code);
// TODO: other error handling
// } END_TRY
len = tbufTell(&bw);
char* c = tbufGetData(&bw, false);
// set the serialized binary string as the parameter of arithmetic expression
SColumnIndex* index1 = taosArrayGet(pColumnList, 0);
addExprInfoParam(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len);
addResColumnInfo(pQueryInfo, exprIndex, index1, &pExpr->base.resSchema, pExpr);
// add ts column
insertPrimaryTsColumn(pQueryInfo->colList, pExpr->base.uid);
tbufCloseWriter(&bw);
taosArrayDestroy(colList);
tExprTreeDestroy(pNode, NULL);
} else {
SColumnIndex columnIndex = {0};
char rawName[TSDB_COL_NAME_LEN] = {0};
char aliasName[TSDB_COL_NAME_LEN] = {0};
getColumnName(pItem, aliasName, rawName, TSDB_COL_NAME_LEN);
SSchema s = {0};
setSchemaVal(&s, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), aliasName);
addResColumnInfo(pQueryInfo, exprIndex, &columnIndex, &s, NULL);
int32_t slot = getNumOfFields(&pQueryInfo->fieldsInfo) - 1;
SInternalField* pInfo = getInternalField(&pQueryInfo->fieldsInfo, slot);
assert(pInfo->pExpr == NULL);
SExprInfo* pExpr = createExprInfo(NULL, FUNCTION_ARITHM, &columnIndex, &s, 0);
strncpy(pExpr->base.token, rawName, tListLen(pExpr->base.token));
pExpr->base.numOfParams = 1;
int32_t ret = sqlExprToExprNode(&pExpr->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExpr->base.uid), pMsgBuf);
if (ret != TSDB_CODE_SUCCESS) {
tExprTreeDestroy(pExpr->pExpr, NULL);
return buildInvalidOperationMsg(pMsgBuf, "invalid expression in select clause");
}
pInfo->pExpr = pExpr;
SBufferWriter bw = tbufInitWriter(NULL, false);
// TRY(0) {
exprTreeToBinary(&bw, pInfo->pExpr->pExpr);
// } CATCH(code) {
// tbufCloseWriter(&bw);
// UNUSED(code);
// TODO: other error handling
// } END_TRY
SSqlExpr* pSqlExpr = &pInfo->pExpr->base;
pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw);
pSqlExpr->param[0].pz = tbufGetData(&bw, true);
pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY;
// tbufCloseWriter(&bw); // TODO there is a memory leak
}
return TSDB_CODE_SUCCESS;
}
int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool outerQuery, SMsgBuf* pMsgBuf) {
assert(pSelNodeList != NULL);
const char* msg1 = "too many items in selection clause";
const char* msg2 = "functions or others can not be mixed up";
const char* msg3 = "not support query expression";
const char* msg4 = "not support distinct mixed with proj/agg func";
const char* msg5 = "invalid function name";
const char* msg9 = "_block_dist not support subquery, only support stable/table";
// too many result columns not support order by in query
if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
if (pQueryInfo->colList == NULL) {
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
}
size_t numOfExpr = taosArrayGetSize(pSelNodeList);
for (int32_t i = 0; i < numOfExpr; ++i) {
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i);
int32_t type = pItem->pNode->type;
if (pItem->distinct) {
if (i != 0 || type == SQL_NODE_SQLFUNCTION || type == SQL_NODE_EXPR) {
return buildInvalidOperationMsg(pMsgBuf, msg4);
}
pQueryInfo->distinct = true;
}
if (type == SQL_NODE_SQLFUNCTION) {
pItem->functionId = qIsBuiltinFunction(pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
if (pItem->functionId == FUNCTION_INVALID_ID) {
int32_t functionId = FUNCTION_INVALID_ID;
bool valid = qIsValidUdf(pQueryInfo->pUdfInfo, pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n, &functionId);
if (!valid) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
pItem->functionId = functionId;
}
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially
if (addExprAndResColumn(pQueryInfo, outputIndex, pItem, true, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} else if (type == SQL_NODE_TABLE_COLUMN || type == SQL_NODE_VALUE) {
// use the dynamic array list to decide if the function is valid or not
// select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2
if (addProjectionExprAndResColumn(pQueryInfo, pItem, outerQuery, pMsgBuf) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
} else if (type == SQL_NODE_EXPR) {
int32_t code = handleArithmeticExpr(pQueryInfo, i, pItem, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
} else {
return buildInvalidOperationMsg(pMsgBuf, msg3);
}
if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
return buildInvalidOperationMsg(pMsgBuf, msg1);
}
}
// there is only one user-defined column in the final result field, add the timestamp column.
// size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
// if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
// addPrimaryTsColIntoResult(pQueryInfo, pCmd);
// }
// if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) {
// return buildInvalidOperationMsg(pMsgBuf, msg2);
// }
return TSDB_CODE_SUCCESS;
}
int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf) {
assert(pNode != NULL && pMsgBuf != NULL && pMsgBuf->len > 0);
if (pNode->pWhere == NULL) { if (pNode->pWhere == NULL) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t code = evaluateImpl(pNode->pWhere, tsPrecision); int32_t code = evaluateImpl(pNode->pWhere, tsPrecision);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
strncpy(msg, "invalid time expression in sql", msgBufLen); strncpy(pMsgBuf->buf, "invalid time expression in sql", pMsgBuf->len);
return code; return code;
} }
...@@ -1275,14 +2325,14 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1275,14 +2325,14 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0); SToken* pzName = taosArrayGet(pInfo->pMiscInfo->a, 0);
if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (parserValidateIdToken(pzName) != TSDB_CODE_SUCCESS)) { if ((pInfo->type != TSDB_SQL_DROP_DNODE) && (parserValidateIdToken(pzName) != TSDB_CODE_SUCCESS)) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2); return setInvalidOperatorMsg(pMsgBuf, msg2);
} }
if (pInfo->type == TSDB_SQL_DROP_DB) { if (pInfo->type == TSDB_SQL_DROP_DB) {
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1); assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName); code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2); return setInvalidOperatorMsg(pMsgBuf, msg2);
} }
} else if (pInfo->type == TSDB_SQL_DROP_TABLE) { } else if (pInfo->type == TSDB_SQL_DROP_TABLE) {
...@@ -1299,7 +2349,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1299,7 +2349,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
strncpy(pCmd->payload, pzName->z, pzName->n); strncpy(pCmd->payload, pzName->z, pzName->n);
} else { // drop user/account } else { // drop user/account
if (pzName->n >= TSDB_USER_LEN) { if (pzName->n >= TSDB_USER_LEN) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3); return setInvalidOperatorMsg(pMsgBuf, msg3);
} }
strncpy(pCmd->payload, pzName->z, pzName->n); strncpy(pCmd->payload, pzName->z, pzName->n);
...@@ -1313,12 +2363,12 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1313,12 +2363,12 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg); return setInvalidOperatorMsg(pMsgBuf, msg);
} }
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken); int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg); return setInvalidOperatorMsg(pMsgBuf, msg);
} }
break; break;
...@@ -1353,19 +2403,19 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1353,19 +2403,19 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt); SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt);
if (pCreateDB->dbname.n >= TSDB_DB_NAME_LEN) { if (pCreateDB->dbname.n >= TSDB_DB_NAME_LEN) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2); return setInvalidOperatorMsg(pMsgBuf, msg2);
} }
char buf[TSDB_DB_NAME_LEN] = {0}; char buf[TSDB_DB_NAME_LEN] = {0};
SToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf)); SToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf));
if (tscValidateName(&token) != TSDB_CODE_SUCCESS) { if (tscValidateName(&token) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &token); int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &token);
if (ret != TSDB_CODE_SUCCESS) { if (ret != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2); return setInvalidOperatorMsg(pMsgBuf, msg2);
} }
if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) { if (parseCreateDBOptions(pCmd, pCreateDB) != TSDB_CODE_SUCCESS) {
...@@ -1379,7 +2429,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1379,7 +2429,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
const char* msg = "invalid host name (ip address)"; const char* msg = "invalid host name (ip address)";
if (taosArrayGetSize(pInfo->pMiscInfo->a) > 1) { if (taosArrayGetSize(pInfo->pMiscInfo->a) > 1) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg); return setInvalidOperatorMsg(pMsgBuf, msg);
} }
SToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0); SToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0);
...@@ -1403,11 +2453,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1403,11 +2453,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
} }
if (pName->n >= TSDB_USER_LEN) { if (pName->n >= TSDB_USER_LEN) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3); return setInvalidOperatorMsg(pMsgBuf, msg3);
} }
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2); return setInvalidOperatorMsg(pMsgBuf, msg2);
} }
SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt; SCreateAcctInfo* pAcctOpt = &pInfo->pMiscInfo->acctOpt;
...@@ -1417,7 +2467,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1417,7 +2467,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
} else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) { } else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
} else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) { } else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
} else { } else {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
} }
...@@ -1429,7 +2479,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1429,7 +2479,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
// additional msg has been attached already // additional msg has been attached already
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql); code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
...@@ -1445,7 +2495,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1445,7 +2495,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql); code = tscSetTableFullName(&pTableMetaInfo->name, pToken, pSql);
...@@ -1460,11 +2510,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1460,11 +2510,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0); SToken* pToken = taosArrayGet(pInfo->pMiscInfo->a, 0);
if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
if (pToken->n > TSDB_DB_NAME_LEN) { if (pToken->n > TSDB_DB_NAME_LEN) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
return tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken); return tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pToken);
} }
...@@ -1477,7 +2527,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1477,7 +2527,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
/* validate the parameter names and options */ /* validate the parameter names and options */
if (validateDNodeConfig(pMiscInfo) != TSDB_CODE_SUCCESS) { if (validateDNodeConfig(pMiscInfo) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2); return setInvalidOperatorMsg(pMsgBuf, msg2);
} }
char* pMsg = pCmd->payload; char* pMsg = pCmd->payload;
...@@ -1491,7 +2541,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1491,7 +2541,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
strncpy(pCfg->ep, t0->z, t0->n); strncpy(pCfg->ep, t0->z, t0->n);
if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) { if (validateEp(pCfg->ep) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3); return setInvalidOperatorMsg(pMsgBuf, msg3);
} }
strncpy(pCfg->config, t1->z, t1->n); strncpy(pCfg->config, t1->z, t1->n);
...@@ -1520,11 +2570,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1520,11 +2570,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
SToken* pPwd = &pUser->passwd; SToken* pPwd = &pUser->passwd;
if (pName->n >= TSDB_USER_LEN) { if (pName->n >= TSDB_USER_LEN) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg3); return setInvalidOperatorMsg(pMsgBuf, msg3);
} }
if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { if (tscValidateName(pName) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg2); return setInvalidOperatorMsg(pMsgBuf, msg2);
} }
if (pCmd->command == TSDB_SQL_CREATE_USER) { if (pCmd->command == TSDB_SQL_CREATE_USER) {
...@@ -1548,10 +2598,10 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1548,10 +2598,10 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
} else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) { } else if (strncasecmp(pPrivilege->z, "write", 5) == 0 && pPrivilege->n == 5) {
pCmd->count = 3; pCmd->count = 3;
} else { } else {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg5); return setInvalidOperatorMsg(pMsgBuf, msg5);
} }
} else { } else {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg7); return setInvalidOperatorMsg(pMsgBuf, msg7);
} }
} }
...@@ -1564,7 +2614,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1564,7 +2614,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
// validate the parameter names and options // validate the parameter names and options
if (validateLocalConfig(pMiscInfo) != TSDB_CODE_SUCCESS) { if (validateLocalConfig(pMiscInfo) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg); return setInvalidOperatorMsg(pMsgBuf, msg);
} }
int32_t numOfToken = (int32_t) taosArrayGetSize(pMiscInfo->a); int32_t numOfToken = (int32_t) taosArrayGetSize(pMiscInfo->a);
...@@ -1619,7 +2669,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1619,7 +2669,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
tscTrace("0x%"PRIx64" start to parse the %dth subclause, total:%"PRIzu, pSql->self, i, size); tscTrace("0x%"PRIx64" start to parse the %dth subclause, total:%"PRIzu, pSql->self, i, size);
if (size > 1 && pSqlNode->from && pSqlNode->from->type == SQL_NODE_FROM_SUBQUERY) { if (size > 1 && pSqlNode->from && pSqlNode->from->type == SQL_NODE_FROM_SUBQUERY) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
// normalizeSqlNode(pSqlNode); // normalize the column name in each function // normalizeSqlNode(pSqlNode); // normalize the column name in each function
...@@ -1685,19 +2735,19 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1685,19 +2735,19 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1); assert(taosArrayGetSize(pInfo->pMiscInfo->a) == 1);
code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName); code = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), pzName);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg1); return setInvalidOperatorMsg(pMsgBuf, msg1);
} }
break; break;
} }
case TSDB_SQL_COMPACT_VNODE:{ case TSDB_SQL_COMPACT_VNODE:{
const char* msg = "invalid compact"; const char* msg = "invalid compact";
if (setCompactVnodeInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) { if (setCompactVnodeInfo(pSql, pInfo) != TSDB_CODE_SUCCESS) {
return setInvalidOperatorMsg(msgBuf, msgBufLen, msg); return setInvalidOperatorMsg(pMsgBuf, msg);
} }
break; break;
} }
default: default:
return setInvalidOperatorMsg(msgBuf, msgBufLen, "not support sql expression"); return setInvalidOperatorMsg(pMsgBuf, "not support sql expression");
} }
#endif #endif
...@@ -1721,10 +2771,12 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer ...@@ -1721,10 +2771,12 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
STableMeta* pTableMeta = (STableMeta*) taosArrayGetP(data.pTableMeta, 0); STableMeta* pTableMeta = (STableMeta*) taosArrayGetP(data.pTableMeta, 0);
assert(pTableMeta != NULL); assert(pTableMeta != NULL);
SMsgBuf buf = {.buf = msgBuf, .len = msgBufLen};
size_t len = taosArrayGetSize(pInfo->list); size_t len = taosArrayGetSize(pInfo->list);
for(int32_t i = 0; i < len; ++i) { for(int32_t i = 0; i < len; ++i) {
SSqlNode* p = taosArrayGetP(pInfo->list, i); SSqlNode* p = taosArrayGetP(pInfo->list, i);
code = evaluateSqlNode(p, pTableMeta->tableInfo.precision, msgBuf, msgBufLen); code = evaluateSqlNode(p, pTableMeta->tableInfo.precision, &buf);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
......
...@@ -59,7 +59,7 @@ int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql) { ...@@ -59,7 +59,7 @@ int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql) {
return 0; return 0;
} }
static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, char* msg, int32_t msgBufLen); static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgBuf* pMsgBuf);
static int32_t tnameComparFn(const void* p1, const void* p2) { static int32_t tnameComparFn(const void* p1, const void* p2) {
SName* pn1 = (SName*)p1; SName* pn1 = (SName*)p1;
...@@ -83,7 +83,7 @@ static int32_t tnameComparFn(const void* p1, const void* p2) { ...@@ -83,7 +83,7 @@ static int32_t tnameComparFn(const void* p1, const void* p2) {
} }
} }
static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameList, char* msgBuf, int32_t msgBufLen) { static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameList, SMsgBuf* pMsgBuf) {
int32_t numOfSub = (int32_t)taosArrayGetSize(pSqlNode->from->list); int32_t numOfSub = (int32_t)taosArrayGetSize(pSqlNode->from->list);
for (int32_t j = 0; j < numOfSub; ++j) { for (int32_t j = 0; j < numOfSub; ++j) {
...@@ -93,12 +93,12 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis ...@@ -93,12 +93,12 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis
for (int32_t i = 0; i < num; ++i) { for (int32_t i = 0; i < num; ++i) {
SSqlNode* p = taosArrayGetP(sub->pSubquery, i); SSqlNode* p = taosArrayGetP(sub->pSubquery, i);
if (p->from->type == SQL_NODE_FROM_TABLELIST) { if (p->from->type == SQL_NODE_FROM_TABLELIST) {
int32_t code = getTableNameFromSqlNode(p, tableNameList, msgBuf, msgBufLen); int32_t code = getTableNameFromSqlNode(p, tableNameList, pMsgBuf);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
} else { } else {
getTableNameFromSubquery(p, tableNameList, msgBuf, msgBufLen); getTableNameFromSubquery(p, tableNameList, pMsgBuf);
} }
} }
} }
...@@ -106,7 +106,7 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis ...@@ -106,7 +106,7 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, char* msg, int32_t msgBufLen) { int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgBuf* pMsgBuf) {
const char* msg1 = "invalid table name"; const char* msg1 = "invalid table name";
int32_t numOfTables = (int32_t) taosArrayGetSize(pSqlNode->from->list); int32_t numOfTables = (int32_t) taosArrayGetSize(pSqlNode->from->list);
...@@ -117,12 +117,12 @@ int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, char* ...@@ -117,12 +117,12 @@ int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, char*
SToken* t = &item->tableName; SToken* t = &item->tableName;
if (t->type == TK_INTEGER || t->type == TK_FLOAT || t->type == TK_STRING) { if (t->type == TK_INTEGER || t->type == TK_FLOAT || t->type == TK_STRING) {
return buildInvalidOperationMsg(msg, msgBufLen, msg1); return buildInvalidOperationMsg(pMsgBuf, msg1);
} }
// tscDequoteAndTrimToken(t); // tscDequoteAndTrimToken(t);
if (parserValidateIdToken(t) != TSDB_CODE_SUCCESS) { if (parserValidateIdToken(t) != TSDB_CODE_SUCCESS) {
return buildInvalidOperationMsg(msg, msgBufLen, msg1); return buildInvalidOperationMsg(pMsgBuf, msg1);
} }
SName name = {0}; SName name = {0};
...@@ -143,6 +143,7 @@ static void freePtrElem(void* p) { ...@@ -143,6 +143,7 @@ static void freePtrElem(void* p) {
int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMetaInfo, char* msg, int32_t msgBufLen) { int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMetaInfo, char* msg, int32_t msgBufLen) {
int32_t code = TSDB_CODE_SUCCESS; int32_t code = TSDB_CODE_SUCCESS;
SMsgBuf msgBuf = {.buf = msg, .len = msgBufLen};
pMetaInfo->pTableName = taosArrayInit(4, sizeof(SName)); pMetaInfo->pTableName = taosArrayInit(4, sizeof(SName));
pMetaInfo->pUdf = taosArrayInit(4, POINTER_BYTES); pMetaInfo->pUdf = taosArrayInit(4, POINTER_BYTES);
...@@ -151,17 +152,17 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet ...@@ -151,17 +152,17 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
for (int32_t i = 0; i < size; ++i) { for (int32_t i = 0; i < size; ++i) {
SSqlNode* pSqlNode = taosArrayGetP(pSqlInfo->list, i); SSqlNode* pSqlNode = taosArrayGetP(pSqlInfo->list, i);
if (pSqlNode->from == NULL) { if (pSqlNode->from == NULL) {
return buildInvalidOperationMsg(msg, msgBufLen, "invalid from clause"); return buildInvalidOperationMsg(&msgBuf, "invalid from clause");
} }
// load the table meta in the FROM clause // load the table meta in the FROM clause
if (pSqlNode->from->type == SQL_NODE_FROM_TABLELIST) { if (pSqlNode->from->type == SQL_NODE_FROM_TABLELIST) {
code = getTableNameFromSqlNode(pSqlNode, pMetaInfo->pTableName, msg, msgBufLen); code = getTableNameFromSqlNode(pSqlNode, pMetaInfo->pTableName, &msgBuf);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
} else { } else {
code = getTableNameFromSubquery(pSqlNode, pMetaInfo->pTableName, msg, msgBufLen); code = getTableNameFromSubquery(pSqlNode, pMetaInfo->pTableName, &msgBuf);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
......
...@@ -78,8 +78,8 @@ int32_t parserValidateIdToken(SToken* pToken) { ...@@ -78,8 +78,8 @@ int32_t parserValidateIdToken(SToken* pToken) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
int32_t buildInvalidOperationMsg(char* dst, int32_t dstBufLen, const char* msg) { int32_t buildInvalidOperationMsg(SMsgBuf* pBuf, const char* msg) {
strncpy(dst, msg, dstBufLen); strncpy(pBuf->buf, msg, pBuf->len);
return TSDB_CODE_TSC_INVALID_OPERATION; return TSDB_CODE_TSC_INVALID_OPERATION;
} }
...@@ -493,12 +493,25 @@ static void createInputDataFilterInfo(SQueryStmtInfo* px, int32_t numOfCol1, int ...@@ -493,12 +493,25 @@ static void createInputDataFilterInfo(SQueryStmtInfo* px, int32_t numOfCol1, int
// return len; // return len;
//} //}
TAOS_FIELD createField(int8_t type, const char* name, int16_t bytes) { TAOS_FIELD createField(const SSchema* pSchema) {
TAOS_FIELD f = { .type = type, .bytes = bytes, }; TAOS_FIELD f = { .type = pSchema->type, .bytes = pSchema->bytes, };
tstrncpy(f.name, name, sizeof(f.name)); tstrncpy(f.name, pSchema->name, sizeof(f.name));
return f; return f;
} }
void setSchemaVal(SSchema* pSchema, uint8_t type, int16_t bytes, int16_t colId, const char* name){
assert(pSchema != NULL);
pSchema->type = type;
pSchema->bytes = bytes;
pSchema->colId = colId;
tstrncpy(pSchema->name, name, tListLen(pSchema->name));
}
int32_t getNumOfFields(SFieldInfo* pFieldInfo) {
return pFieldInfo->numOfOutput;
}
int32_t getFirstInvisibleFieldPos(SQueryStmtInfo* pQueryInfo) { int32_t getFirstInvisibleFieldPos(SQueryStmtInfo* pQueryInfo) {
if (pQueryInfo->fieldsInfo.numOfOutput <= 0 || pQueryInfo->fieldsInfo.internalField == NULL) { if (pQueryInfo->fieldsInfo.numOfOutput <= 0 || pQueryInfo->fieldsInfo.internalField == NULL) {
return 0; return 0;
...@@ -524,11 +537,14 @@ SInternalField* appendFieldInfo(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { ...@@ -524,11 +537,14 @@ SInternalField* appendFieldInfo(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) {
return taosArrayPush(pFieldInfo->internalField, &info); return taosArrayPush(pFieldInfo->internalField, &info);
} }
SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* field) { SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* pSchema) {
pFieldInfo->numOfOutput++; pFieldInfo->numOfOutput++;
struct SInternalField info = { .pExpr = NULL, .visible = true }; struct SInternalField info = { .pExpr = NULL, .visible = true };
info.field = *field; info.field.type = pSchema->type;
info.field.bytes = pSchema->bytes;
tstrncpy(info.field.name, pSchema->name, tListLen(pSchema->name));
return taosArrayInsert(pFieldInfo->internalField, index, &info); return taosArrayInsert(pFieldInfo->internalField, index, &info);
} }
...@@ -539,12 +555,12 @@ void fieldInfoUpdateOffset(SQueryStmtInfo* pQueryInfo) { ...@@ -539,12 +555,12 @@ void fieldInfoUpdateOffset(SQueryStmtInfo* pQueryInfo) {
for (int32_t i = 0; i < numOfExprs; ++i) { for (int32_t i = 0; i < numOfExprs; ++i) {
SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, i); SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, i);
p->base.offset = offset; // p->base.offset = offset;
offset += p->base.resBytes; offset += p->base.resSchema.bytes;
} }
} }
SInternalField* fieldInfoGetInternalField(SFieldInfo* pFieldInfo, int32_t index) { SInternalField* getInternalField(SFieldInfo* pFieldInfo, int32_t index) {
assert(index < pFieldInfo->numOfOutput); assert(index < pFieldInfo->numOfOutput);
return TARRAY_GET_ELEM(pFieldInfo->internalField, index); return TARRAY_GET_ELEM(pFieldInfo->internalField, index);
} }
...@@ -555,10 +571,10 @@ TAOS_FIELD* getFieldInfo(SFieldInfo* pFieldInfo, int32_t index) { ...@@ -555,10 +571,10 @@ TAOS_FIELD* getFieldInfo(SFieldInfo* pFieldInfo, int32_t index) {
} }
int16_t getFieldInfoOffset(SQueryStmtInfo* pQueryInfo, int32_t index) { int16_t getFieldInfoOffset(SQueryStmtInfo* pQueryInfo, int32_t index) {
SInternalField* pInfo = fieldInfoGetInternalField(&pQueryInfo->fieldsInfo, index); SInternalField* pInfo = getInternalField(&pQueryInfo->fieldsInfo, index);
assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL); assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL);
return 0;
return pInfo->pExpr->base.offset; // return pInfo->pExpr->base.offset;
} }
int32_t fieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) { int32_t fieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) {
...@@ -659,10 +675,10 @@ void copyFieldInfo(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray* ...@@ -659,10 +675,10 @@ void copyFieldInfo(SFieldInfo* pFieldInfo, const SFieldInfo* pSrc, const SArray*
SInternalField p = {.visible = pfield->visible, .field = pfield->field}; SInternalField p = {.visible = pfield->visible, .field = pfield->field};
bool found = false; bool found = false;
int32_t resColId = pfield->pExpr->base.resColId; int32_t resColId = pfield->pExpr->base.resSchema.colId;
for(int32_t j = 0; j < numOfExpr; ++j) { for(int32_t j = 0; j < numOfExpr; ++j) {
SExprInfo* pExpr = taosArrayGetP(pExprList, j); SExprInfo* pExpr = taosArrayGetP(pExprList, j);
if (pExpr->base.resColId == resColId) { if (pExpr->base.resSchema.colId == resColId) {
p.pExpr = pExpr; p.pExpr = pExpr;
found = true; found = true;
break; break;
...@@ -757,6 +773,11 @@ SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid ...@@ -757,6 +773,11 @@ SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid
return taosArrayGetP(pColumnList, i); return taosArrayGetP(pColumnList, i);
} }
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid) {
SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
return columnListInsert(pColumnList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s);
}
void columnCopy(SColumn* pDest, const SColumn* pSrc); void columnCopy(SColumn* pDest, const SColumn* pSrc);
SColumn* columnClone(const SColumn* src) { SColumn* columnClone(const SColumn* src) {
...@@ -771,6 +792,30 @@ SColumn* columnClone(const SColumn* src) { ...@@ -771,6 +792,30 @@ SColumn* columnClone(const SColumn* src) {
return dst; return dst;
} }
SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFilters) {
if (numOfFilters == 0 || src == NULL) {
assert(src == NULL);
return NULL;
}
SColumnFilterInfo* pFilter = calloc(1, numOfFilters * sizeof(SColumnFilterInfo));
memcpy(pFilter, src, sizeof(SColumnFilterInfo) * numOfFilters);
for (int32_t j = 0; j < numOfFilters; ++j) {
if (pFilter[j].filterstr) {
size_t len = (size_t) pFilter[j].len + 1 * TSDB_NCHAR_SIZE;
pFilter[j].pz = (int64_t) calloc(1, len);
memcpy((char*)pFilter[j].pz, (char*)src[j].pz, (size_t) pFilter[j].len);
}
}
assert(src->filterstr == 0 || src->filterstr == 1);
assert(!(src->lowerRelOptr == TSDB_RELATION_INVALID && src->upperRelOptr == TSDB_RELATION_INVALID));
return pFilter;
}
void columnCopy(SColumn* pDest, const SColumn* pSrc) { void columnCopy(SColumn* pDest, const SColumn* pSrc) {
destroyFilterInfo(&pDest->info.flist); destroyFilterInfo(&pDest->info.flist);
...@@ -1238,7 +1283,7 @@ static void doSetSqlExprAndResultFieldInfo(SQueryStmtInfo* pNewQueryInfo, int64_ ...@@ -1238,7 +1283,7 @@ static void doSetSqlExprAndResultFieldInfo(SQueryStmtInfo* pNewQueryInfo, int64_
for (int32_t i = 0; i < numOfOutput; ++i) { for (int32_t i = 0; i < numOfOutput; ++i) {
SExprInfo* pExpr = getExprInfo(pNewQueryInfo, i); SExprInfo* pExpr = getExprInfo(pNewQueryInfo, i);
TAOS_FIELD f = createField((int8_t) pExpr->base.resType, pExpr->base.aliasName, pExpr->base.resBytes); TAOS_FIELD f = createField(&pExpr->base.resSchema);
SInternalField* pInfo1 = appendFieldInfo(&pNewQueryInfo->fieldsInfo, &f); SInternalField* pInfo1 = appendFieldInfo(&pNewQueryInfo->fieldsInfo, &f);
pInfo1->pExpr = pExpr; pInfo1->pExpr = pExpr;
} }
...@@ -1252,7 +1297,7 @@ static void doSetSqlExprAndResultFieldInfo(SQueryStmtInfo* pNewQueryInfo, int64_ ...@@ -1252,7 +1297,7 @@ static void doSetSqlExprAndResultFieldInfo(SQueryStmtInfo* pNewQueryInfo, int64_
for (int32_t k1 = 0; k1 < numOfOutput; ++k1) { for (int32_t k1 = 0; k1 < numOfOutput; ++k1) {
SExprInfo* pExpr1 = getExprInfo(pNewQueryInfo, k1); SExprInfo* pExpr1 = getExprInfo(pNewQueryInfo, k1);
if (strcmp(field->name, pExpr1->base.aliasName) == 0) { // establish link according to the result field name if (strcmp(field->name, pExpr1->base.resSchema.name) == 0) { // establish link according to the result field name
SInternalField* pInfo = getInternalFieldInfo(&pNewQueryInfo->fieldsInfo, f); SInternalField* pInfo = getInternalFieldInfo(&pNewQueryInfo->fieldsInfo, f);
pInfo->pExpr = pExpr1; pInfo->pExpr = pExpr1;
...@@ -1446,11 +1491,12 @@ int32_t getNumOfOutput(SFieldInfo* pFieldInfo) { ...@@ -1446,11 +1491,12 @@ int32_t getNumOfOutput(SFieldInfo* pFieldInfo) {
return pFieldInfo->numOfOutput; return pFieldInfo->numOfOutput;
} }
// todo move to planner module
int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num) { int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num) {
// if (!pQueryInfo->arithmeticOnAgg) { // if (!pQueryInfo->arithmeticOnAgg) {
// return TSDB_CODE_SUCCESS; // return TSDB_CODE_SUCCESS;
// } // }
#if 0
*num = getNumOfOutput(pQueryInfo); *num = getNumOfOutput(pQueryInfo);
*pExpr = calloc(*(num), POINTER_BYTES); *pExpr = calloc(*(num), POINTER_BYTES);
if ((*pExpr) == NULL) { if ((*pExpr) == NULL) {
...@@ -1466,28 +1512,24 @@ int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableM ...@@ -1466,28 +1512,24 @@ int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableM
SSqlExpr *pse = &px->base; SSqlExpr *pse = &px->base;
pse->uid = pTableMetaInfo->pTableMeta->uid; pse->uid = pTableMetaInfo->pTableMeta->uid;
pse->resColId = pSource->base.resColId; memcpy(&pse->resSchema, &pSource->base.resSchema, sizeof(SSchema));
strncpy(pse->aliasName, pSource->base.aliasName, tListLen(pse->aliasName));
strncpy(pse->token, pSource->base.token, tListLen(pse->token));
if (pSource->base.functionId != FUNCTION_ARITHM) { // this should be switched to projection query if (pSource->base.functionId != FUNCTION_ARITHM) { // this should be switched to projection query
pse->numOfParams = 0; // no params for projection query pse->numOfParams = 0; // no params for projection query
pse->functionId = FUNCTION_PRJ; pse->functionId = FUNCTION_PRJ;
pse->colInfo.colId = pSource->base.resColId; pse->colInfo.colId = pSource->base.resSchema.colId;
int32_t numOfOutput = (int32_t) taosArrayGetSize(pQueryInfo->exprList); int32_t numOfOutput = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
for (int32_t j = 0; j < numOfOutput; ++j) { for (int32_t j = 0; j < numOfOutput; ++j) {
SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, j); SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, j);
if (p->base.resColId == pse->colInfo.colId) { if (p->base.resSchema.colId == pse->colInfo.colId) {
pse->colInfo.colIndex = j; pse->colInfo.colIndex = j;
break; break;
} }
} }
pse->colInfo.flag = TSDB_COL_NORMAL; pse->colInfo.flag = TSDB_COL_NORMAL;
pse->resType = pSource->base.resType; strncpy(pse->colInfo.name, pSource->base.resSchema.name, tListLen(pse->colInfo.name));
pse->resBytes = pSource->base.resBytes;
strncpy(pse->colInfo.name, pSource->base.aliasName, tListLen(pse->colInfo.name));
// TODO restore refactor // TODO restore refactor
int32_t functionId = pSource->base.functionId; int32_t functionId = pSource->base.functionId;
...@@ -1500,17 +1542,17 @@ int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableM ...@@ -1500,17 +1542,17 @@ int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableM
} }
int32_t inter = 0; int32_t inter = 0;
getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resType, getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resSchema.type,
&pse->resBytes, &inter, 0, false/*, NULL*/); &pse->resSchema.bytes, &inter, 0, false/*, NULL*/);
pse->colType = pse->resType; pse->colType = pse->resSchema.type;
pse->colBytes = pse->resBytes; pse->colBytes = pse->resSchema.bytes;
} else { // arithmetic expression } else { // arithmetic expression
pse->colInfo.colId = pSource->base.colInfo.colId; pse->colInfo.colId = pSource->base.colInfo.colId;
pse->colType = pSource->base.colType; pse->colType = pSource->base.colType;
pse->colBytes = pSource->base.colBytes; pse->colBytes = pSource->base.colBytes;
pse->resBytes = sizeof(double); pse->resSchema.bytes = sizeof(double);
pse->resType = TSDB_DATA_TYPE_DOUBLE; pse->resSchema.type = TSDB_DATA_TYPE_DOUBLE;
pse->functionId = pSource->base.functionId; pse->functionId = pSource->base.functionId;
pse->numOfParams = pSource->base.numOfParams; pse->numOfParams = pSource->base.numOfParams;
...@@ -1521,7 +1563,7 @@ int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableM ...@@ -1521,7 +1563,7 @@ int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableM
} }
} }
} }
#endif
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
......
#include "queryInfoUtil.h" #include "queryInfoUtil.h"
#include "tmsgtype.h" #include <function.h>
#include "astGenerator.h" #include "astGenerator.h"
#include "function.h"
#include "os.h" #include "os.h"
#include "parser.h" #include "parser.h"
#include "parserInt.h" #include "parserInt.h"
...@@ -54,56 +55,66 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) { ...@@ -54,56 +55,66 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns); return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns);
} }
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema) {
int16_t size, int16_t resColId, int16_t interSize, int32_t colType) { tExprNode* pColumnNode = calloc(1, sizeof(tExprNode));
pColumnNode->nodeType = TEXPR_COL_NODE;
pColumnNode->pSchema = calloc(1, sizeof(SSchema));
memcpy(pColumnNode->pSchema, pSchema, sizeof(SSchema));
tExprNode* pNode = calloc(1, sizeof(tExprNode));
pNode->nodeType = TEXPR_UNARYEXPR_NODE;
pNode->_node.functionId = functionId;
pNode->_node.pLeft = pColumnNode;
return pNode;
}
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, SSchema* pResSchema, int16_t interSize) {
SExprInfo* pExpr = calloc(1, sizeof(SExprInfo)); SExprInfo* pExpr = calloc(1, sizeof(SExprInfo));
if (pExpr == NULL) { if (pExpr == NULL) {
return NULL; return NULL;
} }
SSqlExpr* p = &pExpr->base; SSqlExpr* p = &pExpr->base;
p->functionId = functionId;
// set the correct columnIndex index // set the correct columnIndex index
if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) { if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
SSchema* s = getTbnameColumnSchema(); SSchema* s = getTbnameColumnSchema();
p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
p->colBytes = s->bytes; pExpr->pExpr = createUnaryFunctionExprNode(functionId, s);
p->colType = s->type;
} else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX) { } else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX) {
p->colInfo.colId = pColIndex->columnIndex; p->colInfo.colId = pColIndex->columnIndex;
p->colBytes = size; SSchema s = {.colId = pColIndex->columnIndex, .bytes = pResSchema->bytes, .type = pResSchema->type};
p->colType = type; tstrncpy(s.name, pResSchema->name, TSDB_COL_NAME_LEN);
} else if (functionId == 0/*TSDB_FUNC_BLKINFO*/) { pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s);
assert(0); } else if (functionId == FUNCTION_BLKINFO) {
p->colInfo.colId = pColIndex->columnIndex; p->colInfo.colId = pColIndex->columnIndex;
p->colBytes = TSDB_MAX_BINARY_LEN; SSchema s = {.colId = pColIndex->columnIndex, .bytes = pResSchema->bytes, .type = pResSchema->type};
p->colType = TSDB_DATA_TYPE_BINARY; tstrncpy(s.name, pResSchema->name, TSDB_COL_NAME_LEN);
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s);
// p->colBytes = TSDB_MAX_BINARY_LEN;
// p->colType = TSDB_DATA_TYPE_BINARY;
} else { } else {
int32_t len = tListLen(p->colInfo.name); int32_t len = tListLen(p->colInfo.name);
if (TSDB_COL_IS_TAG(colType)) { if (TSDB_COL_IS_TAG(pColIndex->type)) {
SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta); SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta);
p->colInfo.colId = pSchema[pColIndex->columnIndex].colId; p->colInfo.colId = pSchema[pColIndex->columnIndex].colId;
p->colBytes = pSchema[pColIndex->columnIndex].bytes; pExpr->pExpr = createUnaryFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex]);
p->colType = pSchema[pColIndex->columnIndex].type;
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema[pColIndex->columnIndex].name); snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema[pColIndex->columnIndex].name);
} else if (pTableMetaInfo->pTableMeta != NULL) { } else if (pTableMetaInfo->pTableMeta != NULL) {
// in handling select database/version/server_status(), the pTableMeta is NULL // in handling select database/version/server_status(), the pTableMeta is NULL
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex); SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex);
p->colInfo.colId = pSchema->colId; p->colInfo.colId = pSchema->colId;
p->colBytes = pSchema->bytes;
p->colType = pSchema->type;
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema->name); snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema->name);
pExpr->pExpr = createUnaryFunctionExprNode(functionId, pSchema);
} }
} }
p->colInfo.flag = colType; p->colInfo.flag = pColIndex->type;
p->colInfo.colIndex = pColIndex->columnIndex; p->colInfo.colIndex = pColIndex->columnIndex;
p->interBytes = interSize;
p->resType = type; memcpy(&p->resSchema, pResSchema, sizeof(SSchema));
p->resBytes = size;
p->resColId = resColId;
p->interBytes = interSize;
if (pTableMetaInfo->pTableMeta) { if (pTableMetaInfo->pTableMeta) {
p->uid = pTableMetaInfo->pTableMeta->uid; p->uid = pTableMetaInfo->pTableMeta->uid;
...@@ -127,12 +138,12 @@ void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int ...@@ -127,12 +138,12 @@ void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int
assert(pExprInfo != NULL); assert(pExprInfo != NULL);
SSqlExpr* pse = &pExprInfo->base; SSqlExpr* pse = &pExprInfo->base;
pse->functionId = functionId; pExprInfo->pExpr->_node.functionId = functionId;
pse->colInfo.colIndex = srcColumnIndex; pse->colInfo.colIndex = srcColumnIndex;
pse->colInfo.colId = colId; pse->colInfo.colId = colId;
pse->resType = resType; pse->resSchema.type = resType;
pse->resBytes = resSize; pse->resSchema.bytes = resSize;
} }
SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index) { SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index) {
...@@ -145,13 +156,13 @@ void destroyExprInfo(SArray* pExprInfo) { ...@@ -145,13 +156,13 @@ void destroyExprInfo(SArray* pExprInfo) {
for(int32_t i = 0; i < size; ++i) { for(int32_t i = 0; i < size; ++i) {
SExprInfo* pExpr = taosArrayGetP(pExprInfo, i); SExprInfo* pExpr = taosArrayGetP(pExprInfo, i);
tSqlExprDestroy(&pExpr->base); // tSqlExprDestroy(&pExpr->base);
} }
taosArrayDestroy(pExprInfo); taosArrayDestroy(pExprInfo);
} }
void addExprParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) { void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) {
assert (pExpr != NULL || argument != NULL || bytes != 0); assert (pExpr != NULL || argument != NULL || bytes != 0);
// set parameter value // set parameter value
...@@ -166,11 +177,12 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src) { ...@@ -166,11 +177,12 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
assert(dst != NULL && src != NULL); assert(dst != NULL && src != NULL);
*dst = *src; *dst = *src;
#if 0
if (src->base.flist.numOfFilters > 0) { if (src->base.flist.numOfFilters > 0) {
dst->base.flist.filterInfo = calloc(src->base.flist.numOfFilters, sizeof(SColumnFilterInfo)); dst->base.flist.filterInfo = calloc(src->base.flist.numOfFilters, sizeof(SColumnFilterInfo));
memcpy(dst->base.flist.filterInfo, src->base.flist.filterInfo, sizeof(SColumnFilterInfo) * src->base.flist.numOfFilters); memcpy(dst->base.flist.filterInfo, src->base.flist.filterInfo, sizeof(SColumnFilterInfo) * src->base.flist.numOfFilters);
} }
#endif
assert(0); assert(0);
// dst->pExpr = exprdup(src->pExpr); // dst->pExpr = exprdup(src->pExpr);
...@@ -252,7 +264,7 @@ int32_t getResRowLength(SArray* pExprList) { ...@@ -252,7 +264,7 @@ int32_t getResRowLength(SArray* pExprList) {
int32_t size = 0; int32_t size = 0;
for(int32_t i = 0; i < num; ++i) { for(int32_t i = 0; i < num; ++i) {
SExprInfo* pExpr = taosArrayGetP(pExprList, i); SExprInfo* pExpr = taosArrayGetP(pExprList, i);
size += pExpr->base.resBytes; size += pExpr->base.resSchema.bytes;
} }
return size; return size;
...@@ -316,33 +328,12 @@ SArray* extractFunctionIdList(SArray* pExprInfoList) { ...@@ -316,33 +328,12 @@ SArray* extractFunctionIdList(SArray* pExprInfoList) {
SArray* p = taosArrayInit(len, sizeof(int16_t)); SArray* p = taosArrayInit(len, sizeof(int16_t));
for(int32_t i = 0; i < len; ++i) { for(int32_t i = 0; i < len; ++i) {
SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i); SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i);
taosArrayPush(p, &pExprInfo->base.functionId); taosArrayPush(p, &pExprInfo->pExpr->_node.functionId);
} }
return p; return p;
} }
bool tscIsProjectionQueryOnSTable(SQueryStmtInfo* pQueryInfo, int32_t tableIndex);
bool tscNonOrderedProjectionQueryOnSTable(SQueryStmtInfo* pQueryInfo, int32_t tableIndex) {
if (!tscIsProjectionQueryOnSTable(pQueryInfo, tableIndex)) {
return false;
}
// order by columnIndex exists, not a non-ordered projection query
return pQueryInfo->order.orderColId < 0;
}
// not order by timestamp projection query on super table
bool tscOrderedProjectionQueryOnSTable(SQueryStmtInfo* pQueryInfo, int32_t tableIndex) {
if (!tscIsProjectionQueryOnSTable(pQueryInfo, tableIndex)) {
return false;
}
// order by columnIndex exists, a non-ordered projection query
return pQueryInfo->order.orderColId >= 0;
}
bool tscHasColumnFilter(SQueryStmtInfo* pQueryInfo) { bool tscHasColumnFilter(SQueryStmtInfo* pQueryInfo) {
// filter on primary timestamp column // filter on primary timestamp column
if (pQueryInfo->window.skey != INT64_MIN || pQueryInfo->window.ekey != INT64_MAX) { if (pQueryInfo->window.skey != INT64_MIN || pQueryInfo->window.ekey != INT64_MAX) {
......
...@@ -673,13 +673,18 @@ TEST(testCase, generateAST_test) { ...@@ -673,13 +673,18 @@ TEST(testCase, generateAST_test) {
ASSERT_EQ(info1.valid, true); ASSERT_EQ(info1.valid, true);
char msg[128] = {0}; char msg[128] = {0};
SMsgBuf msgBuf = {0};
msgBuf.buf = msg;
msgBuf.len = 128;
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, msg, sizeof(msg)); int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
ASSERT_EQ(code, 0); ASSERT_EQ(code, 0);
SSqlInfo info2 = doGenerateAST("select * from abc where ts<now+2"); SSqlInfo info2 = doGenerateAST("select * from abc where ts<now+2");
SSqlNode* pNode2 = (SSqlNode*) taosArrayGetP(((SArray*)info2.list), 0); SSqlNode* pNode2 = (SSqlNode*) taosArrayGetP(((SArray*)info2.list), 0);
code = evaluateSqlNode(pNode2, TSDB_TIME_PRECISION_MILLI, msg, sizeof(msg)); code = evaluateSqlNode(pNode2, TSDB_TIME_PRECISION_MILLI, &msgBuf);
ASSERT_NE(code, 0); ASSERT_NE(code, 0);
} }
...@@ -688,8 +693,12 @@ TEST(testCase, evaluateAST_test) { ...@@ -688,8 +693,12 @@ TEST(testCase, evaluateAST_test) {
ASSERT_EQ(info1.valid, true); ASSERT_EQ(info1.valid, true);
char msg[128] = {0}; char msg[128] = {0};
SMsgBuf msgBuf = {0};
msgBuf.buf = msg;
msgBuf.len = 128;
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, msg, sizeof(msg)); int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
ASSERT_EQ(code, 0); ASSERT_EQ(code, 0);
......
...@@ -50,9 +50,9 @@ typedef struct SQueryNode { ...@@ -50,9 +50,9 @@ typedef struct SQueryNode {
struct SQueryNode *nextNode; struct SQueryNode *nextNode;
} SQueryNode; } SQueryNode;
typedef struct SQueryPhyNode { typedef struct SQueryDistPlanNode {
} SQueryPhyNode; } SQueryDistPlanNode;
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -33,11 +33,11 @@ int32_t qQueryPlanToSql(struct SQueryNode* pQueryNode, char** sql) { ...@@ -33,11 +33,11 @@ int32_t qQueryPlanToSql(struct SQueryNode* pQueryNode, char** sql) {
return 0; return 0;
} }
int32_t qCreatePhysicalPlan(struct SQueryNode* pQueryNode, struct SEpSet* pQnode, struct SQueryPhyNode *pPhyNode) { int32_t qCreatePhysicalPlan(struct SQueryNode* pQueryNode, struct SEpSet* pQnode, struct SQueryDistPlanNode *pPhyNode) {
return 0; return 0;
} }
int32_t qPhyPlanToString(struct SQueryPhyNode *pPhyNode, char** str) { int32_t qPhyPlanToString(struct SQueryDistPlanNode *pPhyNode, char** str) {
return 0; return 0;
} }
...@@ -45,10 +45,10 @@ void* qDestroyQueryPlan(struct SQueryNode* pQueryNode) { ...@@ -45,10 +45,10 @@ void* qDestroyQueryPlan(struct SQueryNode* pQueryNode) {
return NULL; return NULL;
} }
void* qDestroyQueryPhyPlan(struct SQueryPhyNode* pQueryPhyNode) { void* qDestroyQueryPhyPlan(struct SQueryDistPlanNode* pQueryPhyNode) {
return NULL; return NULL;
} }
int32_t qCreateQueryJob(const struct SQueryPhyNode* pPhyNode, struct SQueryJob** pJob) { int32_t qCreateQueryJob(const struct SQueryDistPlanNode* pPhyNode, struct SQueryJob** pJob) {
return 0; return 0;
} }
\ No newline at end of file
...@@ -459,7 +459,7 @@ namespace { ...@@ -459,7 +459,7 @@ namespace {
// two level expression tree // two level expression tree
tExprNode *createExpr1() { tExprNode *createExpr1() {
auto *pLeft = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pLeft = (tExprNode*) calloc(1, sizeof(tExprNode));
pLeft->nodeType = TSQL_NODE_COL; pLeft->nodeType = TEXPR_COL_NODE;
pLeft->pSchema = (SSchema*) calloc(1, sizeof(SSchema)); pLeft->pSchema = (SSchema*) calloc(1, sizeof(SSchema));
strcpy(pLeft->pSchema->name, "col_a"); strcpy(pLeft->pSchema->name, "col_a");
...@@ -468,14 +468,14 @@ tExprNode *createExpr1() { ...@@ -468,14 +468,14 @@ tExprNode *createExpr1() {
pLeft->pSchema->colId = 1; pLeft->pSchema->colId = 1;
auto *pRight = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pRight = (tExprNode*) calloc(1, sizeof(tExprNode));
pRight->nodeType = TSQL_NODE_VALUE; pRight->nodeType = TEXPR_VALUE_NODE;
pRight->pVal = (tVariant*) calloc(1, sizeof(tVariant)); pRight->pVal = (tVariant*) calloc(1, sizeof(tVariant));
pRight->pVal->nType = TSDB_DATA_TYPE_INT; pRight->pVal->nType = TSDB_DATA_TYPE_INT;
pRight->pVal->i64 = 12; pRight->pVal->i64 = 12;
auto *pRoot = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pRoot = (tExprNode*) calloc(1, sizeof(tExprNode));
pRoot->nodeType = TSQL_NODE_EXPR; pRoot->nodeType = TEXPR_NODE_EXPR;
pRoot->_node.optr = TSDB_RELATION_EQUAL; pRoot->_node.optr = TSDB_RELATION_EQUAL;
pRoot->_node.pLeft = pLeft; pRoot->_node.pLeft = pLeft;
...@@ -488,7 +488,7 @@ tExprNode *createExpr1() { ...@@ -488,7 +488,7 @@ tExprNode *createExpr1() {
// thress level expression tree // thress level expression tree
tExprNode* createExpr2() { tExprNode* createExpr2() {
auto *pLeft2 = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pLeft2 = (tExprNode*) calloc(1, sizeof(tExprNode));
pLeft2->nodeType = TSQL_NODE_COL; pLeft2->nodeType = TEXPR_COL_NODE;
pLeft2->pSchema = (SSchema*) calloc(1, sizeof(SSchema)); pLeft2->pSchema = (SSchema*) calloc(1, sizeof(SSchema));
strcpy(pLeft2->pSchema->name, "col_a"); strcpy(pLeft2->pSchema->name, "col_a");
...@@ -497,7 +497,7 @@ tExprNode* createExpr2() { ...@@ -497,7 +497,7 @@ tExprNode* createExpr2() {
pLeft2->pSchema->colId = 1; pLeft2->pSchema->colId = 1;
auto *pRight2 = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pRight2 = (tExprNode*) calloc(1, sizeof(tExprNode));
pRight2->nodeType = TSQL_NODE_VALUE; pRight2->nodeType = TEXPR_VALUE_NODE;
pRight2->pVal = (tVariant*) calloc(1, sizeof(tVariant)); pRight2->pVal = (tVariant*) calloc(1, sizeof(tVariant));
pRight2->pVal->nType = TSDB_DATA_TYPE_BINARY; pRight2->pVal->nType = TSDB_DATA_TYPE_BINARY;
...@@ -506,7 +506,7 @@ tExprNode* createExpr2() { ...@@ -506,7 +506,7 @@ tExprNode* createExpr2() {
pRight2->pVal->nLen = strlen(v); pRight2->pVal->nLen = strlen(v);
auto *p1 = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *p1 = (tExprNode*) calloc(1, sizeof(tExprNode));
p1->nodeType = TSQL_NODE_EXPR; p1->nodeType = TEXPR_NODE_EXPR;
p1->_node.optr = TSDB_RELATION_LIKE; p1->_node.optr = TSDB_RELATION_LIKE;
p1->_node.pLeft = pLeft2; p1->_node.pLeft = pLeft2;
...@@ -514,7 +514,7 @@ tExprNode* createExpr2() { ...@@ -514,7 +514,7 @@ tExprNode* createExpr2() {
p1->_node.hasPK = false; p1->_node.hasPK = false;
auto *pLeft1 = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pLeft1 = (tExprNode*) calloc(1, sizeof(tExprNode));
pLeft1->nodeType = TSQL_NODE_COL; pLeft1->nodeType = TEXPR_COL_NODE;
pLeft1->pSchema = (SSchema*) calloc(1, sizeof(SSchema)); pLeft1->pSchema = (SSchema*) calloc(1, sizeof(SSchema));
strcpy(pLeft1->pSchema->name, "col_b"); strcpy(pLeft1->pSchema->name, "col_b");
...@@ -523,14 +523,14 @@ tExprNode* createExpr2() { ...@@ -523,14 +523,14 @@ tExprNode* createExpr2() {
pLeft1->pSchema->colId = 99; pLeft1->pSchema->colId = 99;
auto *pRight1 = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pRight1 = (tExprNode*) calloc(1, sizeof(tExprNode));
pRight1->nodeType = TSQL_NODE_VALUE; pRight1->nodeType = TEXPR_VALUE_NODE;
pRight1->pVal = (tVariant*) calloc(1, sizeof(tVariant)); pRight1->pVal = (tVariant*) calloc(1, sizeof(tVariant));
pRight1->pVal->nType = TSDB_DATA_TYPE_DOUBLE; pRight1->pVal->nType = TSDB_DATA_TYPE_DOUBLE;
pRight1->pVal->dKey = 91.99; pRight1->pVal->dKey = 91.99;
auto *p2 = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *p2 = (tExprNode*) calloc(1, sizeof(tExprNode));
p2->nodeType = TSQL_NODE_EXPR; p2->nodeType = TEXPR_NODE_EXPR;
p2->_node.optr = TSDB_RELATION_GREATER_EQUAL; p2->_node.optr = TSDB_RELATION_GREATER_EQUAL;
p2->_node.pLeft = pLeft1; p2->_node.pLeft = pLeft1;
...@@ -538,7 +538,7 @@ tExprNode* createExpr2() { ...@@ -538,7 +538,7 @@ tExprNode* createExpr2() {
p2->_node.hasPK = false; p2->_node.hasPK = false;
auto *pRoot = (tExprNode*) calloc(1, sizeof(tExprNode)); auto *pRoot = (tExprNode*) calloc(1, sizeof(tExprNode));
pRoot->nodeType = TSQL_NODE_EXPR; pRoot->nodeType = TEXPR_NODE_EXPR;
pRoot->_node.optr = TSDB_RELATION_OR; pRoot->_node.optr = TSDB_RELATION_OR;
pRoot->_node.pLeft = p1; pRoot->_node.pLeft = p1;
...@@ -605,11 +605,11 @@ void exprSerializeTest2() { ...@@ -605,11 +605,11 @@ void exprSerializeTest2() {
ASSERT_EQ(c1Left->nodeType, c2Left->nodeType); ASSERT_EQ(c1Left->nodeType, c2Left->nodeType);
ASSERT_EQ(c2Left->nodeType, TSQL_NODE_EXPR); ASSERT_EQ(c2Left->nodeType, TEXPR_NODE_EXPR);
ASSERT_EQ(c2Left->_node.optr, TSDB_RELATION_LIKE); ASSERT_EQ(c2Left->_node.optr, TSDB_RELATION_LIKE);
ASSERT_STRCASEEQ(c2Left->_node.pLeft->pSchema->name, "col_a"); ASSERT_STRCASEEQ(c2Left->_node.pLeft->pSchema->name, "col_a");
ASSERT_EQ(c2Left->_node.pRight->nodeType, TSQL_NODE_VALUE); ASSERT_EQ(c2Left->_node.pRight->nodeType, TEXPR_VALUE_NODE);
ASSERT_STRCASEEQ(c2Left->_node.pRight->pVal->pz, "hello world!"); ASSERT_STRCASEEQ(c2Left->_node.pRight->pVal->pz, "hello world!");
...@@ -617,7 +617,7 @@ void exprSerializeTest2() { ...@@ -617,7 +617,7 @@ void exprSerializeTest2() {
tExprNode* c2Right = p2->_node.pRight; tExprNode* c2Right = p2->_node.pRight;
ASSERT_EQ(c1Right->nodeType, c2Right->nodeType); ASSERT_EQ(c1Right->nodeType, c2Right->nodeType);
ASSERT_EQ(c2Right->nodeType, TSQL_NODE_EXPR); ASSERT_EQ(c2Right->nodeType, TEXPR_NODE_EXPR);
ASSERT_EQ(c2Right->_node.optr, TSDB_RELATION_GREATER_EQUAL); ASSERT_EQ(c2Right->_node.optr, TSDB_RELATION_GREATER_EQUAL);
ASSERT_EQ(c2Right->_node.pRight->pVal->dKey, 91.99); ASSERT_EQ(c2Right->_node.pRight->pVal->dKey, 91.99);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册