TD-13338 SELECT statement translate code
This commit is contained in:
parent
13c9aa55ad
commit
d2f1e633a3
|
@ -54,6 +54,9 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_NODE_LIST,
|
QUERY_NODE_NODE_LIST,
|
||||||
QUERY_NODE_FILL,
|
QUERY_NODE_FILL,
|
||||||
|
|
||||||
|
// only for parser
|
||||||
|
QUERY_NODE_TARGET_EXPR,
|
||||||
|
|
||||||
QUERY_NODE_SET_OPERATOR,
|
QUERY_NODE_SET_OPERATOR,
|
||||||
QUERY_NODE_SELECT_STMT,
|
QUERY_NODE_SELECT_STMT,
|
||||||
QUERY_NODE_SHOW_STMT
|
QUERY_NODE_SHOW_STMT
|
||||||
|
@ -78,11 +81,6 @@ typedef struct SNodeList {
|
||||||
SListCell* pTail;
|
SListCell* pTail;
|
||||||
} SNodeList;
|
} SNodeList;
|
||||||
|
|
||||||
typedef struct SNameStr {
|
|
||||||
int32_t len;
|
|
||||||
char* pName;
|
|
||||||
} SNameStr;
|
|
||||||
|
|
||||||
typedef struct SDataType {
|
typedef struct SDataType {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
|
@ -114,7 +112,7 @@ typedef struct SColumnNode {
|
||||||
} SColumnNode;
|
} SColumnNode;
|
||||||
|
|
||||||
typedef struct SValueNode {
|
typedef struct SValueNode {
|
||||||
SExprNode type; // QUERY_NODE_VALUE
|
SExprNode node; // QUERY_NODE_VALUE
|
||||||
char* literal;
|
char* literal;
|
||||||
} SValueNode;
|
} SValueNode;
|
||||||
|
|
||||||
|
@ -146,7 +144,7 @@ typedef enum EOperatorType {
|
||||||
} EOperatorType;
|
} EOperatorType;
|
||||||
|
|
||||||
typedef struct SOperatorNode {
|
typedef struct SOperatorNode {
|
||||||
SExprNode type; // QUERY_NODE_OPERATOR
|
SExprNode node; // QUERY_NODE_OPERATOR
|
||||||
EOperatorType opType;
|
EOperatorType opType;
|
||||||
SNode* pLeft;
|
SNode* pLeft;
|
||||||
SNode* pRight;
|
SNode* pRight;
|
||||||
|
@ -332,6 +330,10 @@ void nodesCloneNode(const SNode* pNode);
|
||||||
int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen);
|
int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen);
|
||||||
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
||||||
|
|
||||||
|
bool nodesIsArithmeticOp(const SOperatorNode* pOp);
|
||||||
|
bool nodesIsComparisonOp(const SOperatorNode* pOp);
|
||||||
|
bool nodesIsJsonOp(const SOperatorNode* pOp);
|
||||||
|
|
||||||
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
||||||
bool nodesIsTimelineQuery(const SNode* pQuery);
|
bool nodesIsTimelineQuery(const SNode* pQuery);
|
||||||
|
|
||||||
|
|
|
@ -444,6 +444,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_PARSER_INVALID_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2601) //invalid column name
|
#define TSDB_CODE_PARSER_INVALID_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2601) //invalid column name
|
||||||
#define TSDB_CODE_PARSER_TABLE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x2602) //table not exist
|
#define TSDB_CODE_PARSER_TABLE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x2602) //table not exist
|
||||||
#define TSDB_CODE_PARSER_AMBIGUOUS_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2603) //ambiguous column
|
#define TSDB_CODE_PARSER_AMBIGUOUS_COLUMN TAOS_DEF_ERROR_CODE(0, 0x2603) //ambiguous column
|
||||||
|
#define TSDB_CODE_PARSER_WRONG_VALUE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2604) //wrong value type
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ typedef struct SAstCreateContext {
|
||||||
bool notSupport;
|
bool notSupport;
|
||||||
bool valid;
|
bool valid;
|
||||||
SNode* pRootNode;
|
SNode* pRootNode;
|
||||||
SHashObj* pResourceHash;
|
|
||||||
} SAstCreateContext;
|
} SAstCreateContext;
|
||||||
|
|
||||||
int32_t createAstCreateContext(SParseContext* pQueryCxt, SAstCreateContext* pCxt);
|
int32_t createAstCreateContext(SParseContext* pQueryCxt, SAstCreateContext* pCxt);
|
||||||
|
|
|
@ -13,11 +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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nodes.h"
|
|
||||||
#include "nodesShowStmts.h"
|
|
||||||
#include "astCreateContext.h"
|
|
||||||
#include "ttoken.h"
|
|
||||||
|
|
||||||
#ifndef _TD_AST_CREATE_FUNCS_H_
|
#ifndef _TD_AST_CREATE_FUNCS_H_
|
||||||
#define _TD_AST_CREATE_FUNCS_H_
|
#define _TD_AST_CREATE_FUNCS_H_
|
||||||
|
|
||||||
|
@ -25,15 +20,26 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "nodes.h"
|
||||||
|
#include "nodesShowStmts.h"
|
||||||
|
#include "astCreateContext.h"
|
||||||
|
#include "ttoken.h"
|
||||||
|
|
||||||
extern SToken nil_token;
|
extern SToken nil_token;
|
||||||
|
|
||||||
|
typedef struct STargetExprNode {
|
||||||
|
ENodeType nodeType;
|
||||||
|
char* p;
|
||||||
|
uint32_t n;
|
||||||
|
SNode* pNode;
|
||||||
|
} STargetExprNode;
|
||||||
|
|
||||||
SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode);
|
SNodeList* createNodeList(SAstCreateContext* pCxt, SNode* pNode);
|
||||||
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode);
|
SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode);
|
||||||
|
|
||||||
SNode* createColumnNode(SAstCreateContext* pCxt, const SToken* pTableAlias, const SToken* pColumnName);
|
SNode* createColumnNode(SAstCreateContext* pCxt, const SToken* pTableAlias, const SToken* pColumnName);
|
||||||
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral);
|
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral);
|
||||||
SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral);
|
SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral);
|
||||||
SNode* addMinusSign(SAstCreateContext* pCxt, SNode* pNode);
|
|
||||||
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias);
|
SNode* setProjectionAlias(SAstCreateContext* pCxt, SNode* pNode, const SToken* pAlias);
|
||||||
SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType type, SNode* pParam1, SNode* pParam2);
|
SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType type, SNode* pParam1, SNode* pParam2);
|
||||||
SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pLeft, SNode* pRight);
|
SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pLeft, SNode* pRight);
|
||||||
|
|
|
@ -76,7 +76,10 @@ SNode* createColumnNode(SAstCreateContext* pCxt, const SToken* pTableAlias, cons
|
||||||
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral) {
|
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral) {
|
||||||
SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||||
CHECK_OUT_OF_MEM(val);
|
CHECK_OUT_OF_MEM(val);
|
||||||
// todo
|
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||||
|
CHECK_OUT_OF_MEM(val->literal);
|
||||||
|
val->node.resType.type = dataType;
|
||||||
|
val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
|
||||||
return (SNode*)val;
|
return (SNode*)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,10 +90,6 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral)
|
||||||
return (SNode*)val;
|
return (SNode*)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* addMinusSign(SAstCreateContext* pCxt, SNode* pNode) {
|
|
||||||
// todo
|
|
||||||
}
|
|
||||||
|
|
||||||
SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType type, SNode* pParam1, SNode* pParam2) {
|
SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType type, SNode* pParam1, SNode* pParam2) {
|
||||||
SLogicConditionNode* cond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
SLogicConditionNode* cond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||||
CHECK_OUT_OF_MEM(cond);
|
CHECK_OUT_OF_MEM(cond);
|
||||||
|
|
|
@ -28,82 +28,11 @@ extern void NewParseFree(void*, FFree);
|
||||||
extern void NewParseTrace(FILE*, char*);
|
extern void NewParseTrace(FILE*, char*);
|
||||||
|
|
||||||
static uint32_t toNewTokenId(uint32_t tokenId) {
|
static uint32_t toNewTokenId(uint32_t tokenId) {
|
||||||
// #define 1
|
|
||||||
// #define NEW_TK_AND 2
|
|
||||||
// #define NEW_TK_UNION 3
|
|
||||||
// #define NEW_TK_ALL 4
|
|
||||||
// #define NEW_TK_MINUS 5
|
|
||||||
// #define NEW_TK_EXCEPT 6
|
|
||||||
// #define NEW_TK_INTERSECT 7
|
|
||||||
// #define NEW_TK_NK_PLUS 8
|
|
||||||
// #define NEW_TK_NK_MINUS 9
|
|
||||||
// #define NEW_TK_NK_STAR 10
|
|
||||||
// #define NEW_TK_NK_SLASH 11
|
|
||||||
// #define NEW_TK_NK_REM 12
|
|
||||||
// #define NEW_TK_SHOW 13
|
|
||||||
// #define NEW_TK_DATABASES 14
|
|
||||||
// #define NEW_TK_NK_INTEGER 15
|
|
||||||
// #define NEW_TK_NK_FLOAT 16
|
|
||||||
// #define NEW_TK_NK_STRING 17
|
|
||||||
// #define NEW_TK_NK_BOOL 18
|
|
||||||
// #define NEW_TK_TIMESTAMP 19
|
|
||||||
// #define NEW_TK_NK_VARIABLE 20
|
|
||||||
// #define NEW_TK_NK_COMMA 21
|
|
||||||
// #define NEW_TK_NK_ID 22
|
|
||||||
// #define NEW_TK_NK_LP 23
|
|
||||||
// #define NEW_TK_NK_RP 24
|
|
||||||
// #define NEW_TK_NK_DOT 25
|
|
||||||
// #define NEW_TK_BETWEEN 26
|
|
||||||
// #define NEW_TK_NOT 27
|
|
||||||
// #define NEW_TK_IS 28
|
|
||||||
// #define NEW_TK_NULL 29
|
|
||||||
// #define NEW_TK_NK_LT 30
|
|
||||||
// #define NEW_TK_NK_GT 31
|
|
||||||
// #define NEW_TK_NK_LE 32
|
|
||||||
// #define NEW_TK_NK_GE 33
|
|
||||||
// #define NEW_TK_NK_NE 34
|
|
||||||
// #define 35
|
|
||||||
// #define NEW_TK_LIKE 36
|
|
||||||
// #define NEW_TK_MATCH 37
|
|
||||||
// #define NEW_TK_NMATCH 38
|
|
||||||
// #define NEW_TK_IN 39
|
|
||||||
// #define NEW_TK_FROM 40
|
|
||||||
// #define NEW_TK_AS 41
|
|
||||||
// #define NEW_TK_JOIN 42
|
|
||||||
// #define NEW_TK_ON 43
|
|
||||||
// #define NEW_TK_INNER 44
|
|
||||||
// #define NEW_TK_SELECT 45
|
|
||||||
// #define NEW_TK_DISTINCT 46
|
|
||||||
// #define 47
|
|
||||||
// #define NEW_TK_PARTITION 48
|
|
||||||
// #define NEW_TK_BY 49
|
|
||||||
// #define NEW_TK_SESSION 50
|
|
||||||
// #define NEW_TK_STATE_WINDOW 51
|
|
||||||
// #define NEW_TK_INTERVAL 52
|
|
||||||
// #define NEW_TK_SLIDING 53
|
|
||||||
// #define NEW_TK_FILL 54
|
|
||||||
// #define NEW_TK_VALUE 55
|
|
||||||
// #define NEW_TK_NONE 56
|
|
||||||
// #define NEW_TK_PREV 57
|
|
||||||
// #define NEW_TK_LINEAR 58
|
|
||||||
// #define NEW_TK_NEXT 59
|
|
||||||
// #define NEW_TK_GROUP 60
|
|
||||||
// #define NEW_TK_HAVING 61
|
|
||||||
// #define NEW_TK_ORDER 62
|
|
||||||
// #define NEW_TK_SLIMIT 63
|
|
||||||
// #define NEW_TK_SOFFSET 64
|
|
||||||
// #define NEW_TK_LIMIT 65
|
|
||||||
// #define NEW_TK_OFFSET 66
|
|
||||||
// #define NEW_TK_NK_LR 67
|
|
||||||
// #define NEW_TK_ASC 68
|
|
||||||
// #define NEW_TK_DESC 69
|
|
||||||
// #define NEW_TK_NULLS 70
|
|
||||||
// #define NEW_TK_FIRST 71
|
|
||||||
// #define NEW_TK_LAST 72
|
|
||||||
|
|
||||||
switch (tokenId) {
|
switch (tokenId) {
|
||||||
case TK_OR:
|
case TK_OR:
|
||||||
return NEW_TK_OR;
|
return NEW_TK_OR;
|
||||||
|
case TK_AND:
|
||||||
|
return NEW_TK_AND;
|
||||||
case TK_UNION:
|
case TK_UNION:
|
||||||
return NEW_TK_UNION;
|
return NEW_TK_UNION;
|
||||||
case TK_ALL:
|
case TK_ALL:
|
||||||
|
@ -116,22 +45,62 @@ static uint32_t toNewTokenId(uint32_t tokenId) {
|
||||||
return NEW_TK_NK_STAR;
|
return NEW_TK_NK_STAR;
|
||||||
case TK_SLASH:
|
case TK_SLASH:
|
||||||
return NEW_TK_NK_SLASH;
|
return NEW_TK_NK_SLASH;
|
||||||
|
case TK_REM:
|
||||||
|
return NEW_TK_NK_REM;
|
||||||
case TK_SHOW:
|
case TK_SHOW:
|
||||||
return NEW_TK_SHOW;
|
return NEW_TK_SHOW;
|
||||||
case TK_DATABASES:
|
case TK_DATABASES:
|
||||||
return NEW_TK_DATABASES;
|
return NEW_TK_DATABASES;
|
||||||
|
case TK_INTEGER:
|
||||||
|
return NEW_TK_NK_INTEGER;
|
||||||
|
case TK_FLOAT:
|
||||||
|
return NEW_TK_NK_FLOAT;
|
||||||
|
case TK_STRING:
|
||||||
|
return NEW_TK_NK_STRING;
|
||||||
|
case TK_BOOL:
|
||||||
|
return NEW_TK_NK_BOOL;
|
||||||
|
case TK_TIMESTAMP:
|
||||||
|
return NEW_TK_TIMESTAMP;
|
||||||
|
case TK_VARIABLE:
|
||||||
|
return NEW_TK_NK_VARIABLE;
|
||||||
|
case TK_COMMA:
|
||||||
|
return NEW_TK_NK_COMMA;
|
||||||
case TK_ID:
|
case TK_ID:
|
||||||
return NEW_TK_NK_ID;
|
return NEW_TK_NK_ID;
|
||||||
case TK_LP:
|
case TK_LP:
|
||||||
return NEW_TK_NK_LP;
|
return NEW_TK_NK_LP;
|
||||||
case TK_RP:
|
case TK_RP:
|
||||||
return NEW_TK_NK_RP;
|
return NEW_TK_NK_RP;
|
||||||
case TK_COMMA:
|
|
||||||
return NEW_TK_NK_COMMA;
|
|
||||||
case TK_DOT:
|
case TK_DOT:
|
||||||
return NEW_TK_NK_DOT;
|
return NEW_TK_NK_DOT;
|
||||||
|
case TK_BETWEEN:
|
||||||
|
return NEW_TK_BETWEEN;
|
||||||
|
case TK_NOT:
|
||||||
|
return NEW_TK_NOT;
|
||||||
|
case TK_IS:
|
||||||
|
return NEW_TK_IS;
|
||||||
|
case TK_NULL:
|
||||||
|
return NEW_TK_NULL;
|
||||||
|
case TK_LT:
|
||||||
|
return NEW_TK_NK_LT;
|
||||||
|
case TK_GT:
|
||||||
|
return NEW_TK_NK_GT;
|
||||||
|
case TK_LE:
|
||||||
|
return NEW_TK_NK_LE;
|
||||||
|
case TK_GE:
|
||||||
|
return NEW_TK_NK_GE;
|
||||||
|
case TK_NE:
|
||||||
|
return NEW_TK_NK_NE;
|
||||||
case TK_EQ:
|
case TK_EQ:
|
||||||
return NEW_TK_NK_EQ;
|
return NEW_TK_NK_EQ;
|
||||||
|
case TK_LIKE:
|
||||||
|
return NEW_TK_LIKE;
|
||||||
|
case TK_MATCH:
|
||||||
|
return NEW_TK_MATCH;
|
||||||
|
case TK_NMATCH:
|
||||||
|
return NEW_TK_NMATCH;
|
||||||
|
case TK_IN:
|
||||||
|
return NEW_TK_IN;
|
||||||
case TK_SELECT:
|
case TK_SELECT:
|
||||||
return NEW_TK_SELECT;
|
return NEW_TK_SELECT;
|
||||||
case TK_DISTINCT:
|
case TK_DISTINCT:
|
||||||
|
@ -142,6 +111,38 @@ static uint32_t toNewTokenId(uint32_t tokenId) {
|
||||||
return NEW_TK_AS;
|
return NEW_TK_AS;
|
||||||
case TK_FROM:
|
case TK_FROM:
|
||||||
return NEW_TK_FROM;
|
return NEW_TK_FROM;
|
||||||
|
case TK_JOIN:
|
||||||
|
return NEW_TK_JOIN;
|
||||||
|
// case TK_ON:
|
||||||
|
// return NEW_TK_ON;
|
||||||
|
// case TK_INNER:
|
||||||
|
// return NEW_TK_INNER;
|
||||||
|
// case TK_PARTITION:
|
||||||
|
// return NEW_TK_PARTITION;
|
||||||
|
case TK_SESSION:
|
||||||
|
return NEW_TK_SESSION;
|
||||||
|
case TK_STATE_WINDOW:
|
||||||
|
return NEW_TK_STATE_WINDOW;
|
||||||
|
case TK_INTERVAL:
|
||||||
|
return NEW_TK_INTERVAL;
|
||||||
|
case TK_SLIDING:
|
||||||
|
return NEW_TK_SLIDING;
|
||||||
|
case TK_FILL:
|
||||||
|
return NEW_TK_FILL;
|
||||||
|
// case TK_VALUE:
|
||||||
|
// return NEW_TK_VALUE;
|
||||||
|
case TK_NONE:
|
||||||
|
return NEW_TK_NONE;
|
||||||
|
case TK_PREV:
|
||||||
|
return NEW_TK_PREV;
|
||||||
|
case TK_LINEAR:
|
||||||
|
return NEW_TK_LINEAR;
|
||||||
|
// case TK_NEXT:
|
||||||
|
// return NEW_TK_NEXT;
|
||||||
|
case TK_GROUP:
|
||||||
|
return NEW_TK_GROUP;
|
||||||
|
case TK_HAVING:
|
||||||
|
return NEW_TK_HAVING;
|
||||||
case TK_ORDER:
|
case TK_ORDER:
|
||||||
return NEW_TK_ORDER;
|
return NEW_TK_ORDER;
|
||||||
case TK_BY:
|
case TK_BY:
|
||||||
|
@ -150,6 +151,14 @@ static uint32_t toNewTokenId(uint32_t tokenId) {
|
||||||
return NEW_TK_ASC;
|
return NEW_TK_ASC;
|
||||||
case TK_DESC:
|
case TK_DESC:
|
||||||
return NEW_TK_DESC;
|
return NEW_TK_DESC;
|
||||||
|
case TK_SLIMIT:
|
||||||
|
return NEW_TK_SLIMIT;
|
||||||
|
case TK_SOFFSET:
|
||||||
|
return NEW_TK_SOFFSET;
|
||||||
|
case TK_LIMIT:
|
||||||
|
return NEW_TK_LIMIT;
|
||||||
|
case TK_OFFSET:
|
||||||
|
return NEW_TK_OFFSET;
|
||||||
case TK_SPACE:
|
case TK_SPACE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -224,14 +233,6 @@ abort_parse:
|
||||||
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
|
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef struct SNamespace {
|
|
||||||
// int16_t level; // todo for correlated subquery
|
|
||||||
// char dbName[TSDB_DB_NAME_LEN];
|
|
||||||
// char tableAlias[TSDB_TABLE_NAME_LEN];
|
|
||||||
// SHashObj* pColHash; // key is colname, value is index of STableMeta.schema
|
|
||||||
// STableMeta* pMeta;
|
|
||||||
// } SNamespace;
|
|
||||||
|
|
||||||
typedef enum ESqlClause {
|
typedef enum ESqlClause {
|
||||||
SQL_CLAUSE_FROM = 1,
|
SQL_CLAUSE_FROM = 1,
|
||||||
SQL_CLAUSE_WHERE
|
SQL_CLAUSE_WHERE
|
||||||
|
@ -256,6 +257,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
|
||||||
return "Table does not exist : %s";
|
return "Table does not exist : %s";
|
||||||
case TSDB_CODE_PARSER_AMBIGUOUS_COLUMN:
|
case TSDB_CODE_PARSER_AMBIGUOUS_COLUMN:
|
||||||
return "Column ambiguously defined : %s";
|
return "Column ambiguously defined : %s";
|
||||||
|
case TSDB_CODE_PARSER_WRONG_VALUE_TYPE:
|
||||||
|
return "Invalid value type : %s";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -322,7 +325,8 @@ static void setColumnInfoBySchema(const STableNode* pTable, const SSchema* pColS
|
||||||
strcpy(pCol->node.aliasName, pColSchema->name);
|
strcpy(pCol->node.aliasName, pColSchema->name);
|
||||||
}
|
}
|
||||||
pCol->colId = pColSchema->colId;
|
pCol->colId = pColSchema->colId;
|
||||||
pCol->colType = pColSchema->type;
|
// pCol->colType = pColSchema->type;
|
||||||
|
pCol->node.resType.type = pColSchema->type;
|
||||||
pCol->node.resType.bytes = pColSchema->bytes;
|
pCol->node.resType.bytes = pColSchema->bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,6 +435,30 @@ static bool translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
|
static bool translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
|
||||||
|
SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType;
|
||||||
|
SDataType rdt = ((SExprNode*)(pOp->pRight))->resType;
|
||||||
|
if (nodesIsArithmeticOp(pOp)) {
|
||||||
|
if (TSDB_DATA_TYPE_JSON == ldt.type || TSDB_DATA_TYPE_BLOB == ldt.type ||
|
||||||
|
TSDB_DATA_TYPE_JSON == rdt.type || TSDB_DATA_TYPE_BLOB == rdt.type) {
|
||||||
|
generateSyntaxErrMsg(pCxt, TSDB_CODE_PARSER_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pOp->node.resType.type = TSDB_DATA_TYPE_DOUBLE;
|
||||||
|
pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
|
||||||
|
return true;
|
||||||
|
} else if (nodesIsComparisonOp(pOp)) {
|
||||||
|
if (TSDB_DATA_TYPE_JSON == ldt.type || TSDB_DATA_TYPE_BLOB == ldt.type ||
|
||||||
|
TSDB_DATA_TYPE_JSON == rdt.type || TSDB_DATA_TYPE_BLOB == rdt.type) {
|
||||||
|
generateSyntaxErrMsg(pCxt, TSDB_CODE_PARSER_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pOp->node.resType.type = TSDB_DATA_TYPE_BOOL;
|
||||||
|
pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// todo json operator
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,13 @@ protected:
|
||||||
return (TSDB_CODE_SUCCESS != translateCode);
|
return (TSDB_CODE_SUCCESS != translateCode);
|
||||||
}
|
}
|
||||||
if (NULL != query_.pRoot && QUERY_NODE_SELECT_STMT == nodeType(query_.pRoot)) {
|
if (NULL != query_.pRoot && QUERY_NODE_SELECT_STMT == nodeType(query_.pRoot)) {
|
||||||
string sql;
|
|
||||||
selectToSql(query_.pRoot, sql);
|
|
||||||
cout << "input sql : [" << cxt_.pSql << "]" << endl;
|
cout << "input sql : [" << cxt_.pSql << "]" << endl;
|
||||||
cout << "output sql : [" << sql << "]" << endl;
|
// string sql;
|
||||||
|
// selectToSql(query_.pRoot, sql);
|
||||||
|
// cout << "output sql : [" << sql << "]" << endl;
|
||||||
|
string str;
|
||||||
|
selectToStr(query_.pRoot, str);
|
||||||
|
cout << "translate str : \n" << str << endl;
|
||||||
}
|
}
|
||||||
return (TSDB_CODE_SUCCESS == translateCode);
|
return (TSDB_CODE_SUCCESS == translateCode);
|
||||||
}
|
}
|
||||||
|
@ -67,6 +70,162 @@ private:
|
||||||
static const int max_err_len = 1024;
|
static const int max_err_len = 1024;
|
||||||
static const int max_sql_len = 1024 * 1024;
|
static const int max_sql_len = 1024 * 1024;
|
||||||
|
|
||||||
|
string dataTypeToStr(const SDataType& dt) {
|
||||||
|
switch (dt.type) {
|
||||||
|
case TSDB_DATA_TYPE_NULL:
|
||||||
|
return "NULL";
|
||||||
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
|
return "BOOL";
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
return "TINYINT";
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
return "SMALLINT";
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
return "INT";
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
return "BIGINT";
|
||||||
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
|
return "FLOAT";
|
||||||
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
|
return "DOUBLE";
|
||||||
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
|
return "BINART(" + to_string(dt.bytes) + ")";
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
|
return "TIMESTAMP";
|
||||||
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
|
return "NCHAR(" + to_string(dt.bytes) + ")";
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
return "UTINYINT";
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
return "USMALLINT";
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
return "UINT";
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
return "UBIGINT";
|
||||||
|
case TSDB_DATA_TYPE_VARCHAR:
|
||||||
|
return "VARCHAR(" + to_string(dt.bytes) + ")";
|
||||||
|
case TSDB_DATA_TYPE_VARBINARY:
|
||||||
|
return "VARBINARY(" + to_string(dt.bytes) + ")";
|
||||||
|
case TSDB_DATA_TYPE_JSON:
|
||||||
|
return "JSON";
|
||||||
|
case TSDB_DATA_TYPE_DECIMAL:
|
||||||
|
return "DECIMAL(" + to_string(dt.precision) + ", " + to_string(dt.scale) + ")";
|
||||||
|
case TSDB_DATA_TYPE_BLOB:
|
||||||
|
return "BLOB";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "Unknown Data Type " + to_string(dt.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nodeToStr(const SNode* node, string& str, bool isProject) {
|
||||||
|
if (nullptr == node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (nodeType(node)) {
|
||||||
|
case QUERY_NODE_COLUMN: {
|
||||||
|
SColumnNode* pCol = (SColumnNode*)node;
|
||||||
|
if ('\0' != pCol->dbName[0]) {
|
||||||
|
str.append(pCol->dbName);
|
||||||
|
str.append(".");
|
||||||
|
}
|
||||||
|
if ('\0' != pCol->tableAlias[0]) {
|
||||||
|
str.append(pCol->tableAlias);
|
||||||
|
str.append(".");
|
||||||
|
}
|
||||||
|
str.append(pCol->colName);
|
||||||
|
str.append(" [" + dataTypeToStr(pCol->node.resType) + "]");
|
||||||
|
if (isProject) {
|
||||||
|
str.append(" AS " + string(pCol->node.aliasName));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_VALUE: {
|
||||||
|
SValueNode* pVal = (SValueNode*)node;
|
||||||
|
str.append(pVal->literal);
|
||||||
|
str.append(" [" + dataTypeToStr(pVal->node.resType) + "]");
|
||||||
|
if (isProject) {
|
||||||
|
str.append(" AS " + string(pVal->node.aliasName));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_OPERATOR: {
|
||||||
|
SOperatorNode* pOp = (SOperatorNode*)node;
|
||||||
|
nodeToStr(pOp->pLeft, str, false);
|
||||||
|
str.append(opTypeToStr(pOp->opType));
|
||||||
|
nodeToStr(pOp->pRight, str, false);
|
||||||
|
str.append(" [" + dataTypeToStr(pOp->node.resType) + "]");
|
||||||
|
if (isProject) {
|
||||||
|
str.append(" AS " + string(pOp->node.aliasName));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nodeListToStr(const SNodeList* nodelist, const string& prefix, string& str, bool isProject = false) {
|
||||||
|
SNode* node = nullptr;
|
||||||
|
FOREACH(node, nodelist) {
|
||||||
|
str.append(prefix);
|
||||||
|
nodeToStr(node, str, isProject);
|
||||||
|
str.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tableToStr(const SNode* node, const string& prefix, string& str) {
|
||||||
|
const STableNode* table = (const STableNode*)node;
|
||||||
|
switch (nodeType(node)) {
|
||||||
|
case QUERY_NODE_REAL_TABLE: {
|
||||||
|
SRealTableNode* realTable = (SRealTableNode*)table;
|
||||||
|
str.append(prefix);
|
||||||
|
if ('\0' != realTable->table.dbName[0]) {
|
||||||
|
str.append(realTable->table.dbName);
|
||||||
|
str.append(".");
|
||||||
|
}
|
||||||
|
str.append(realTable->table.tableName);
|
||||||
|
str.append(string(" ") + realTable->table.tableAlias);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_TEMP_TABLE: {
|
||||||
|
STempTableNode* tempTable = (STempTableNode*)table;
|
||||||
|
str.append(prefix + "(\n");
|
||||||
|
selectToStr(tempTable->pSubquery, str, prefix + "\t");
|
||||||
|
str.append("\n");
|
||||||
|
str.append(prefix + ") ");
|
||||||
|
str.append(tempTable->table.tableAlias);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QUERY_NODE_JOIN_TABLE: {
|
||||||
|
SJoinTableNode* joinTable = (SJoinTableNode*)table;
|
||||||
|
tableToStr(joinTable->pLeft, prefix, str);
|
||||||
|
str.append("\n" + prefix + "JOIN\n");
|
||||||
|
tableToStr(joinTable->pRight, prefix, str);
|
||||||
|
if (nullptr != joinTable->pOnCond) {
|
||||||
|
str.append("\n" + prefix + "\tON ");
|
||||||
|
nodeToStr(joinTable->pOnCond, str, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectToStr(const SNode* node, string& str, const string& prefix = "") {
|
||||||
|
SSelectStmt* select = (SSelectStmt*)node;
|
||||||
|
str.append(prefix + "SELECT ");
|
||||||
|
if (select->isDistinct) {
|
||||||
|
str.append("DISTINCT");
|
||||||
|
}
|
||||||
|
str.append("\n");
|
||||||
|
nodeListToStr(select->pProjectionList, prefix + "\t", str, true);
|
||||||
|
str.append("\n" + prefix + "FROM\n");
|
||||||
|
tableToStr(select->pFromTable, prefix + "\t", str);
|
||||||
|
}
|
||||||
|
|
||||||
void selectToSql(const SNode* node, string& sql) {
|
void selectToSql(const SNode* node, string& sql) {
|
||||||
SSelectStmt* select = (SSelectStmt*)node;
|
SSelectStmt* select = (SSelectStmt*)node;
|
||||||
sql.append("SELECT ");
|
sql.append("SELECT ");
|
||||||
|
@ -123,7 +282,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string opTypeToSql(EOperatorType type) {
|
string opTypeToStr(EOperatorType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OP_TYPE_ADD:
|
case OP_TYPE_ADD:
|
||||||
return " + ";
|
return " + ";
|
||||||
|
@ -177,7 +336,7 @@ private:
|
||||||
case QUERY_NODE_OPERATOR: {
|
case QUERY_NODE_OPERATOR: {
|
||||||
SOperatorNode* pOp = (SOperatorNode*)node;
|
SOperatorNode* pOp = (SOperatorNode*)node;
|
||||||
nodeToSql(pOp->pLeft, sql);
|
nodeToSql(pOp->pLeft, sql);
|
||||||
sql.append(opTypeToSql(pOp->opType));
|
sql.append(opTypeToStr(pOp->opType));
|
||||||
nodeToSql(pOp->pRight, sql);
|
nodeToSql(pOp->pRight, sql);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -213,8 +372,7 @@ private:
|
||||||
SQuery query_;
|
SQuery query_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SELECT * FROM t1
|
TEST_F(NewParserTest, selectSimple) {
|
||||||
TEST_F(NewParserTest, selectStar) {
|
|
||||||
setDatabase("root", "test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
bind("SELECT * FROM t1");
|
bind("SELECT * FROM t1");
|
||||||
|
@ -233,7 +391,14 @@ TEST_F(NewParserTest, selectStar) {
|
||||||
ASSERT_TRUE(run());
|
ASSERT_TRUE(run());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(NewParserTest, syntaxError) {
|
TEST_F(NewParserTest, selectExpression) {
|
||||||
|
setDatabase("root", "test");
|
||||||
|
|
||||||
|
bind("SELECT c1 + 10, c2 FROM t1");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(NewParserTest, selectSyntaxError) {
|
||||||
setDatabase("root", "test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
bind("SELECTT * FROM t1");
|
bind("SELECTT * FROM t1");
|
||||||
|
@ -249,7 +414,7 @@ TEST_F(NewParserTest, syntaxError) {
|
||||||
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(NewParserTest, semanticError) {
|
TEST_F(NewParserTest, selectSemanticError) {
|
||||||
setDatabase("root", "test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
bind("SELECT * FROM t10");
|
bind("SELECT * FROM t10");
|
||||||
|
|
|
@ -109,7 +109,7 @@ void nodesWalkNodePostOrder(SNode* pNode, FQueryNodeWalker walker, void* pContex
|
||||||
}
|
}
|
||||||
|
|
||||||
void nodesWalkListPostOrder(SNodeList* pList, FQueryNodeWalker walker, void* pContext) {
|
void nodesWalkListPostOrder(SNodeList* pList, FQueryNodeWalker walker, void* pContext) {
|
||||||
(void)walkList(pList, TRAVERSAL_PREORDER, walker, pContext);
|
(void)walkList(pList, TRAVERSAL_POSTORDER, walker, pContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nodesWalkStmt(SNode* pNode, FQueryNodeWalker walker, void* pContext) {
|
bool nodesWalkStmt(SNode* pNode, FQueryNodeWalker walker, void* pContext) {
|
||||||
|
|
|
@ -70,8 +70,19 @@ SNode* nodesMakeNode(ENodeType type) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nodesDestroyNode(SNode* pNode) {
|
static bool destroyNode(SNode* pNode, void* pContext) {
|
||||||
|
switch (nodeType(pNode)) {
|
||||||
|
case QUERY_NODE_VALUE:
|
||||||
|
tfree(((SValueNode*)pNode)->literal);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tfree(pNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nodesDestroyNode(SNode* pNode) {
|
||||||
|
nodesWalkNodePostOrder(pNode, destroyNode, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SNodeList* nodesMakeList() {
|
SNodeList* nodesMakeList() {
|
||||||
|
@ -103,13 +114,63 @@ SNodeList* nodesListAppend(SNodeList* pList, SNode* pNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void nodesDestroyList(SNodeList* pList) {
|
void nodesDestroyList(SNodeList* pList) {
|
||||||
|
SNode* node;
|
||||||
|
FOREACH(node, pList) {
|
||||||
|
nodesDestroyNode(node);
|
||||||
|
}
|
||||||
|
tfree(pList);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nodesIsArithmeticOp(const SOperatorNode* pOp) {
|
||||||
|
switch (pOp->opType) {
|
||||||
|
case OP_TYPE_ADD:
|
||||||
|
case OP_TYPE_SUB:
|
||||||
|
case OP_TYPE_MULTI:
|
||||||
|
case OP_TYPE_DIV:
|
||||||
|
case OP_TYPE_MOD:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nodesIsComparisonOp(const SOperatorNode* pOp) {
|
||||||
|
switch (pOp->opType) {
|
||||||
|
case OP_TYPE_GREATER_THAN:
|
||||||
|
case OP_TYPE_GREATER_EQUAL:
|
||||||
|
case OP_TYPE_LOWER_THAN:
|
||||||
|
case OP_TYPE_LOWER_EQUAL:
|
||||||
|
case OP_TYPE_EQUAL:
|
||||||
|
case OP_TYPE_NOT_EQUAL:
|
||||||
|
case OP_TYPE_IN:
|
||||||
|
case OP_TYPE_NOT_IN:
|
||||||
|
case OP_TYPE_LIKE:
|
||||||
|
case OP_TYPE_NOT_LIKE:
|
||||||
|
case OP_TYPE_MATCH:
|
||||||
|
case OP_TYPE_NMATCH:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nodesIsJsonOp(const SOperatorNode* pOp) {
|
||||||
|
switch (pOp->opType) {
|
||||||
|
case OP_TYPE_JSON_GET_VALUE:
|
||||||
|
case OP_TYPE_JSON_CONTAINS:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nodesIsTimeorderQuery(const SNode* pQuery) {
|
bool nodesIsTimeorderQuery(const SNode* pQuery) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nodesIsTimelineQuery(const SNode* pQuery) {
|
bool nodesIsTimelineQuery(const SNode* pQuery) {
|
||||||
|
return false;
|
||||||
}
|
}
|
Loading…
Reference in New Issue