TD-13852 create super table implement
This commit is contained in:
parent
be73f15a17
commit
08fb912aad
|
@ -55,102 +55,104 @@
|
||||||
#define TK_TTL 37
|
#define TK_TTL 37
|
||||||
#define TK_WAL 38
|
#define TK_WAL 38
|
||||||
#define TK_VGROUPS 39
|
#define TK_VGROUPS 39
|
||||||
#define TK_SINGLESTABLE 40
|
#define TK_SINGLE_STABLE 40
|
||||||
#define TK_STREAMMODE 41
|
#define TK_STREAM_MODE 41
|
||||||
#define TK_USE 42
|
#define TK_USE 42
|
||||||
#define TK_TABLE 43
|
#define TK_TABLE 43
|
||||||
#define TK_NK_LP 44
|
#define TK_NK_LP 44
|
||||||
#define TK_NK_RP 45
|
#define TK_NK_RP 45
|
||||||
#define TK_NK_ID 46
|
#define TK_STABLE 46
|
||||||
#define TK_NK_DOT 47
|
#define TK_USING 47
|
||||||
#define TK_NK_COMMA 48
|
#define TK_TAGS 48
|
||||||
#define TK_COMMENT 49
|
#define TK_NK_ID 49
|
||||||
#define TK_BOOL 50
|
#define TK_NK_DOT 50
|
||||||
#define TK_TINYINT 51
|
#define TK_NK_COMMA 51
|
||||||
#define TK_SMALLINT 52
|
#define TK_COMMENT 52
|
||||||
#define TK_INT 53
|
#define TK_BOOL 53
|
||||||
#define TK_INTEGER 54
|
#define TK_TINYINT 54
|
||||||
#define TK_BIGINT 55
|
#define TK_SMALLINT 55
|
||||||
#define TK_FLOAT 56
|
#define TK_INT 56
|
||||||
#define TK_DOUBLE 57
|
#define TK_INTEGER 57
|
||||||
#define TK_BINARY 58
|
#define TK_BIGINT 58
|
||||||
#define TK_TIMESTAMP 59
|
#define TK_FLOAT 59
|
||||||
#define TK_NCHAR 60
|
#define TK_DOUBLE 60
|
||||||
#define TK_UNSIGNED 61
|
#define TK_BINARY 61
|
||||||
#define TK_JSON 62
|
#define TK_TIMESTAMP 62
|
||||||
#define TK_VARCHAR 63
|
#define TK_NCHAR 63
|
||||||
#define TK_MEDIUMBLOB 64
|
#define TK_UNSIGNED 64
|
||||||
#define TK_BLOB 65
|
#define TK_JSON 65
|
||||||
#define TK_VARBINARY 66
|
#define TK_VARCHAR 66
|
||||||
#define TK_DECIMAL 67
|
#define TK_MEDIUMBLOB 67
|
||||||
#define TK_SHOW 68
|
#define TK_BLOB 68
|
||||||
#define TK_DATABASES 69
|
#define TK_VARBINARY 69
|
||||||
#define TK_TABLES 70
|
#define TK_DECIMAL 70
|
||||||
#define TK_NK_FLOAT 71
|
#define TK_SMA 71
|
||||||
#define TK_NK_BOOL 72
|
#define TK_SHOW 72
|
||||||
#define TK_NK_VARIABLE 73
|
#define TK_DATABASES 73
|
||||||
#define TK_BETWEEN 74
|
#define TK_TABLES 74
|
||||||
#define TK_IS 75
|
#define TK_NK_FLOAT 75
|
||||||
#define TK_NULL 76
|
#define TK_NK_BOOL 76
|
||||||
#define TK_NK_LT 77
|
#define TK_NK_VARIABLE 77
|
||||||
#define TK_NK_GT 78
|
#define TK_BETWEEN 78
|
||||||
#define TK_NK_LE 79
|
#define TK_IS 79
|
||||||
#define TK_NK_GE 80
|
#define TK_NULL 80
|
||||||
#define TK_NK_NE 81
|
#define TK_NK_LT 81
|
||||||
#define TK_NK_EQ 82
|
#define TK_NK_GT 82
|
||||||
#define TK_LIKE 83
|
#define TK_NK_LE 83
|
||||||
#define TK_MATCH 84
|
#define TK_NK_GE 84
|
||||||
#define TK_NMATCH 85
|
#define TK_NK_NE 85
|
||||||
#define TK_IN 86
|
#define TK_NK_EQ 86
|
||||||
#define TK_FROM 87
|
#define TK_LIKE 87
|
||||||
#define TK_AS 88
|
#define TK_MATCH 88
|
||||||
#define TK_JOIN 89
|
#define TK_NMATCH 89
|
||||||
#define TK_ON 90
|
#define TK_IN 90
|
||||||
#define TK_INNER 91
|
#define TK_FROM 91
|
||||||
#define TK_SELECT 92
|
#define TK_AS 92
|
||||||
#define TK_DISTINCT 93
|
#define TK_JOIN 93
|
||||||
#define TK_WHERE 94
|
#define TK_ON 94
|
||||||
#define TK_PARTITION 95
|
#define TK_INNER 95
|
||||||
#define TK_BY 96
|
#define TK_SELECT 96
|
||||||
#define TK_SESSION 97
|
#define TK_DISTINCT 97
|
||||||
#define TK_STATE_WINDOW 98
|
#define TK_WHERE 98
|
||||||
#define TK_INTERVAL 99
|
#define TK_PARTITION 99
|
||||||
#define TK_SLIDING 100
|
#define TK_BY 100
|
||||||
#define TK_FILL 101
|
#define TK_SESSION 101
|
||||||
#define TK_VALUE 102
|
#define TK_STATE_WINDOW 102
|
||||||
#define TK_NONE 103
|
#define TK_INTERVAL 103
|
||||||
#define TK_PREV 104
|
#define TK_SLIDING 104
|
||||||
#define TK_LINEAR 105
|
#define TK_FILL 105
|
||||||
#define TK_NEXT 106
|
#define TK_VALUE 106
|
||||||
#define TK_GROUP 107
|
#define TK_NONE 107
|
||||||
#define TK_HAVING 108
|
#define TK_PREV 108
|
||||||
#define TK_ORDER 109
|
#define TK_LINEAR 109
|
||||||
#define TK_SLIMIT 110
|
#define TK_NEXT 110
|
||||||
#define TK_SOFFSET 111
|
#define TK_GROUP 111
|
||||||
#define TK_LIMIT 112
|
#define TK_HAVING 112
|
||||||
#define TK_OFFSET 113
|
#define TK_ORDER 113
|
||||||
#define TK_ASC 114
|
#define TK_SLIMIT 114
|
||||||
#define TK_DESC 115
|
#define TK_SOFFSET 115
|
||||||
#define TK_NULLS 116
|
#define TK_LIMIT 116
|
||||||
#define TK_FIRST 117
|
#define TK_OFFSET 117
|
||||||
#define TK_LAST 118
|
#define TK_ASC 118
|
||||||
|
#define TK_DESC 119
|
||||||
|
#define TK_NULLS 120
|
||||||
|
#define TK_FIRST 121
|
||||||
|
#define TK_LAST 122
|
||||||
|
|
||||||
#define TK_SPACE 300
|
#define TK_NK_SPACE 300
|
||||||
#define TK_NK_COMMENT 301
|
#define TK_NK_COMMENT 301
|
||||||
#define TK_ILLEGAL 302
|
#define TK_NK_ILLEGAL 302
|
||||||
#define TK_HEX 303 // hex number 0x123
|
#define TK_NK_HEX 303 // hex number 0x123
|
||||||
#define TK_OCT 304 // oct number
|
#define TK_NK_OCT 304 // oct number
|
||||||
#define TK_BIN 305 // bin format data 0b111
|
#define TK_NK_BIN 305 // bin format data 0b111
|
||||||
#define TK_FILE 306
|
#define TK_NK_FILE 306
|
||||||
#define TK_QUESTION 307 // denoting the placeholder of "?",when invoking statement bind query
|
#define TK_NK_QUESTION 307 // denoting the placeholder of "?",when invoking statement bind query
|
||||||
|
|
||||||
#define TK_NK_COLON 500
|
#define TK_NK_COLON 500
|
||||||
#define TK_NK_BITNOT 501
|
#define TK_NK_BITNOT 501
|
||||||
#define TK_INSERT 502
|
#define TK_INSERT 502
|
||||||
#define TK_INTO 503
|
#define TK_INTO 503
|
||||||
#define TK_NOW 504
|
#define TK_NOW 504
|
||||||
#define TK_TAGS 505
|
|
||||||
#define TK_USING 506
|
|
||||||
#define TK_VALUES 507
|
#define TK_VALUES 507
|
||||||
#define TK_IMPORT 507
|
#define TK_IMPORT 507
|
||||||
#define TK_SEMI 508
|
#define TK_SEMI 508
|
||||||
|
|
|
@ -58,6 +58,7 @@ typedef struct STableOptions {
|
||||||
int32_t keep;
|
int32_t keep;
|
||||||
int32_t ttl;
|
int32_t ttl;
|
||||||
char comments[TSDB_STB_COMMENT_LEN];
|
char comments[TSDB_STB_COMMENT_LEN];
|
||||||
|
SNodeList* pSma;
|
||||||
} STableOptions;
|
} STableOptions;
|
||||||
|
|
||||||
typedef struct SColumnDefNode {
|
typedef struct SColumnDefNode {
|
||||||
|
@ -73,10 +74,25 @@ typedef struct SCreateTableStmt {
|
||||||
char tableName[TSDB_TABLE_NAME_LEN];
|
char tableName[TSDB_TABLE_NAME_LEN];
|
||||||
bool ignoreExists;
|
bool ignoreExists;
|
||||||
SNodeList* pCols;
|
SNodeList* pCols;
|
||||||
|
SNodeList* pTags;
|
||||||
STableOptions options;
|
STableOptions options;
|
||||||
} SCreateTableStmt;
|
} SCreateTableStmt;
|
||||||
|
|
||||||
// CREATE TABLE [IF NOT EXISTS] [db_name.]tb_name (create_definition [, create_definitionn] ...) [table_options]
|
typedef struct SCreateSubTableStmt {
|
||||||
|
ENodeType type;
|
||||||
|
char dbName[TSDB_DB_NAME_LEN];
|
||||||
|
char tableName[TSDB_TABLE_NAME_LEN];
|
||||||
|
char useDbName[TSDB_DB_NAME_LEN];
|
||||||
|
char useTableName[TSDB_TABLE_NAME_LEN];
|
||||||
|
bool ignoreExists;
|
||||||
|
SNodeList* pSpecificTags;
|
||||||
|
SNodeList* pValsOfTags;
|
||||||
|
} SCreateSubTableStmt;
|
||||||
|
|
||||||
|
typedef struct SCreateMultiTableStmt {
|
||||||
|
ENodeType type;
|
||||||
|
SNodeList* pSubTables;
|
||||||
|
} SCreateMultiTableStmt;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,8 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_VNODE_MODIF_STMT,
|
QUERY_NODE_VNODE_MODIF_STMT,
|
||||||
QUERY_NODE_CREATE_DATABASE_STMT,
|
QUERY_NODE_CREATE_DATABASE_STMT,
|
||||||
QUERY_NODE_CREATE_TABLE_STMT,
|
QUERY_NODE_CREATE_TABLE_STMT,
|
||||||
|
QUERY_NODE_CREATE_SUBTABLE_STMT,
|
||||||
|
QUERY_NODE_CREATE_MULTI_TABLE_STMT,
|
||||||
QUERY_NODE_USE_DATABASE_STMT,
|
QUERY_NODE_USE_DATABASE_STMT,
|
||||||
QUERY_NODE_SHOW_DATABASES_STMT, // temp
|
QUERY_NODE_SHOW_DATABASES_STMT, // temp
|
||||||
QUERY_NODE_SHOW_TABLES_STMT, // temp
|
QUERY_NODE_SHOW_TABLES_STMT, // temp
|
||||||
|
|
|
@ -74,6 +74,7 @@ typedef struct SValueNode {
|
||||||
SExprNode node; // QUERY_NODE_VALUE
|
SExprNode node; // QUERY_NODE_VALUE
|
||||||
char* literal;
|
char* literal;
|
||||||
bool isDuration;
|
bool isDuration;
|
||||||
|
bool translate;
|
||||||
union {
|
union {
|
||||||
bool b;
|
bool b;
|
||||||
int64_t i;
|
int64_t i;
|
||||||
|
|
|
@ -94,11 +94,11 @@ void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type) {
|
||||||
bool sign = true;
|
bool sign = true;
|
||||||
|
|
||||||
int32_t base = 10;
|
int32_t base = 10;
|
||||||
if (type == TK_HEX) {
|
if (type == TK_NK_HEX) {
|
||||||
base = 16;
|
base = 16;
|
||||||
} else if (type == TK_OCT) {
|
} else if (type == TK_NK_OCT) {
|
||||||
base = 8;
|
base = 8;
|
||||||
} else if (type == TK_BIN) {
|
} else if (type == TK_NK_BIN) {
|
||||||
base = 2;
|
base = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TD_NODES_INT_H_
|
||||||
|
#define _TD_NODES_INT_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define nodesFatal(param, ...) qFatal("NODES: " param, __VA_ARGS__)
|
||||||
|
#define nodesError(param, ...) qError("NODES: " param, __VA_ARGS__)
|
||||||
|
#define nodesWarn(param, ...) qWarn("NODES: " param, __VA_ARGS__)
|
||||||
|
#define nodesInfo(param, ...) qInfo("NODES: " param, __VA_ARGS__)
|
||||||
|
#define nodesDebug(param, ...) qDebug("NODES: " param, __VA_ARGS__)
|
||||||
|
#define nodesTrace(param, ...) qTrace("NODES: " param, __VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*_TD_NODES_INT_H_*/
|
|
@ -13,6 +13,7 @@
|
||||||
* 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 "nodesint.h"
|
||||||
#include "plannodes.h"
|
#include "plannodes.h"
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
|
@ -221,7 +222,7 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("nodesCloneNode unknown node = %s\n", nodesNodeName(nodeType(pNode)));
|
nodesWarn("nodesCloneNode unknown node = %s", nodesNodeName(nodeType(pNode)));
|
||||||
return pDst;
|
return pDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* 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 "nodesint.h"
|
||||||
#include "plannodes.h"
|
#include "plannodes.h"
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
@ -127,9 +128,8 @@ const char* nodesNodeName(ENodeType type) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
static char tmp[20];
|
nodesWarn("nodesNodeName unknown node = %d", type);
|
||||||
snprintf(tmp, sizeof(tmp), "Unknown %d", type);
|
return "UnknownNode";
|
||||||
return tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t nodeListToJson(SJson* pJson, const char* pName, const SNodeList* pList) {
|
static int32_t nodeListToJson(SJson* pJson, const char* pName, const SNodeList* pList) {
|
||||||
|
@ -871,19 +871,13 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) {
|
||||||
|
|
||||||
static const char* jkValueLiteral = "Literal";
|
static const char* jkValueLiteral = "Literal";
|
||||||
static const char* jkValueDuration = "Duration";
|
static const char* jkValueDuration = "Duration";
|
||||||
|
static const char* jkValueTranslate = "Translate";
|
||||||
static const char* jkValueDatum = "Datum";
|
static const char* jkValueDatum = "Datum";
|
||||||
|
|
||||||
static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t datumToJson(const void* pObj, SJson* pJson) {
|
||||||
const SValueNode* pNode = (const SValueNode*)pObj;
|
const SValueNode* pNode = (const SValueNode*)pObj;
|
||||||
|
|
||||||
int32_t code = exprNodeToJson(pObj, pJson);
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->literal);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = tjsonAddBoolToObject(pJson, jkValueDuration, pNode->isDuration);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
switch (pNode->node.resType.type) {
|
switch (pNode->node.resType.type) {
|
||||||
case TSDB_DATA_TYPE_NULL:
|
case TSDB_DATA_TYPE_NULL:
|
||||||
break;
|
break;
|
||||||
|
@ -920,22 +914,34 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return code ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
|
const SValueNode* pNode = (const SValueNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = exprNodeToJson(pObj, pJson);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->literal);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkValueDuration, pNode->isDuration);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkValueTranslate, pNode->translate);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && pNode->translate) {
|
||||||
|
code = datumToJson(pNode, pJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
|
static int32_t jsonToDatum(const SJson* pJson, void* pObj) {
|
||||||
SValueNode* pNode = (SValueNode*)pObj;
|
SValueNode* pNode = (SValueNode*)pObj;
|
||||||
|
|
||||||
int32_t code = jsonToExprNode(pJson, pObj);
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = tjsonDupStringValue(pJson, jkValueLiteral, &pNode->literal);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = tjsonGetBoolValue(pJson, jkValueDuration, &pNode->isDuration);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
switch (pNode->node.resType.type) {
|
switch (pNode->node.resType.type) {
|
||||||
case TSDB_DATA_TYPE_NULL:
|
case TSDB_DATA_TYPE_NULL:
|
||||||
break;
|
break;
|
||||||
|
@ -972,6 +978,25 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
|
||||||
|
SValueNode* pNode = (SValueNode*)pObj;
|
||||||
|
|
||||||
|
int32_t code = jsonToExprNode(pJson, pObj);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonDupStringValue(pJson, jkValueLiteral, &pNode->literal);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkValueDuration, &pNode->isDuration);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkValueTranslate, &pNode->translate);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && pNode->translate) {
|
||||||
|
code = jsonToDatum(pJson, pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -1365,7 +1390,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("================================ specificNodeToJson unknown node = %s\n", nodesNodeName(nodeType(pObj)));
|
nodesWarn("specificNodeToJson unknown node = %s", nodesNodeName(nodeType(pObj)));
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1434,7 +1459,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("================================ jsonToSpecificNode unknown node = %s\n", nodesNodeName(nodeType(pObj)));
|
nodesWarn("jsonToSpecificNode unknown node = %s", nodesNodeName(nodeType(pObj)));
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1450,6 +1475,9 @@ static int32_t nodeToJson(const void* pObj, SJson* pJson) {
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddObject(pJson, nodesNodeName(pNode->type), specificNodeToJson, pNode);
|
code = tjsonAddObject(pJson, nodesNodeName(pNode->type), specificNodeToJson, pNode);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
nodesError("%s ToJson error", nodesNodeName(pNode->type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -1464,7 +1492,7 @@ static int32_t jsonToNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonToObject(pJson, nodesNodeName(pNode->type), jsonToSpecificNode, pNode);
|
code = tjsonToObject(pJson, nodesNodeName(pNode->type), jsonToSpecificNode, pNode);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
printf("%s toNode error\n", nodesNodeName(pNode->type));
|
nodesError("%s toNode error", nodesNodeName(pNode->type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cmdnodes.h"
|
#include "cmdnodes.h"
|
||||||
#include "querynodes.h"
|
#include "nodesint.h"
|
||||||
#include "plannodes.h"
|
#include "plannodes.h"
|
||||||
|
#include "querynodes.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "taos.h"
|
|
||||||
#include "thash.h"
|
#include "thash.h"
|
||||||
|
|
||||||
static SNode* makeNode(ENodeType type, size_t size) {
|
static SNode* makeNode(ENodeType type, size_t size) {
|
||||||
|
@ -84,6 +84,10 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
||||||
return makeNode(type, sizeof(SCreateDatabaseStmt));
|
return makeNode(type, sizeof(SCreateDatabaseStmt));
|
||||||
case QUERY_NODE_CREATE_TABLE_STMT:
|
case QUERY_NODE_CREATE_TABLE_STMT:
|
||||||
return makeNode(type, sizeof(SCreateTableStmt));
|
return makeNode(type, sizeof(SCreateTableStmt));
|
||||||
|
case QUERY_NODE_CREATE_SUBTABLE_STMT:
|
||||||
|
return makeNode(type, sizeof(SCreateSubTableStmt));
|
||||||
|
case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
|
||||||
|
return makeNode(type, sizeof(SCreateMultiTableStmt));
|
||||||
case QUERY_NODE_USE_DATABASE_STMT:
|
case QUERY_NODE_USE_DATABASE_STMT:
|
||||||
return makeNode(type, sizeof(SUseDatabaseStmt));
|
return makeNode(type, sizeof(SUseDatabaseStmt));
|
||||||
case QUERY_NODE_SHOW_DATABASES_STMT:
|
case QUERY_NODE_SHOW_DATABASES_STMT:
|
||||||
|
@ -132,7 +136,7 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("================================ nodesMakeNode unknown node = %s\n", nodesNodeName(type));
|
nodesError("nodesMakeNode unknown node = %s", nodesNodeName(type));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,15 +110,20 @@ typedef enum ETableOptionType {
|
||||||
TABLE_OPTION_KEEP = 0,
|
TABLE_OPTION_KEEP = 0,
|
||||||
TABLE_OPTION_TTL,
|
TABLE_OPTION_TTL,
|
||||||
TABLE_OPTION_COMMENT,
|
TABLE_OPTION_COMMENT,
|
||||||
|
TABLE_OPTION_SMA,
|
||||||
|
|
||||||
TABLE_OPTION_MAX
|
TABLE_OPTION_MAX
|
||||||
} ETableOptionType;
|
} ETableOptionType;
|
||||||
STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt);
|
STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt);
|
||||||
STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal);
|
STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal);
|
||||||
|
STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma);
|
||||||
SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment);
|
SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment);
|
||||||
SDataType createDataType(uint8_t type);
|
SDataType createDataType(uint8_t type);
|
||||||
SDataType createVarLenDataType(uint8_t type, const SToken* pLen);
|
SDataType createVarLenDataType(uint8_t type, const SToken* pLen);
|
||||||
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, STableOptions* pOptions);
|
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions);
|
||||||
|
SNode* createCreateSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists,
|
||||||
|
const STokenPair* pFullTableName, const STokenPair* pUseFullTableName, SNodeList* pSpecificTags, SNodeList* pValsOfTags);
|
||||||
|
SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables);
|
||||||
|
|
||||||
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName);
|
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type { SToken }
|
%token_type { SToken }
|
||||||
%default_type { SNode* }
|
%default_type { SNode* }
|
||||||
%default_destructor { PARSER_DESTRUCTOR_TRACE; nodesDestroyNode($$); }
|
%default_destructor { nodesDestroyNode($$); }
|
||||||
|
|
||||||
%extra_argument { SAstCreateContext* pCxt }
|
%extra_argument { SAstCreateContext* pCxt }
|
||||||
|
|
||||||
|
@ -21,16 +21,6 @@
|
||||||
#include "ttoken.h"
|
#include "ttoken.h"
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
#include "astCreateFuncs.h"
|
#include "astCreateFuncs.h"
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define PARSER_TRACE printf("lemon rule = %s\n", yyRuleName[yyruleno])
|
|
||||||
#define PARSER_DESTRUCTOR_TRACE printf("lemon destroy token = %s\n", yyTokenName[yymajor])
|
|
||||||
#define PARSER_COMPLETE printf("parsing complete!\n" )
|
|
||||||
#else
|
|
||||||
#define PARSER_TRACE
|
|
||||||
#define PARSER_DESTRUCTOR_TRACE
|
|
||||||
#define PARSER_COMPLETE
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%syntax_error {
|
%syntax_error {
|
||||||
|
@ -51,8 +41,6 @@
|
||||||
pCxt->valid = false;
|
pCxt->valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
%parse_accept { PARSER_COMPLETE; }
|
|
||||||
|
|
||||||
%left OR.
|
%left OR.
|
||||||
%left AND.
|
%left AND.
|
||||||
//%right NOT.
|
//%right NOT.
|
||||||
|
@ -68,6 +56,7 @@
|
||||||
cmd ::= CREATE DATABASE exists_opt(A) db_name(B) db_options(C). { pCxt->pRootNode = createCreateDatabaseStmt(pCxt, A, &B, C);}
|
cmd ::= CREATE DATABASE exists_opt(A) db_name(B) db_options(C). { pCxt->pRootNode = createCreateDatabaseStmt(pCxt, A, &B, C);}
|
||||||
|
|
||||||
%type exists_opt { bool }
|
%type exists_opt { bool }
|
||||||
|
%destructor exists_opt { }
|
||||||
exists_opt(A) ::= IF NOT EXISTS. { A = true; }
|
exists_opt(A) ::= IF NOT EXISTS. { A = true; }
|
||||||
exists_opt(A) ::= . { A = false; }
|
exists_opt(A) ::= . { A = false; }
|
||||||
|
|
||||||
|
@ -76,7 +65,7 @@ exists_opt(A) ::= .
|
||||||
db_options(A) ::= . { A = createDefaultDatabaseOptions(pCxt); }
|
db_options(A) ::= . { A = createDefaultDatabaseOptions(pCxt); }
|
||||||
db_options(A) ::= db_options(B) BLOCKS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_BLOCKS, &C); }
|
db_options(A) ::= db_options(B) BLOCKS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_BLOCKS, &C); }
|
||||||
db_options(A) ::= db_options(B) CACHE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_CACHE, &C); }
|
db_options(A) ::= db_options(B) CACHE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_CACHE, &C); }
|
||||||
db_options(A) ::= db_options(B) CACHELAST NK_INTEGER(X)(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_CACHELAST, &C); }
|
db_options(A) ::= db_options(B) CACHELAST NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_CACHELAST, &C); }
|
||||||
db_options(A) ::= db_options(B) COMP NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_COMP, &C); }
|
db_options(A) ::= db_options(B) COMP NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_COMP, &C); }
|
||||||
db_options(A) ::= db_options(B) DAYS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_DAYS, &C); }
|
db_options(A) ::= db_options(B) DAYS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_DAYS, &C); }
|
||||||
db_options(A) ::= db_options(B) FSYNC NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_FSYNC, &C); }
|
db_options(A) ::= db_options(B) FSYNC NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_FSYNC, &C); }
|
||||||
|
@ -89,15 +78,34 @@ db_options(A) ::= db_options(B) REPLICA NK_INTEGER(C).
|
||||||
db_options(A) ::= db_options(B) TTL NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_TTL, &C); }
|
db_options(A) ::= db_options(B) TTL NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_TTL, &C); }
|
||||||
db_options(A) ::= db_options(B) WAL NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_WAL, &C); }
|
db_options(A) ::= db_options(B) WAL NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_WAL, &C); }
|
||||||
db_options(A) ::= db_options(B) VGROUPS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_VGROUPS, &C); }
|
db_options(A) ::= db_options(B) VGROUPS NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_VGROUPS, &C); }
|
||||||
db_options(A) ::= db_options(B) SINGLESTABLE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_SINGLESTABLE, &C); }
|
db_options(A) ::= db_options(B) SINGLE_STABLE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_SINGLESTABLE, &C); }
|
||||||
db_options(A) ::= db_options(B) STREAMMODE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_STREAMMODE, &C); }
|
db_options(A) ::= db_options(B) STREAM_MODE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_STREAMMODE, &C); }
|
||||||
|
|
||||||
/************************************************ create database *****************************************************/
|
/************************************************ create database *****************************************************/
|
||||||
cmd ::= USE db_name(A). { pCxt->pRootNode = createUseDatabaseStmt(pCxt, &A);}
|
cmd ::= USE db_name(A). { pCxt->pRootNode = createUseDatabaseStmt(pCxt, &A);}
|
||||||
|
|
||||||
/************************************************ create table *******************************************************/
|
/************************************************ create table/stable *************************************************/
|
||||||
cmd ::= CREATE TABLE exists_opt(A) full_table_name(B)
|
cmd ::= CREATE TABLE exists_opt(A) full_table_name(B)
|
||||||
NK_LP column_def_list(C) NK_RP table_options(D). { pCxt->pRootNode = createCreateTableStmt(pCxt, A, &B, C, D);}
|
NK_LP column_def_list(C) NK_RP tags_def_opt(D) table_options(E). { pCxt->pRootNode = createCreateTableStmt(pCxt, A, &B, C, D, E);}
|
||||||
|
|
||||||
|
cmd ::= CREATE TABLE multi_create_clause(A). { pCxt->pRootNode = createCreateMultiTableStmt(pCxt, A);}
|
||||||
|
|
||||||
|
cmd ::= CREATE STABLE exists_opt(A) full_table_name(B)
|
||||||
|
NK_LP column_def_list(C) NK_RP tags_def(D) table_options(E). { pCxt->pRootNode = createCreateTableStmt(pCxt, A, &B, C, D, E);}
|
||||||
|
|
||||||
|
%type multi_create_clause { SNodeList* }
|
||||||
|
%destructor multi_create_clause { nodesDestroyList($$); }
|
||||||
|
multi_create_clause(A) ::= create_subtable_clause(B). { A = createNodeList(pCxt, B); }
|
||||||
|
multi_create_clause(A) ::= multi_create_clause(B) create_subtable_clause(C). { A = addNodeToList(pCxt, B, C); }
|
||||||
|
|
||||||
|
create_subtable_clause(A) ::=
|
||||||
|
exists_opt(B) full_table_name(C) USING full_table_name(D)
|
||||||
|
specific_tags_opt(E) TAGS NK_LP literal_list(F) NK_RP. { A = createCreateSubTableStmt(pCxt, B, &C, &D, E, F); }
|
||||||
|
|
||||||
|
%type specific_tags_opt { SNodeList* }
|
||||||
|
%destructor specific_tags_opt { nodesDestroyList($$); }
|
||||||
|
specific_tags_opt(A) ::= . { A = NULL; }
|
||||||
|
specific_tags_opt(A) ::= NK_LP col_name_list(B) NK_RP. { A = B; }
|
||||||
|
|
||||||
%type full_table_name { STokenPair }
|
%type full_table_name { STokenPair }
|
||||||
%destructor full_table_name { }
|
%destructor full_table_name { }
|
||||||
|
@ -138,247 +146,247 @@ type_name(A) ::= DECIMAL.
|
||||||
type_name(A) ::= DECIMAL NK_LP NK_INTEGER NK_RP. { A = createDataType(TSDB_DATA_TYPE_DECIMAL); }
|
type_name(A) ::= DECIMAL NK_LP NK_INTEGER NK_RP. { A = createDataType(TSDB_DATA_TYPE_DECIMAL); }
|
||||||
type_name(A) ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP. { A = createDataType(TSDB_DATA_TYPE_DECIMAL); }
|
type_name(A) ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP. { A = createDataType(TSDB_DATA_TYPE_DECIMAL); }
|
||||||
|
|
||||||
|
%type tags_def_opt { SNodeList* }
|
||||||
|
%destructor tags_def_opt { nodesDestroyList($$); }
|
||||||
|
tags_def_opt(A) ::= . { A = NULL; }
|
||||||
|
tags_def_opt(A) ::= tags_def(B). { A = B; }
|
||||||
|
|
||||||
|
%type tags_def { SNodeList* }
|
||||||
|
%destructor tags_def { nodesDestroyList($$); }
|
||||||
|
tags_def(A) ::= TAGS NK_LP column_def_list(B) NK_RP. { A = B; }
|
||||||
|
|
||||||
%type table_options { STableOptions* }
|
%type table_options { STableOptions* }
|
||||||
%destructor table_options { tfree($$); }
|
%destructor table_options { tfree($$); }
|
||||||
table_options(A) ::= . { A = createDefaultTableOptions(pCxt);}
|
table_options(A) ::= . { A = createDefaultTableOptions(pCxt);}
|
||||||
table_options(A) ::= table_options(B) COMMENT NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_COMMENT, &C); }
|
table_options(A) ::= table_options(B) COMMENT NK_STRING(C). { A = setTableOption(pCxt, B, TABLE_OPTION_COMMENT, &C); }
|
||||||
table_options(A) ::= table_options(B) KEEP NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); }
|
table_options(A) ::= table_options(B) KEEP NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); }
|
||||||
table_options(A) ::= table_options(B) TTL NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_TTL, &C); }
|
table_options(A) ::= table_options(B) TTL NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_TTL, &C); }
|
||||||
|
table_options(A) ::= table_options(B) SMA NK_LP col_name_list(C) NK_RP. { A = setTableSmaOption(pCxt, B, C); }
|
||||||
|
|
||||||
|
%type col_name_list { SNodeList* }
|
||||||
|
%destructor col_name_list { nodesDestroyList($$); }
|
||||||
|
col_name_list(A) ::= col_name(B). { A = createNodeList(pCxt, B); }
|
||||||
|
col_name_list(A) ::= col_name_list(B) NK_COMMA col_name(C). { A = addNodeToList(pCxt, B, C); }
|
||||||
|
|
||||||
|
col_name(A) ::= column_name(B). { A = createColumnNode(pCxt, NULL, &B); }
|
||||||
|
|
||||||
/************************************************ show ***************************************************************/
|
/************************************************ show ***************************************************************/
|
||||||
cmd ::= SHOW DATABASES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); }
|
cmd ::= SHOW DATABASES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); }
|
||||||
cmd ::= SHOW TABLES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TABLES_STMT); }
|
cmd ::= SHOW TABLES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TABLES_STMT); }
|
||||||
|
|
||||||
/************************************************ select *************************************************************/
|
/************************************************ select *************************************************************/
|
||||||
cmd ::= query_expression(A). { PARSER_TRACE; pCxt->pRootNode = A; }
|
cmd ::= query_expression(A). { pCxt->pRootNode = A; }
|
||||||
|
|
||||||
/************************************************ literal *************************************************************/
|
/************************************************ literal *************************************************************/
|
||||||
literal(A) ::= NK_INTEGER(B). { PARSER_TRACE; A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &B)); }
|
literal(A) ::= NK_INTEGER(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &B)); }
|
||||||
literal(A) ::= NK_FLOAT(B). { PARSER_TRACE; A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &B)); }
|
literal(A) ::= NK_FLOAT(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &B)); }
|
||||||
literal(A) ::= NK_STRING(B). { PARSER_TRACE; A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &B)); }
|
literal(A) ::= NK_STRING(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &B)); }
|
||||||
literal(A) ::= NK_BOOL(B). { PARSER_TRACE; A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &B)); }
|
literal(A) ::= NK_BOOL(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &B)); }
|
||||||
literal(A) ::= TIMESTAMP(B) NK_STRING(C). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &C, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &C)); }
|
literal(A) ::= TIMESTAMP(B) NK_STRING(C). { A = createRawExprNodeExt(pCxt, &B, &C, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &C)); }
|
||||||
literal(A) ::= duration_literal(B). { PARSER_TRACE; A = B; }
|
literal(A) ::= duration_literal(B). { A = B; }
|
||||||
|
|
||||||
duration_literal(A) ::= NK_VARIABLE(B). { PARSER_TRACE; A = createRawExprNode(pCxt, &B, createDurationValueNode(pCxt, &B)); }
|
duration_literal(A) ::= NK_VARIABLE(B). { A = createRawExprNode(pCxt, &B, createDurationValueNode(pCxt, &B)); }
|
||||||
|
|
||||||
%type literal_list { SNodeList* }
|
%type literal_list { SNodeList* }
|
||||||
%destructor literal_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor literal_list { nodesDestroyList($$); }
|
||||||
literal_list(A) ::= literal(B). { PARSER_TRACE; A = createNodeList(pCxt, releaseRawExprNode(pCxt, B)); }
|
literal_list(A) ::= literal(B). { A = createNodeList(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||||
literal_list(A) ::= literal_list(B) NK_COMMA literal(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, releaseRawExprNode(pCxt, C)); }
|
literal_list(A) ::= literal_list(B) NK_COMMA literal(C). { A = addNodeToList(pCxt, B, releaseRawExprNode(pCxt, C)); }
|
||||||
|
|
||||||
/************************************************ names and identifiers ***********************************************/
|
/************************************************ names and identifiers ***********************************************/
|
||||||
%type db_name { SToken }
|
%type db_name { SToken }
|
||||||
%destructor db_name { PARSER_DESTRUCTOR_TRACE; }
|
%destructor db_name { }
|
||||||
db_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
db_name(A) ::= NK_ID(B). { A = B; }
|
||||||
|
|
||||||
%type table_name { SToken }
|
%type table_name { SToken }
|
||||||
%destructor table_name { PARSER_DESTRUCTOR_TRACE; }
|
%destructor table_name { }
|
||||||
table_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
table_name(A) ::= NK_ID(B). { A = B; }
|
||||||
|
|
||||||
%type column_name { SToken }
|
%type column_name { SToken }
|
||||||
%destructor column_name { PARSER_DESTRUCTOR_TRACE; }
|
%destructor column_name { }
|
||||||
column_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
column_name(A) ::= NK_ID(B). { A = B; }
|
||||||
|
|
||||||
%type function_name { SToken }
|
%type function_name { SToken }
|
||||||
%destructor function_name { PARSER_DESTRUCTOR_TRACE; }
|
%destructor function_name { }
|
||||||
function_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
function_name(A) ::= NK_ID(B). { A = B; }
|
||||||
|
|
||||||
%type table_alias { SToken }
|
%type table_alias { SToken }
|
||||||
%destructor table_alias { PARSER_DESTRUCTOR_TRACE; }
|
%destructor table_alias { }
|
||||||
table_alias(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
table_alias(A) ::= NK_ID(B). { A = B; }
|
||||||
|
|
||||||
%type column_alias { SToken }
|
%type column_alias { SToken }
|
||||||
%destructor column_alias { PARSER_DESTRUCTOR_TRACE; }
|
%destructor column_alias { }
|
||||||
column_alias(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
column_alias(A) ::= NK_ID(B). { A = B; }
|
||||||
|
|
||||||
/************************************************ expression **********************************************************/
|
/************************************************ expression **********************************************************/
|
||||||
expression(A) ::= literal(B). { PARSER_TRACE; A = B; }
|
expression(A) ::= literal(B). { A = B; }
|
||||||
//expression(A) ::= NK_QUESTION(B). { PARSER_TRACE; A = B; }
|
//expression(A) ::= NK_QUESTION(B). { A = B; }
|
||||||
//expression(A) ::= pseudo_column(B). { PARSER_TRACE; A = B; }
|
//expression(A) ::= pseudo_column(B). { A = B; }
|
||||||
expression(A) ::= column_reference(B). { PARSER_TRACE; A = B; }
|
expression(A) ::= column_reference(B). { A = B; }
|
||||||
expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
|
||||||
expression(A) ::= function_name(B) NK_LP NK_STAR(C) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, createNodeList(pCxt, createColumnNode(pCxt, NULL, &C)))); }
|
expression(A) ::= function_name(B) NK_LP NK_STAR(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, createNodeList(pCxt, createColumnNode(pCxt, NULL, &C)))); }
|
||||||
//expression(A) ::= cast_expression(B). { PARSER_TRACE; A = B; }
|
//expression(A) ::= cast_expression(B). { A = B; }
|
||||||
//expression(A) ::= case_expression(B). { PARSER_TRACE; A = B; }
|
//expression(A) ::= case_expression(B). { A = B; }
|
||||||
expression(A) ::= subquery(B). { PARSER_TRACE; A = B; }
|
expression(A) ::= subquery(B). { A = B; }
|
||||||
expression(A) ::= NK_LP(B) expression(C) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &D, releaseRawExprNode(pCxt, C)); }
|
expression(A) ::= NK_LP(B) expression(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, releaseRawExprNode(pCxt, C)); }
|
||||||
expression(A) ::= NK_PLUS(B) expression(C). {
|
expression(A) ::= NK_PLUS(B) expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken t = getTokenFromRawExprNode(pCxt, C);
|
SToken t = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &B, &t, releaseRawExprNode(pCxt, C));
|
A = createRawExprNodeExt(pCxt, &B, &t, releaseRawExprNode(pCxt, C));
|
||||||
}
|
}
|
||||||
expression(A) ::= NK_MINUS(B) expression(C). {
|
expression(A) ::= NK_MINUS(B) expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken t = getTokenFromRawExprNode(pCxt, C);
|
SToken t = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &B, &t, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, C), NULL));
|
A = createRawExprNodeExt(pCxt, &B, &t, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, C), NULL));
|
||||||
}
|
}
|
||||||
expression(A) ::= expression(B) NK_PLUS expression(C). {
|
expression(A) ::= expression(B) NK_PLUS expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||||
}
|
}
|
||||||
expression(A) ::= expression(B) NK_MINUS expression(C). {
|
expression(A) ::= expression(B) NK_MINUS expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||||
}
|
}
|
||||||
expression(A) ::= expression(B) NK_STAR expression(C). {
|
expression(A) ::= expression(B) NK_STAR expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||||
}
|
}
|
||||||
expression(A) ::= expression(B) NK_SLASH expression(C). {
|
expression(A) ::= expression(B) NK_SLASH expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||||
}
|
}
|
||||||
expression(A) ::= expression(B) NK_REM expression(C). {
|
expression(A) ::= expression(B) NK_REM expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MOD, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MOD, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||||
}
|
}
|
||||||
|
|
||||||
%type expression_list { SNodeList* }
|
%type expression_list { SNodeList* }
|
||||||
%destructor expression_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor expression_list { nodesDestroyList($$); }
|
||||||
expression_list(A) ::= expression(B). { PARSER_TRACE; A = createNodeList(pCxt, releaseRawExprNode(pCxt, B)); }
|
expression_list(A) ::= expression(B). { A = createNodeList(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||||
expression_list(A) ::= expression_list(B) NK_COMMA expression(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, releaseRawExprNode(pCxt, C)); }
|
expression_list(A) ::= expression_list(B) NK_COMMA expression(C). { A = addNodeToList(pCxt, B, releaseRawExprNode(pCxt, C)); }
|
||||||
|
|
||||||
column_reference(A) ::= column_name(B). { PARSER_TRACE; A = createRawExprNode(pCxt, &B, createColumnNode(pCxt, NULL, &B)); }
|
column_reference(A) ::= column_name(B). { A = createRawExprNode(pCxt, &B, createColumnNode(pCxt, NULL, &B)); }
|
||||||
column_reference(A) ::= table_name(B) NK_DOT column_name(C). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &C, createColumnNode(pCxt, &B, &C)); }
|
column_reference(A) ::= table_name(B) NK_DOT column_name(C). { A = createRawExprNodeExt(pCxt, &B, &C, createColumnNode(pCxt, &B, &C)); }
|
||||||
|
|
||||||
//pseudo_column(A) ::= NK_NOW. { PARSER_TRACE; A = createFunctionNode(pCxt, NULL, NULL); }
|
//pseudo_column(A) ::= NK_NOW. { A = createFunctionNode(pCxt, NULL, NULL); }
|
||||||
|
|
||||||
/************************************************ predicate ***********************************************************/
|
/************************************************ predicate ***********************************************************/
|
||||||
predicate(A) ::= expression(B) compare_op(C) expression(D). {
|
predicate(A) ::= expression(B) compare_op(C) expression(D). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, D);
|
SToken e = getTokenFromRawExprNode(pCxt, D);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, C, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, D)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, C, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, D)));
|
||||||
}
|
}
|
||||||
//predicate(A) ::= expression(B) compare_op sub_type expression(B).
|
//predicate(A) ::= expression(B) compare_op sub_type expression(B).
|
||||||
predicate(A) ::= expression(B) BETWEEN expression(C) AND expression(D). {
|
predicate(A) ::= expression(B) BETWEEN expression(C) AND expression(D). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, D);
|
SToken e = getTokenFromRawExprNode(pCxt, D);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, D)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, D)));
|
||||||
}
|
}
|
||||||
predicate(A) ::= expression(B) NOT BETWEEN expression(C) AND expression(D). {
|
predicate(A) ::= expression(B) NOT BETWEEN expression(C) AND expression(D). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, D);
|
SToken e = getTokenFromRawExprNode(pCxt, D);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, D)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, C), releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, D)));
|
||||||
}
|
}
|
||||||
predicate(A) ::= expression(B) IS NULL(C). {
|
predicate(A) ::= expression(B) IS NULL(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, B), NULL));
|
A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, B), NULL));
|
||||||
}
|
}
|
||||||
predicate(A) ::= expression(B) IS NOT NULL(C). {
|
predicate(A) ::= expression(B) IS NOT NULL(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, B), NULL));
|
A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, B), NULL));
|
||||||
}
|
}
|
||||||
predicate(A) ::= expression(B) in_op(C) in_predicate_value(D). {
|
predicate(A) ::= expression(B) in_op(C) in_predicate_value(D). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, D);
|
SToken e = getTokenFromRawExprNode(pCxt, D);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, C, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, D)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, C, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, D)));
|
||||||
}
|
}
|
||||||
|
|
||||||
%type compare_op { EOperatorType }
|
%type compare_op { EOperatorType }
|
||||||
%destructor compare_op { PARSER_DESTRUCTOR_TRACE; }
|
%destructor compare_op { }
|
||||||
compare_op(A) ::= NK_LT. { PARSER_TRACE; A = OP_TYPE_LOWER_THAN; }
|
compare_op(A) ::= NK_LT. { A = OP_TYPE_LOWER_THAN; }
|
||||||
compare_op(A) ::= NK_GT. { PARSER_TRACE; A = OP_TYPE_GREATER_THAN; }
|
compare_op(A) ::= NK_GT. { A = OP_TYPE_GREATER_THAN; }
|
||||||
compare_op(A) ::= NK_LE. { PARSER_TRACE; A = OP_TYPE_LOWER_EQUAL; }
|
compare_op(A) ::= NK_LE. { A = OP_TYPE_LOWER_EQUAL; }
|
||||||
compare_op(A) ::= NK_GE. { PARSER_TRACE; A = OP_TYPE_GREATER_EQUAL; }
|
compare_op(A) ::= NK_GE. { A = OP_TYPE_GREATER_EQUAL; }
|
||||||
compare_op(A) ::= NK_NE. { PARSER_TRACE; A = OP_TYPE_NOT_EQUAL; }
|
compare_op(A) ::= NK_NE. { A = OP_TYPE_NOT_EQUAL; }
|
||||||
compare_op(A) ::= NK_EQ. { PARSER_TRACE; A = OP_TYPE_EQUAL; }
|
compare_op(A) ::= NK_EQ. { A = OP_TYPE_EQUAL; }
|
||||||
compare_op(A) ::= LIKE. { PARSER_TRACE; A = OP_TYPE_LIKE; }
|
compare_op(A) ::= LIKE. { A = OP_TYPE_LIKE; }
|
||||||
compare_op(A) ::= NOT LIKE. { PARSER_TRACE; A = OP_TYPE_NOT_LIKE; }
|
compare_op(A) ::= NOT LIKE. { A = OP_TYPE_NOT_LIKE; }
|
||||||
compare_op(A) ::= MATCH. { PARSER_TRACE; A = OP_TYPE_MATCH; }
|
compare_op(A) ::= MATCH. { A = OP_TYPE_MATCH; }
|
||||||
compare_op(A) ::= NMATCH. { PARSER_TRACE; A = OP_TYPE_NMATCH; }
|
compare_op(A) ::= NMATCH. { A = OP_TYPE_NMATCH; }
|
||||||
|
|
||||||
%type in_op { EOperatorType }
|
%type in_op { EOperatorType }
|
||||||
%destructor in_op { PARSER_DESTRUCTOR_TRACE; }
|
%destructor in_op { }
|
||||||
in_op(A) ::= IN. { PARSER_TRACE; A = OP_TYPE_IN; }
|
in_op(A) ::= IN. { A = OP_TYPE_IN; }
|
||||||
in_op(A) ::= NOT IN. { PARSER_TRACE; A = OP_TYPE_NOT_IN; }
|
in_op(A) ::= NOT IN. { A = OP_TYPE_NOT_IN; }
|
||||||
|
|
||||||
in_predicate_value(A) ::= NK_LP(C) expression_list(B) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &C, &D, createNodeListNode(pCxt, B)); }
|
in_predicate_value(A) ::= NK_LP(C) expression_list(B) NK_RP(D). { A = createRawExprNodeExt(pCxt, &C, &D, createNodeListNode(pCxt, B)); }
|
||||||
|
|
||||||
/************************************************ boolean_value_expression ********************************************/
|
/************************************************ boolean_value_expression ********************************************/
|
||||||
boolean_value_expression(A) ::= boolean_primary(B). { PARSER_TRACE; A = B; }
|
boolean_value_expression(A) ::= boolean_primary(B). { A = B; }
|
||||||
boolean_value_expression(A) ::= NOT(C) boolean_primary(B). {
|
boolean_value_expression(A) ::= NOT(C) boolean_primary(B). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, B);
|
SToken e = getTokenFromRawExprNode(pCxt, B);
|
||||||
A = createRawExprNodeExt(pCxt, &C, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, B), NULL));
|
A = createRawExprNodeExt(pCxt, &C, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, B), NULL));
|
||||||
}
|
}
|
||||||
boolean_value_expression(A) ::=
|
boolean_value_expression(A) ::=
|
||||||
boolean_value_expression(B) OR boolean_value_expression(C). {
|
boolean_value_expression(B) OR boolean_value_expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||||
}
|
}
|
||||||
boolean_value_expression(A) ::=
|
boolean_value_expression(A) ::=
|
||||||
boolean_value_expression(B) AND boolean_value_expression(C). {
|
boolean_value_expression(B) AND boolean_value_expression(C). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||||
A = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
A = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean_primary(A) ::= predicate(B). { PARSER_TRACE; A = B; }
|
boolean_primary(A) ::= predicate(B). { A = B; }
|
||||||
boolean_primary(A) ::= NK_LP(C) boolean_value_expression(B) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &C, &D, releaseRawExprNode(pCxt, B)); }
|
boolean_primary(A) ::= NK_LP(C) boolean_value_expression(B) NK_RP(D). { A = createRawExprNodeExt(pCxt, &C, &D, releaseRawExprNode(pCxt, B)); }
|
||||||
|
|
||||||
/************************************************ common_expression ********************************************/
|
/************************************************ common_expression ********************************************/
|
||||||
common_expression(A) ::= expression(B). { A = B; }
|
common_expression(A) ::= expression(B). { A = B; }
|
||||||
common_expression(A) ::= boolean_value_expression(B). { A = B; }
|
common_expression(A) ::= boolean_value_expression(B). { A = B; }
|
||||||
|
|
||||||
/************************************************ from_clause *********************************************************/
|
/************************************************ from_clause *********************************************************/
|
||||||
from_clause(A) ::= FROM table_reference_list(B). { PARSER_TRACE; A = B; }
|
from_clause(A) ::= FROM table_reference_list(B). { A = B; }
|
||||||
|
|
||||||
table_reference_list(A) ::= table_reference(B). { PARSER_TRACE; A = B; }
|
table_reference_list(A) ::= table_reference(B). { A = B; }
|
||||||
table_reference_list(A) ::= table_reference_list(B) NK_COMMA table_reference(C). { PARSER_TRACE; A = createJoinTableNode(pCxt, JOIN_TYPE_INNER, B, C, NULL); }
|
table_reference_list(A) ::= table_reference_list(B) NK_COMMA table_reference(C). { A = createJoinTableNode(pCxt, JOIN_TYPE_INNER, B, C, NULL); }
|
||||||
|
|
||||||
/************************************************ table_reference *****************************************************/
|
/************************************************ table_reference *****************************************************/
|
||||||
table_reference(A) ::= table_primary(B). { PARSER_TRACE; A = B; }
|
table_reference(A) ::= table_primary(B). { A = B; }
|
||||||
table_reference(A) ::= joined_table(B). { PARSER_TRACE; A = B; }
|
table_reference(A) ::= joined_table(B). { A = B; }
|
||||||
|
|
||||||
table_primary(A) ::= table_name(B) alias_opt(C). { PARSER_TRACE; A = createRealTableNode(pCxt, NULL, &B, &C); }
|
table_primary(A) ::= table_name(B) alias_opt(C). { A = createRealTableNode(pCxt, NULL, &B, &C); }
|
||||||
table_primary(A) ::= db_name(B) NK_DOT table_name(C) alias_opt(D). { PARSER_TRACE; A = createRealTableNode(pCxt, &B, &C, &D); }
|
table_primary(A) ::= db_name(B) NK_DOT table_name(C) alias_opt(D). { A = createRealTableNode(pCxt, &B, &C, &D); }
|
||||||
table_primary(A) ::= subquery(B) alias_opt(C). { PARSER_TRACE; A = createTempTableNode(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
table_primary(A) ::= subquery(B) alias_opt(C). { A = createTempTableNode(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||||
table_primary(A) ::= parenthesized_joined_table(B). { PARSER_TRACE; A = B; }
|
table_primary(A) ::= parenthesized_joined_table(B). { A = B; }
|
||||||
|
|
||||||
%type alias_opt { SToken }
|
%type alias_opt { SToken }
|
||||||
%destructor alias_opt { PARSER_DESTRUCTOR_TRACE; }
|
%destructor alias_opt { }
|
||||||
alias_opt(A) ::= . { PARSER_TRACE; A = nil_token; }
|
alias_opt(A) ::= . { A = nil_token; }
|
||||||
alias_opt(A) ::= table_alias(B). { PARSER_TRACE; A = B; }
|
alias_opt(A) ::= table_alias(B). { A = B; }
|
||||||
alias_opt(A) ::= AS table_alias(B). { PARSER_TRACE; A = B; }
|
alias_opt(A) ::= AS table_alias(B). { A = B; }
|
||||||
|
|
||||||
parenthesized_joined_table(A) ::= NK_LP joined_table(B) NK_RP. { PARSER_TRACE; A = B; }
|
parenthesized_joined_table(A) ::= NK_LP joined_table(B) NK_RP. { A = B; }
|
||||||
parenthesized_joined_table(A) ::= NK_LP parenthesized_joined_table(B) NK_RP. { PARSER_TRACE; A = B; }
|
parenthesized_joined_table(A) ::= NK_LP parenthesized_joined_table(B) NK_RP. { A = B; }
|
||||||
|
|
||||||
/************************************************ joined_table ********************************************************/
|
/************************************************ joined_table ********************************************************/
|
||||||
joined_table(A) ::=
|
joined_table(A) ::=
|
||||||
table_reference(B) join_type(C) JOIN table_reference(D) ON search_condition(E). { PARSER_TRACE; A = createJoinTableNode(pCxt, C, B, D, E); }
|
table_reference(B) join_type(C) JOIN table_reference(D) ON search_condition(E). { A = createJoinTableNode(pCxt, C, B, D, E); }
|
||||||
|
|
||||||
%type join_type { EJoinType }
|
%type join_type { EJoinType }
|
||||||
%destructor join_type { PARSER_DESTRUCTOR_TRACE; }
|
%destructor join_type { }
|
||||||
join_type(A) ::= . { PARSER_TRACE; A = JOIN_TYPE_INNER; }
|
join_type(A) ::= . { A = JOIN_TYPE_INNER; }
|
||||||
join_type(A) ::= INNER. { PARSER_TRACE; A = JOIN_TYPE_INNER; }
|
join_type(A) ::= INNER. { A = JOIN_TYPE_INNER; }
|
||||||
|
|
||||||
/************************************************ query_specification *************************************************/
|
/************************************************ query_specification *************************************************/
|
||||||
query_specification(A) ::=
|
query_specification(A) ::=
|
||||||
SELECT set_quantifier_opt(B) select_list(C) from_clause(D) where_clause_opt(E)
|
SELECT set_quantifier_opt(B) select_list(C) from_clause(D) where_clause_opt(E)
|
||||||
partition_by_clause_opt(F) twindow_clause_opt(G)
|
partition_by_clause_opt(F) twindow_clause_opt(G)
|
||||||
group_by_clause_opt(H) having_clause_opt(I). {
|
group_by_clause_opt(H) having_clause_opt(I). {
|
||||||
PARSER_TRACE;
|
|
||||||
A = createSelectStmt(pCxt, B, C, D);
|
A = createSelectStmt(pCxt, B, C, D);
|
||||||
A = addWhereClause(pCxt, A, E);
|
A = addWhereClause(pCxt, A, E);
|
||||||
A = addPartitionByClause(pCxt, A, F);
|
A = addPartitionByClause(pCxt, A, F);
|
||||||
|
@ -388,134 +396,132 @@ query_specification(A) ::=
|
||||||
}
|
}
|
||||||
|
|
||||||
%type set_quantifier_opt { bool }
|
%type set_quantifier_opt { bool }
|
||||||
%destructor set_quantifier_opt { PARSER_DESTRUCTOR_TRACE; }
|
%destructor set_quantifier_opt { }
|
||||||
set_quantifier_opt(A) ::= . { PARSER_TRACE; A = false; }
|
set_quantifier_opt(A) ::= . { A = false; }
|
||||||
set_quantifier_opt(A) ::= DISTINCT. { PARSER_TRACE; A = true; }
|
set_quantifier_opt(A) ::= DISTINCT. { A = true; }
|
||||||
set_quantifier_opt(A) ::= ALL. { PARSER_TRACE; A = false; }
|
set_quantifier_opt(A) ::= ALL. { A = false; }
|
||||||
|
|
||||||
%type select_list { SNodeList* }
|
%type select_list { SNodeList* }
|
||||||
%destructor select_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor select_list { nodesDestroyList($$); }
|
||||||
select_list(A) ::= NK_STAR. { PARSER_TRACE; A = NULL; }
|
select_list(A) ::= NK_STAR. { A = NULL; }
|
||||||
select_list(A) ::= select_sublist(B). { PARSER_TRACE; A = B; }
|
select_list(A) ::= select_sublist(B). { A = B; }
|
||||||
|
|
||||||
%type select_sublist { SNodeList* }
|
%type select_sublist { SNodeList* }
|
||||||
%destructor select_sublist { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor select_sublist { nodesDestroyList($$); }
|
||||||
select_sublist(A) ::= select_item(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
select_sublist(A) ::= select_item(B). { A = createNodeList(pCxt, B); }
|
||||||
select_sublist(A) ::= select_sublist(B) NK_COMMA select_item(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, C); }
|
select_sublist(A) ::= select_sublist(B) NK_COMMA select_item(C). { A = addNodeToList(pCxt, B, C); }
|
||||||
|
|
||||||
select_item(A) ::= common_expression(B). {
|
select_item(A) ::= common_expression(B). {
|
||||||
PARSER_TRACE;
|
|
||||||
SToken t = getTokenFromRawExprNode(pCxt, B);
|
SToken t = getTokenFromRawExprNode(pCxt, B);
|
||||||
A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &t);
|
A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &t);
|
||||||
}
|
}
|
||||||
select_item(A) ::= common_expression(B) column_alias(C). { PARSER_TRACE; A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
select_item(A) ::= common_expression(B) column_alias(C). { A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||||
select_item(A) ::= common_expression(B) AS column_alias(C). { PARSER_TRACE; A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
select_item(A) ::= common_expression(B) AS column_alias(C). { A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||||
select_item(A) ::= table_name(B) NK_DOT NK_STAR(C). { PARSER_TRACE; A = createColumnNode(pCxt, &B, &C); }
|
select_item(A) ::= table_name(B) NK_DOT NK_STAR(C). { A = createColumnNode(pCxt, &B, &C); }
|
||||||
|
|
||||||
where_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
where_clause_opt(A) ::= . { A = NULL; }
|
||||||
where_clause_opt(A) ::= WHERE search_condition(B). { PARSER_TRACE; A = B; }
|
where_clause_opt(A) ::= WHERE search_condition(B). { A = B; }
|
||||||
|
|
||||||
%type partition_by_clause_opt { SNodeList* }
|
%type partition_by_clause_opt { SNodeList* }
|
||||||
%destructor partition_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor partition_by_clause_opt { nodesDestroyList($$); }
|
||||||
partition_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
partition_by_clause_opt(A) ::= . { A = NULL; }
|
||||||
partition_by_clause_opt(A) ::= PARTITION BY expression_list(B). { PARSER_TRACE; A = B; }
|
partition_by_clause_opt(A) ::= PARTITION BY expression_list(B). { A = B; }
|
||||||
|
|
||||||
twindow_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
twindow_clause_opt(A) ::= . { A = NULL; }
|
||||||
twindow_clause_opt(A) ::=
|
twindow_clause_opt(A) ::=
|
||||||
SESSION NK_LP column_reference(B) NK_COMMA NK_INTEGER(C) NK_RP. { PARSER_TRACE; A = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
SESSION NK_LP column_reference(B) NK_COMMA NK_INTEGER(C) NK_RP. { A = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||||
twindow_clause_opt(A) ::= STATE_WINDOW NK_LP column_reference(B) NK_RP. { PARSER_TRACE; A = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, B)); }
|
twindow_clause_opt(A) ::= STATE_WINDOW NK_LP column_reference(B) NK_RP. { A = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||||
twindow_clause_opt(A) ::=
|
twindow_clause_opt(A) ::=
|
||||||
INTERVAL NK_LP duration_literal(B) NK_RP sliding_opt(C) fill_opt(D). { PARSER_TRACE; A = createIntervalWindowNode(pCxt, B, NULL, C, D); }
|
INTERVAL NK_LP duration_literal(B) NK_RP sliding_opt(C) fill_opt(D). { A = createIntervalWindowNode(pCxt, B, NULL, C, D); }
|
||||||
twindow_clause_opt(A) ::=
|
twindow_clause_opt(A) ::=
|
||||||
INTERVAL NK_LP duration_literal(B) NK_COMMA duration_literal(C) NK_RP
|
INTERVAL NK_LP duration_literal(B) NK_COMMA duration_literal(C) NK_RP
|
||||||
sliding_opt(D) fill_opt(E). { PARSER_TRACE; A = createIntervalWindowNode(pCxt, B, C, D, E); }
|
sliding_opt(D) fill_opt(E). { A = createIntervalWindowNode(pCxt, B, C, D, E); }
|
||||||
|
|
||||||
sliding_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
sliding_opt(A) ::= . { A = NULL; }
|
||||||
sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { PARSER_TRACE; A = B; }
|
sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { A = B; }
|
||||||
|
|
||||||
fill_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
fill_opt(A) ::= . { A = NULL; }
|
||||||
fill_opt(A) ::= FILL NK_LP fill_mode(B) NK_RP. { PARSER_TRACE; A = createFillNode(pCxt, B, NULL); }
|
fill_opt(A) ::= FILL NK_LP fill_mode(B) NK_RP. { A = createFillNode(pCxt, B, NULL); }
|
||||||
fill_opt(A) ::= FILL NK_LP VALUE NK_COMMA literal_list(B) NK_RP. { PARSER_TRACE; A = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, B)); }
|
fill_opt(A) ::= FILL NK_LP VALUE NK_COMMA literal_list(B) NK_RP. { A = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, B)); }
|
||||||
|
|
||||||
%type fill_mode { EFillMode }
|
%type fill_mode { EFillMode }
|
||||||
%destructor fill_mode { PARSER_DESTRUCTOR_TRACE; }
|
%destructor fill_mode { }
|
||||||
fill_mode(A) ::= NONE. { PARSER_TRACE; A = FILL_MODE_NONE; }
|
fill_mode(A) ::= NONE. { A = FILL_MODE_NONE; }
|
||||||
fill_mode(A) ::= PREV. { PARSER_TRACE; A = FILL_MODE_PREV; }
|
fill_mode(A) ::= PREV. { A = FILL_MODE_PREV; }
|
||||||
fill_mode(A) ::= NULL. { PARSER_TRACE; A = FILL_MODE_NULL; }
|
fill_mode(A) ::= NULL. { A = FILL_MODE_NULL; }
|
||||||
fill_mode(A) ::= LINEAR. { PARSER_TRACE; A = FILL_MODE_LINEAR; }
|
fill_mode(A) ::= LINEAR. { A = FILL_MODE_LINEAR; }
|
||||||
fill_mode(A) ::= NEXT. { PARSER_TRACE; A = FILL_MODE_NEXT; }
|
fill_mode(A) ::= NEXT. { A = FILL_MODE_NEXT; }
|
||||||
|
|
||||||
%type group_by_clause_opt { SNodeList* }
|
%type group_by_clause_opt { SNodeList* }
|
||||||
%destructor group_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor group_by_clause_opt { nodesDestroyList($$); }
|
||||||
group_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
group_by_clause_opt(A) ::= . { A = NULL; }
|
||||||
group_by_clause_opt(A) ::= GROUP BY group_by_list(B). { PARSER_TRACE; A = B; }
|
group_by_clause_opt(A) ::= GROUP BY group_by_list(B). { A = B; }
|
||||||
|
|
||||||
%type group_by_list { SNodeList* }
|
%type group_by_list { SNodeList* }
|
||||||
%destructor group_by_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor group_by_list { nodesDestroyList($$); }
|
||||||
group_by_list(A) ::= expression(B). { PARSER_TRACE; A = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, B))); }
|
group_by_list(A) ::= expression(B). { A = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, B))); }
|
||||||
group_by_list(A) ::= group_by_list(B) NK_COMMA expression(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, C))); }
|
group_by_list(A) ::= group_by_list(B) NK_COMMA expression(C). { A = addNodeToList(pCxt, B, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, C))); }
|
||||||
|
|
||||||
having_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
having_clause_opt(A) ::= . { A = NULL; }
|
||||||
having_clause_opt(A) ::= HAVING search_condition(B). { PARSER_TRACE; A = B; }
|
having_clause_opt(A) ::= HAVING search_condition(B). { A = B; }
|
||||||
|
|
||||||
/************************************************ query_expression ****************************************************/
|
/************************************************ query_expression ****************************************************/
|
||||||
query_expression(A) ::=
|
query_expression(A) ::=
|
||||||
query_expression_body(B)
|
query_expression_body(B)
|
||||||
order_by_clause_opt(C) slimit_clause_opt(D) limit_clause_opt(E). {
|
order_by_clause_opt(C) slimit_clause_opt(D) limit_clause_opt(E). {
|
||||||
PARSER_TRACE;
|
|
||||||
A = addOrderByClause(pCxt, B, C);
|
A = addOrderByClause(pCxt, B, C);
|
||||||
A = addSlimitClause(pCxt, A, D);
|
A = addSlimitClause(pCxt, A, D);
|
||||||
A = addLimitClause(pCxt, A, E);
|
A = addLimitClause(pCxt, A, E);
|
||||||
}
|
}
|
||||||
|
|
||||||
query_expression_body(A) ::= query_primary(B). { PARSER_TRACE; A = B; }
|
query_expression_body(A) ::= query_primary(B). { A = B; }
|
||||||
query_expression_body(A) ::=
|
query_expression_body(A) ::=
|
||||||
query_expression_body(B) UNION ALL query_expression_body(D). { PARSER_TRACE; A = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, B, D); }
|
query_expression_body(B) UNION ALL query_expression_body(D). { A = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, B, D); }
|
||||||
|
|
||||||
query_primary(A) ::= query_specification(B). { PARSER_TRACE; A = B; }
|
query_primary(A) ::= query_specification(B). { A = B; }
|
||||||
//query_primary(A) ::=
|
//query_primary(A) ::=
|
||||||
// NK_LP query_expression_body(B)
|
// NK_LP query_expression_body(B)
|
||||||
// order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP. { PARSER_TRACE; A = B;}
|
// order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP. { A = B;}
|
||||||
|
|
||||||
%type order_by_clause_opt { SNodeList* }
|
%type order_by_clause_opt { SNodeList* }
|
||||||
%destructor order_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor order_by_clause_opt { nodesDestroyList($$); }
|
||||||
order_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
order_by_clause_opt(A) ::= . { A = NULL; }
|
||||||
order_by_clause_opt(A) ::= ORDER BY sort_specification_list(B). { PARSER_TRACE; A = B; }
|
order_by_clause_opt(A) ::= ORDER BY sort_specification_list(B). { A = B; }
|
||||||
|
|
||||||
slimit_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
slimit_clause_opt(A) ::= . { A = NULL; }
|
||||||
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(B). { PARSER_TRACE; A = createLimitNode(pCxt, &B, NULL); }
|
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(B). { A = createLimitNode(pCxt, &B, NULL); }
|
||||||
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(B) SOFFSET NK_INTEGER(C). { PARSER_TRACE; A = createLimitNode(pCxt, &B, &C); }
|
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(B) SOFFSET NK_INTEGER(C). { A = createLimitNode(pCxt, &B, &C); }
|
||||||
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(C) NK_COMMA NK_INTEGER(B). { PARSER_TRACE; A = createLimitNode(pCxt, &B, &C); }
|
slimit_clause_opt(A) ::= SLIMIT NK_INTEGER(C) NK_COMMA NK_INTEGER(B). { A = createLimitNode(pCxt, &B, &C); }
|
||||||
|
|
||||||
limit_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
limit_clause_opt(A) ::= . { A = NULL; }
|
||||||
limit_clause_opt(A) ::= LIMIT NK_INTEGER(B). { PARSER_TRACE; A = createLimitNode(pCxt, &B, NULL); }
|
limit_clause_opt(A) ::= LIMIT NK_INTEGER(B). { A = createLimitNode(pCxt, &B, NULL); }
|
||||||
limit_clause_opt(A) ::= LIMIT NK_INTEGER(B) OFFSET NK_INTEGER(C). { PARSER_TRACE; A = createLimitNode(pCxt, &B, &C); }
|
limit_clause_opt(A) ::= LIMIT NK_INTEGER(B) OFFSET NK_INTEGER(C). { A = createLimitNode(pCxt, &B, &C); }
|
||||||
limit_clause_opt(A) ::= LIMIT NK_INTEGER(C) NK_COMMA NK_INTEGER(B). { PARSER_TRACE; A = createLimitNode(pCxt, &B, &C); }
|
limit_clause_opt(A) ::= LIMIT NK_INTEGER(C) NK_COMMA NK_INTEGER(B). { A = createLimitNode(pCxt, &B, &C); }
|
||||||
|
|
||||||
/************************************************ subquery ************************************************************/
|
/************************************************ subquery ************************************************************/
|
||||||
subquery(A) ::= NK_LP(B) query_expression(C) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &D, C); }
|
subquery(A) ::= NK_LP(B) query_expression(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, C); }
|
||||||
|
|
||||||
/************************************************ search_condition ****************************************************/
|
/************************************************ search_condition ****************************************************/
|
||||||
search_condition(A) ::= common_expression(B). { PARSER_TRACE; A = releaseRawExprNode(pCxt, B); }
|
search_condition(A) ::= common_expression(B). { A = releaseRawExprNode(pCxt, B); }
|
||||||
|
|
||||||
/************************************************ sort_specification_list *********************************************/
|
/************************************************ sort_specification_list *********************************************/
|
||||||
%type sort_specification_list { SNodeList* }
|
%type sort_specification_list { SNodeList* }
|
||||||
%destructor sort_specification_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
%destructor sort_specification_list { nodesDestroyList($$); }
|
||||||
sort_specification_list(A) ::= sort_specification(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
sort_specification_list(A) ::= sort_specification(B). { A = createNodeList(pCxt, B); }
|
||||||
sort_specification_list(A) ::=
|
sort_specification_list(A) ::=
|
||||||
sort_specification_list(B) NK_COMMA sort_specification(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, C); }
|
sort_specification_list(B) NK_COMMA sort_specification(C). { A = addNodeToList(pCxt, B, C); }
|
||||||
|
|
||||||
sort_specification(A) ::=
|
sort_specification(A) ::=
|
||||||
expression(B) ordering_specification_opt(C) null_ordering_opt(D). { PARSER_TRACE; A = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, B), C, D); }
|
expression(B) ordering_specification_opt(C) null_ordering_opt(D). { A = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, B), C, D); }
|
||||||
|
|
||||||
%type ordering_specification_opt EOrder
|
%type ordering_specification_opt EOrder
|
||||||
%destructor ordering_specification_opt { PARSER_DESTRUCTOR_TRACE; }
|
%destructor ordering_specification_opt { }
|
||||||
ordering_specification_opt(A) ::= . { PARSER_TRACE; A = ORDER_ASC; }
|
ordering_specification_opt(A) ::= . { A = ORDER_ASC; }
|
||||||
ordering_specification_opt(A) ::= ASC. { PARSER_TRACE; A = ORDER_ASC; }
|
ordering_specification_opt(A) ::= ASC. { A = ORDER_ASC; }
|
||||||
ordering_specification_opt(A) ::= DESC. { PARSER_TRACE; A = ORDER_DESC; }
|
ordering_specification_opt(A) ::= DESC. { A = ORDER_DESC; }
|
||||||
|
|
||||||
%type null_ordering_opt ENullOrder
|
%type null_ordering_opt ENullOrder
|
||||||
%destructor null_ordering_opt { PARSER_DESTRUCTOR_TRACE; }
|
%destructor null_ordering_opt { }
|
||||||
null_ordering_opt(A) ::= . { PARSER_TRACE; A = NULL_ORDER_DEFAULT; }
|
null_ordering_opt(A) ::= . { A = NULL_ORDER_DEFAULT; }
|
||||||
null_ordering_opt(A) ::= NULLS FIRST. { PARSER_TRACE; A = NULL_ORDER_FIRST; }
|
null_ordering_opt(A) ::= NULLS FIRST. { A = NULL_ORDER_FIRST; }
|
||||||
null_ordering_opt(A) ::= NULLS LAST. { PARSER_TRACE; A = NULL_ORDER_LAST; }
|
null_ordering_opt(A) ::= NULLS LAST. { A = NULL_ORDER_LAST; }
|
||||||
|
|
|
@ -32,16 +32,6 @@ typedef struct SMsgBuf {
|
||||||
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
||||||
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
|
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
|
||||||
|
|
||||||
int32_t parserValidateIdToken(SToken* pToken);
|
|
||||||
|
|
||||||
typedef struct SKvParam {
|
|
||||||
SKVRowBuilder *builder;
|
|
||||||
SSchema *schema;
|
|
||||||
char buf[TSDB_MAX_TAGS_LEN];
|
|
||||||
} SKvParam;
|
|
||||||
|
|
||||||
int32_t KvRowAppend(const void *value, int32_t len, void *param);
|
|
||||||
|
|
||||||
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
STableMeta* tableMetaDup(const STableMeta* pTableMeta);
|
||||||
SSchema *getTableColumnSchema(const STableMeta *pTableMeta);
|
SSchema *getTableColumnSchema(const STableMeta *pTableMeta);
|
||||||
SSchema *getTableTagSchema(const STableMeta* pTableMeta);
|
SSchema *getTableTagSchema(const STableMeta* pTableMeta);
|
||||||
|
@ -49,6 +39,8 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta);
|
||||||
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
||||||
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
||||||
|
|
||||||
|
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -36,7 +36,7 @@ typedef struct SToken {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
#define isNumber(tk) \
|
#define isNumber(tk) \
|
||||||
((tk)->type == TK_NK_INTEGER || (tk)->type == TK_NK_FLOAT || (tk)->type == TK_HEX || (tk)->type == TK_BIN)
|
((tk)->type == TK_NK_INTEGER || (tk)->type == TK_NK_FLOAT || (tk)->type == TK_NK_HEX || (tk)->type == TK_NK_BIN)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tokenizer for sql string
|
* tokenizer for sql string
|
||||||
|
@ -67,11 +67,11 @@ bool taosIsKeyWordToken(const char *z, int32_t len);
|
||||||
/**
|
/**
|
||||||
* check if it is a token or not
|
* check if it is a token or not
|
||||||
* @param pToken
|
* @param pToken
|
||||||
* @return token type, if it is not a number, TK_ILLEGAL will return
|
* @return token type, if it is not a number, TK_NK_ILLEGAL will return
|
||||||
*/
|
*/
|
||||||
static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
||||||
const char* z = pToken->z;
|
const char* z = pToken->z;
|
||||||
int32_t type = TK_ILLEGAL;
|
int32_t type = TK_NK_ILLEGAL;
|
||||||
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for(; i < pToken->n; ++i) {
|
for(; i < pToken->n; ++i) {
|
||||||
|
@ -88,7 +88,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
||||||
* .123e4
|
* .123e4
|
||||||
*/
|
*/
|
||||||
if (!isdigit(z[i+1])) {
|
if (!isdigit(z[i+1])) {
|
||||||
return TK_ILLEGAL;
|
return TK_NK_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i += 2; isdigit(z[i]); i++) {
|
for (i += 2; isdigit(z[i]); i++) {
|
||||||
|
@ -109,13 +109,13 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
||||||
case '0': {
|
case '0': {
|
||||||
char next = z[i + 1];
|
char next = z[i + 1];
|
||||||
if (next == 'b') { // bin number
|
if (next == 'b') { // bin number
|
||||||
type = TK_BIN;
|
type = TK_NK_BIN;
|
||||||
for (i += 2; (z[i] == '0' || z[i] == '1'); ++i) {
|
for (i += 2; (z[i] == '0' || z[i] == '1'); ++i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
goto _end;
|
goto _end;
|
||||||
} else if (next == 'x') { //hex number
|
} else if (next == 'x') { //hex number
|
||||||
type = TK_HEX;
|
type = TK_NK_HEX;
|
||||||
for (i += 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) {
|
for (i += 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg > 1) {
|
if (seg > 1) {
|
||||||
return TK_ILLEGAL;
|
return TK_NK_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((z[i] == 'e' || z[i] == 'E') &&
|
if ((z[i] == 'e' || z[i] == 'E') &&
|
||||||
|
@ -164,12 +164,12 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return TK_ILLEGAL;
|
return TK_NK_ILLEGAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
return (i < pToken->n)? TK_ILLEGAL:type;
|
return (i < pToken->n)? TK_NK_ILLEGAL:type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void taosCleanupKeywordsTable();
|
void taosCleanupKeywordsTable();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "astCreateFuncs.h"
|
#include "astCreateFuncs.h"
|
||||||
|
#include "parserUtil.h"
|
||||||
|
|
||||||
#define CHECK_OUT_OF_MEM(p) \
|
#define CHECK_OUT_OF_MEM(p) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -149,16 +150,16 @@ static SDatabaseOptions* setDbKeep(SAstCreateContext* pCxt, SDatabaseOptions* pO
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDatabaseOptions* setDbPrecision(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, const SToken* pVal) {
|
static SDatabaseOptions* setDbPrecision(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, const SToken* pVal) {
|
||||||
if (0 == strncmp(pVal->z, TSDB_TIME_PRECISION_MILLI_STR, pVal->n) && strlen(TSDB_TIME_PRECISION_MILLI_STR) == pVal->n) {
|
char val[10] = {0};
|
||||||
|
trimString(pVal->z, pVal->n, val, sizeof(val));
|
||||||
|
if (0 == strcmp(val, TSDB_TIME_PRECISION_MILLI_STR)) {
|
||||||
pOptions->precision = TSDB_TIME_PRECISION_MILLI;
|
pOptions->precision = TSDB_TIME_PRECISION_MILLI;
|
||||||
} else if (0 == strncmp(pVal->z, TSDB_TIME_PRECISION_MICRO_STR, pVal->n) && strlen(TSDB_TIME_PRECISION_MICRO_STR) == pVal->n) {
|
} else if (0 == strcmp(val, TSDB_TIME_PRECISION_MICRO_STR)) {
|
||||||
pOptions->precision = TSDB_TIME_PRECISION_MICRO;
|
pOptions->precision = TSDB_TIME_PRECISION_MICRO;
|
||||||
} else if (0 == strncmp(pVal->z, TSDB_TIME_PRECISION_NANO_STR, pVal->n) && strlen(TSDB_TIME_PRECISION_NANO_STR) == pVal->n) {
|
} else if (0 == strcmp(val, TSDB_TIME_PRECISION_NANO_STR)) {
|
||||||
pOptions->precision = TSDB_TIME_PRECISION_NANO;
|
pOptions->precision = TSDB_TIME_PRECISION_NANO;
|
||||||
} else {
|
} else {
|
||||||
char tmp[10];
|
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option precision: %s", val);
|
||||||
strncpy(tmp, pVal->z, pVal->n);
|
|
||||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option precision: %s", tmp);
|
|
||||||
pCxt->valid = false;
|
pCxt->valid = false;
|
||||||
}
|
}
|
||||||
return pOptions;
|
return pOptions;
|
||||||
|
@ -296,7 +297,7 @@ static STableOptions* setTableComment(SAstCreateContext* pCxt, STableOptions* pO
|
||||||
pCxt->valid = false;
|
pCxt->valid = false;
|
||||||
return pOptions;
|
return pOptions;
|
||||||
}
|
}
|
||||||
strncpy(pOptions->comments, pVal->z, pVal->n);
|
trimString(pVal->z, pVal->n, pOptions->comments, sizeof(pOptions->comments));
|
||||||
return pOptions;
|
return pOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,6 +414,8 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
|
||||||
if (TSDB_DATA_TYPE_TIMESTAMP == dataType) {
|
if (TSDB_DATA_TYPE_TIMESTAMP == dataType) {
|
||||||
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
||||||
}
|
}
|
||||||
|
val->isDuration = false;
|
||||||
|
val->translate = false;
|
||||||
return (SNode*)val;
|
return (SNode*)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,6 +425,7 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral)
|
||||||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||||
CHECK_OUT_OF_MEM(val->literal);
|
CHECK_OUT_OF_MEM(val->literal);
|
||||||
val->isDuration = true;
|
val->isDuration = true;
|
||||||
|
val->translate = false;
|
||||||
val->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
val->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
||||||
val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||||
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
||||||
|
@ -708,13 +712,18 @@ STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions,
|
||||||
return setTableOptionFuncs[type](pCxt, pOptions, pVal);
|
return setTableOptionFuncs[type](pCxt, pOptions, pVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma) {
|
||||||
|
pOptions->pSma = pSma;
|
||||||
|
return pOptions;
|
||||||
|
}
|
||||||
|
|
||||||
SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment) {
|
SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment) {
|
||||||
SColumnDefNode* pCol = (SColumnDefNode*)nodesMakeNode(QUERY_NODE_COLUMN_DEF);
|
SColumnDefNode* pCol = (SColumnDefNode*)nodesMakeNode(QUERY_NODE_COLUMN_DEF);
|
||||||
CHECK_OUT_OF_MEM(pCol);
|
CHECK_OUT_OF_MEM(pCol);
|
||||||
strncpy(pCol->colName, pColName->z, pColName->n);
|
strncpy(pCol->colName, pColName->z, pColName->n);
|
||||||
pCol->dataType = dataType;
|
pCol->dataType = dataType;
|
||||||
if (NULL != pComment) {
|
if (NULL != pComment) {
|
||||||
strncpy(pCol->comments, pComment->z, pComment->n);
|
trimString(pComment->z, pComment->n, pCol->comments, sizeof(pCol->comments));
|
||||||
}
|
}
|
||||||
return (SNode*)pCol;
|
return (SNode*)pCol;
|
||||||
}
|
}
|
||||||
|
@ -730,19 +739,51 @@ SDataType createVarLenDataType(uint8_t type, const SToken* pLen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* createCreateTableStmt(SAstCreateContext* pCxt,
|
SNode* createCreateTableStmt(SAstCreateContext* pCxt,
|
||||||
bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, STableOptions* pOptions) {
|
bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions) {
|
||||||
SCreateTableStmt* pStmt = (SCreateTableStmt*)nodesMakeNode(QUERY_NODE_CREATE_TABLE_STMT);
|
SCreateTableStmt* pStmt = (SCreateTableStmt*)nodesMakeNode(QUERY_NODE_CREATE_TABLE_STMT);
|
||||||
CHECK_OUT_OF_MEM(pStmt);
|
CHECK_OUT_OF_MEM(pStmt);
|
||||||
if (TK_NIL != pFullTableName->first.type) {
|
if (TK_NIL != pFullTableName->first.type) {
|
||||||
strncpy(pStmt->dbName, pFullTableName->first.z, pFullTableName->first.n);
|
strncpy(pStmt->dbName, pFullTableName->first.z, pFullTableName->first.n);
|
||||||
|
} else {
|
||||||
|
strcpy(pStmt->dbName, pCxt->pQueryCxt->db);
|
||||||
}
|
}
|
||||||
strncpy(pStmt->tableName, pFullTableName->second.z, pFullTableName->second.n);
|
strncpy(pStmt->tableName, pFullTableName->second.z, pFullTableName->second.n);
|
||||||
pStmt->ignoreExists = ignoreExists;
|
pStmt->ignoreExists = ignoreExists;
|
||||||
pStmt->pCols = pCols;
|
pStmt->pCols = pCols;
|
||||||
|
pStmt->pTags = pTags;
|
||||||
pStmt->options = *pOptions;
|
pStmt->options = *pOptions;
|
||||||
return (SNode*)pStmt;
|
return (SNode*)pStmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNode* createCreateSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists,
|
||||||
|
const STokenPair* pFullTableName, const STokenPair* pUseFullTableName, SNodeList* pSpecificTags, SNodeList* pValsOfTags) {
|
||||||
|
SCreateSubTableStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_SUBTABLE_STMT);
|
||||||
|
CHECK_OUT_OF_MEM(pStmt);
|
||||||
|
if (TK_NIL != pFullTableName->first.type) {
|
||||||
|
strncpy(pStmt->dbName, pFullTableName->first.z, pFullTableName->first.n);
|
||||||
|
} else {
|
||||||
|
strcpy(pStmt->dbName, pCxt->pQueryCxt->db);
|
||||||
|
}
|
||||||
|
strncpy(pStmt->tableName, pFullTableName->second.z, pFullTableName->second.n);
|
||||||
|
if (TK_NIL != pUseFullTableName->first.type) {
|
||||||
|
strncpy(pStmt->useDbName, pUseFullTableName->first.z, pUseFullTableName->first.n);
|
||||||
|
} else {
|
||||||
|
strcpy(pStmt->useDbName, pCxt->pQueryCxt->db);
|
||||||
|
}
|
||||||
|
strncpy(pStmt->useTableName, pUseFullTableName->second.z, pUseFullTableName->second.n);
|
||||||
|
pStmt->ignoreExists = ignoreExists;
|
||||||
|
pStmt->pSpecificTags = pSpecificTags;
|
||||||
|
pStmt->pValsOfTags = pValsOfTags;
|
||||||
|
return (SNode*)pStmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables) {
|
||||||
|
SCreateMultiTableStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_MULTI_TABLE_STMT);
|
||||||
|
CHECK_OUT_OF_MEM(pStmt);
|
||||||
|
pStmt->pSubTables = pSubTables;
|
||||||
|
return (SNode*)pStmt;
|
||||||
|
}
|
||||||
|
|
||||||
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName) {
|
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName) {
|
||||||
SUseDatabaseStmt* pStmt = (SUseDatabaseStmt*)nodesMakeNode(QUERY_NODE_USE_DATABASE_STMT);
|
SUseDatabaseStmt* pStmt = (SUseDatabaseStmt*)nodesMakeNode(QUERY_NODE_USE_DATABASE_STMT);
|
||||||
CHECK_OUT_OF_MEM(pStmt);
|
CHECK_OUT_OF_MEM(pStmt);
|
||||||
|
|
|
@ -26,22 +26,6 @@ extern void NewParse(void*, int, SToken, void*);
|
||||||
extern void NewParseFree(void*, FFree);
|
extern void NewParseFree(void*, FFree);
|
||||||
extern void NewParseTrace(FILE*, char*);
|
extern void NewParseTrace(FILE*, char*);
|
||||||
|
|
||||||
static void setQuery(SAstCreateContext* pCxt, SQuery* pQuery) {
|
|
||||||
pQuery->pRoot = pCxt->pRootNode;
|
|
||||||
ENodeType type = nodeType(pCxt->pRootNode);
|
|
||||||
if (QUERY_NODE_SELECT_STMT == type) {
|
|
||||||
pQuery->haveResultSet = true;
|
|
||||||
pQuery->directRpc = false;
|
|
||||||
} else if (QUERY_NODE_CREATE_TABLE_STMT == type) {
|
|
||||||
pQuery->haveResultSet = false;
|
|
||||||
pQuery->directRpc = false;
|
|
||||||
} else {
|
|
||||||
pQuery->haveResultSet = false;
|
|
||||||
pQuery->directRpc = true;
|
|
||||||
}
|
|
||||||
pQuery->msgType = (QUERY_NODE_CREATE_TABLE_STMT == type ? TDMT_VND_CREATE_TABLE : TDMT_VND_QUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
|
int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
|
||||||
SAstCreateContext cxt;
|
SAstCreateContext cxt;
|
||||||
initAstCreateContext(pParseCxt, &cxt);
|
initAstCreateContext(pParseCxt, &cxt);
|
||||||
|
@ -58,23 +42,23 @@ int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
|
||||||
i += t0.n;
|
i += t0.n;
|
||||||
|
|
||||||
switch (t0.type) {
|
switch (t0.type) {
|
||||||
case TK_SPACE:
|
case TK_NK_SPACE:
|
||||||
case TK_COMMENT: {
|
case TK_NK_COMMENT: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TK_SEMI: {
|
case TK_SEMI: {
|
||||||
NewParse(pParser, 0, t0, &cxt);
|
NewParse(pParser, 0, t0, &cxt);
|
||||||
goto abort_parse;
|
goto abort_parse;
|
||||||
}
|
}
|
||||||
case TK_QUESTION:
|
case TK_NK_QUESTION:
|
||||||
case TK_ILLEGAL: {
|
case TK_NK_ILLEGAL: {
|
||||||
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
|
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
|
||||||
cxt.valid = false;
|
cxt.valid = false;
|
||||||
goto abort_parse;
|
goto abort_parse;
|
||||||
}
|
}
|
||||||
case TK_HEX:
|
case TK_NK_HEX:
|
||||||
case TK_OCT:
|
case TK_NK_OCT:
|
||||||
case TK_BIN: {
|
case TK_NK_BIN: {
|
||||||
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z);
|
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z);
|
||||||
cxt.valid = false;
|
cxt.valid = false;
|
||||||
goto abort_parse;
|
goto abort_parse;
|
||||||
|
@ -95,7 +79,7 @@ abort_parse:
|
||||||
if (NULL == *pQuery) {
|
if (NULL == *pQuery) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
setQuery(&cxt, *pQuery);
|
(*pQuery)->pRoot = cxt.pRootNode;
|
||||||
}
|
}
|
||||||
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
|
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,29 +280,13 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
|
||||||
return found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol);
|
return found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t trimStringCopy(const char* src, int32_t len, bool format, char* dst) {
|
static int32_t trimStringWithVarFormat(const char* src, int32_t len, bool format, char* dst) {
|
||||||
char* dstVal = dst;
|
char* dstVal = dst;
|
||||||
if (format) {
|
if (format) {
|
||||||
varDataSetLen(dst, len);
|
varDataSetLen(dst, len);
|
||||||
dstVal = varDataVal(dst);
|
dstVal = varDataVal(dst);
|
||||||
}
|
}
|
||||||
// delete escape character: \\, \', \"
|
return trimString(src, len, dstVal, len);
|
||||||
char delim = src[0];
|
|
||||||
int32_t cnt = 0;
|
|
||||||
int32_t j = 0;
|
|
||||||
for (uint32_t k = 1; k < len - 1; ++k) {
|
|
||||||
if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
|
|
||||||
dstVal[j] = src[k + 1];
|
|
||||||
cnt++;
|
|
||||||
j++;
|
|
||||||
k++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dstVal[j] = src[k];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
dstVal[j] = '\0';
|
|
||||||
return j;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
|
@ -351,7 +335,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
return DEAL_RES_ERROR;
|
return DEAL_RES_ERROR;
|
||||||
}
|
}
|
||||||
trimStringCopy(pVal->literal, n, true, pVal->datum.p);
|
trimStringWithVarFormat(pVal->literal, n, true, pVal->datum.p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||||
|
@ -361,7 +345,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
return DEAL_RES_ERROR;
|
return DEAL_RES_ERROR;
|
||||||
}
|
}
|
||||||
int32_t len = trimStringCopy(pVal->literal, n, false, tmp);
|
int32_t len = trimStringWithVarFormat(pVal->literal, n, false, tmp);
|
||||||
if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
|
if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
|
||||||
tfree(tmp);
|
tfree(tmp);
|
||||||
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||||
|
@ -378,6 +362,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pVal->translate = true;
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,6 +841,47 @@ static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseS
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t columnNodeToField(SNodeList* pList, SArray** pArray) {
|
||||||
|
*pArray = taosArrayInit(LIST_LENGTH(pList), sizeof(SField));
|
||||||
|
SNode* pNode;
|
||||||
|
FOREACH(pNode, pList) {
|
||||||
|
SColumnDefNode* pCol = (SColumnDefNode*)pNode;
|
||||||
|
SField field = { .type = pCol->dataType.type, .bytes = pCol->dataType.bytes };
|
||||||
|
strcpy(field.name, pCol->colName);
|
||||||
|
taosArrayPush(*pArray, &field);
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateCreateSTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
|
||||||
|
SMCreateStbReq createReq = {0};
|
||||||
|
createReq.igExists = pStmt->ignoreExists;
|
||||||
|
columnNodeToField(pStmt->pCols, &createReq.pColumns);
|
||||||
|
columnNodeToField(pStmt->pTags, &createReq.pTags);
|
||||||
|
createReq.numOfColumns = LIST_LENGTH(pStmt->pCols);
|
||||||
|
createReq.numOfTags = LIST_LENGTH(pStmt->pTags);
|
||||||
|
|
||||||
|
SName tableName = { .type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId };
|
||||||
|
strcpy(tableName.dbname, pStmt->dbName);
|
||||||
|
strcpy(tableName.tname, pStmt->tableName);
|
||||||
|
tNameExtractFullName(&tableName, createReq.name);
|
||||||
|
|
||||||
|
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
|
||||||
|
if (NULL== pCxt->pCmdMsg) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
|
||||||
|
pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_STB;
|
||||||
|
pCxt->pCmdMsg->msgLen = tSerializeSMCreateStbReq(NULL, 0, &createReq);
|
||||||
|
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
|
||||||
|
if (NULL== pCxt->pCmdMsg->pMsg) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
tSerializeSMCreateStbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq);
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* pStmt) {
|
static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* pStmt) {
|
||||||
SName name = {0};
|
SName name = {0};
|
||||||
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
|
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
|
||||||
|
@ -935,6 +961,9 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
|
||||||
case QUERY_NODE_CREATE_DATABASE_STMT:
|
case QUERY_NODE_CREATE_DATABASE_STMT:
|
||||||
code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode);
|
code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_CREATE_TABLE_STMT:
|
||||||
|
code = translateCreateSTable(pCxt, (SCreateTableStmt*)pNode);
|
||||||
|
break;
|
||||||
case QUERY_NODE_USE_DATABASE_STMT:
|
case QUERY_NODE_USE_DATABASE_STMT:
|
||||||
code = translateUseDatabase(pCxt, (SUseDatabaseStmt*)pNode);
|
code = translateUseDatabase(pCxt, (SUseDatabaseStmt*)pNode);
|
||||||
break;
|
break;
|
||||||
|
@ -1020,7 +1049,7 @@ static int32_t doBuildSingleTableBatchReq(SName* pTableName, SNodeList* pColumns
|
||||||
pBatch->info = *pVgroupInfo;
|
pBatch->info = *pVgroupInfo;
|
||||||
pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
|
pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
|
||||||
if (pBatch->req.pArray == NULL) {
|
if (pBatch->req.pArray == NULL) {
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayPush(pBatch->req.pArray, &req);
|
taosArrayPush(pBatch->req.pArray, &req);
|
||||||
|
@ -1031,7 +1060,7 @@ static int32_t serializeVgroupTablesBatchImpl(SVgroupTablesBatch* pTbBatch, SArr
|
||||||
int tlen = sizeof(SMsgHead) + tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req));
|
int tlen = sizeof(SMsgHead) + tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req));
|
||||||
void* buf = malloc(tlen);
|
void* buf = malloc(tlen);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
// TODO: handle error
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
|
((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
|
||||||
|
@ -1068,15 +1097,11 @@ static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
if (QUERY_NODE_CREATE_TABLE_STMT == nodeType(pQuery->pRoot)) {
|
if (QUERY_NODE_CREATE_TABLE_STMT == nodeType(pQuery->pRoot) && NULL == ((SCreateTableStmt*)pQuery->pRoot)->pTags) {
|
||||||
SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot;
|
SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot;
|
||||||
|
|
||||||
SName tableName = { .type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId };
|
SName tableName = { .type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId };
|
||||||
if ('\0' == pStmt->dbName[0]) {
|
|
||||||
strcpy(tableName.dbname, pCxt->pParseCxt->db);
|
|
||||||
} else {
|
|
||||||
strcpy(tableName.dbname, pStmt->dbName);
|
strcpy(tableName.dbname, pStmt->dbName);
|
||||||
}
|
|
||||||
strcpy(tableName.tname, pStmt->tableName);
|
strcpy(tableName.tname, pStmt->tableName);
|
||||||
SVgroupInfo info = {0};
|
SVgroupInfo info = {0};
|
||||||
catalogGetTableHashVgroup(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &pCxt->pParseCxt->mgmtEpSet, &tableName, &info);
|
catalogGetTableHashVgroup(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &pCxt->pParseCxt->mgmtEpSet, &tableName, &info);
|
||||||
|
@ -1089,13 +1114,16 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
|
|
||||||
SArray* pBufArray = taosArrayInit(1, POINTER_BYTES);
|
SArray* pBufArray = taosArrayInit(1, POINTER_BYTES);
|
||||||
if (pBufArray == NULL) {
|
if (pBufArray == NULL) {
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
serializeVgroupTablesBatchImpl(&tbatch, pBufArray);
|
serializeVgroupTablesBatchImpl(&tbatch, pBufArray);
|
||||||
destroyCreateTbReqBatch(&tbatch);
|
destroyCreateTbReqBatch(&tbatch);
|
||||||
|
|
||||||
SVnodeModifOpStmt* pNewStmt = nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT);
|
SVnodeModifOpStmt* pNewStmt = nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT);
|
||||||
|
if (pNewStmt == NULL) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
pNewStmt->sqlNodeType = nodeType(pQuery->pRoot);
|
pNewStmt->sqlNodeType = nodeType(pQuery->pRoot);
|
||||||
pNewStmt->pDataBlocks = pBufArray;
|
pNewStmt->pDataBlocks = pBufArray;
|
||||||
pQuery->sqlNodeType = nodeType(pQuery->pRoot);
|
pQuery->sqlNodeType = nodeType(pQuery->pRoot);
|
||||||
|
@ -1105,6 +1133,31 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
switch (nodeType(pQuery->pRoot)) {
|
||||||
|
case QUERY_NODE_SELECT_STMT:
|
||||||
|
pQuery->haveResultSet = true;
|
||||||
|
pQuery->directRpc = false;
|
||||||
|
pQuery->msgType = TDMT_VND_QUERY;
|
||||||
|
code = setReslutSchema(pCxt, pQuery);
|
||||||
|
break;
|
||||||
|
case QUERY_NODE_VNODE_MODIF_STMT:
|
||||||
|
pQuery->haveResultSet = false;
|
||||||
|
pQuery->directRpc = false;
|
||||||
|
pQuery->msgType = TDMT_VND_CREATE_TABLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pQuery->haveResultSet = false;
|
||||||
|
pQuery->directRpc = true;
|
||||||
|
pQuery->pCmdMsg = pCxt->pCmdMsg;
|
||||||
|
pCxt->pCmdMsg = NULL;
|
||||||
|
pQuery->msgType = pQuery->pCmdMsg->msgType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
|
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
|
||||||
STranslateContext cxt = {
|
STranslateContext cxt = {
|
||||||
.pParseCxt = pParseCxt,
|
.pParseCxt = pParseCxt,
|
||||||
|
@ -1122,13 +1175,7 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
|
||||||
code = translateQuery(&cxt, pQuery->pRoot);
|
code = translateQuery(&cxt, pQuery->pRoot);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
if (pQuery->directRpc) {
|
code = setQuery(&cxt, pQuery);
|
||||||
pQuery->pCmdMsg = cxt.pCmdMsg;
|
|
||||||
cxt.pCmdMsg = NULL;
|
|
||||||
}
|
|
||||||
if (pQuery->haveResultSet) {
|
|
||||||
code = setReslutSchema(&cxt, pQuery);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
destroyTranslateContext(&cxt);
|
destroyTranslateContext(&cxt);
|
||||||
return code;
|
return code;
|
||||||
|
|
|
@ -80,6 +80,68 @@ static int32_t skipInsertInto(SInsertParseContext* pCxt) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t parserValidateIdToken(SToken* pToken) {
|
||||||
|
if (pToken == NULL || pToken->z == NULL || pToken->type != TK_NK_ID) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// it is a token quoted with escape char '`'
|
||||||
|
if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
|
||||||
|
if (sep == NULL) { // It is a single part token, not a complex type
|
||||||
|
if (isNumber(pToken)) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
strntolower(pToken->z, pToken->z, pToken->n);
|
||||||
|
} else { // two part
|
||||||
|
int32_t oldLen = pToken->n;
|
||||||
|
char* pStr = pToken->z;
|
||||||
|
|
||||||
|
if (pToken->type == TK_NK_SPACE) {
|
||||||
|
pToken->n = (uint32_t)strtrim(pToken->z);
|
||||||
|
}
|
||||||
|
|
||||||
|
pToken->n = tGetToken(pToken->z, &pToken->type);
|
||||||
|
if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pToken->type != TK_NK_ID) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t firstPartLen = pToken->n;
|
||||||
|
|
||||||
|
pToken->z = sep + 1;
|
||||||
|
pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1);
|
||||||
|
int32_t len = tGetToken(pToken->z, &pToken->type);
|
||||||
|
if (len != pToken->n || pToken->type != TK_NK_ID) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-build the whole name string
|
||||||
|
if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
|
||||||
|
// first part do not have quote do nothing
|
||||||
|
} else {
|
||||||
|
pStr[firstPartLen] = TS_PATH_DELIMITER[0];
|
||||||
|
memmove(&pStr[firstPartLen + 1], pToken->z, pToken->n);
|
||||||
|
uint32_t offset = (uint32_t)(pToken->z - (pStr + firstPartLen + 1));
|
||||||
|
memset(pToken->z + pToken->n - offset, ' ', offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0]));
|
||||||
|
pToken->z = pStr;
|
||||||
|
|
||||||
|
strntolower(pToken->z, pToken->z, pToken->n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullDbName, char* tableName) {
|
static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullDbName, char* tableName) {
|
||||||
if (parserValidateIdToken(pStname) != TSDB_CODE_SUCCESS) {
|
if (parserValidateIdToken(pStname) != TSDB_CODE_SUCCESS) {
|
||||||
return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pStname->z);
|
return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pStname->z);
|
||||||
|
@ -320,7 +382,7 @@ static int parseTime(char **end, SToken *pToken, int16_t timePrec, int64_t *time
|
||||||
|
|
||||||
static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, uint32_t type, char* tmpTokenBuf, SMsgBuf* pMsgBuf) {
|
static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, uint32_t type, char* tmpTokenBuf, SMsgBuf* pMsgBuf) {
|
||||||
if ((pToken->type != TK_NOW && pToken->type != TK_NK_INTEGER && pToken->type != TK_NK_STRING && pToken->type != TK_NK_FLOAT && pToken->type != TK_NK_BOOL &&
|
if ((pToken->type != TK_NOW && pToken->type != TK_NK_INTEGER && pToken->type != TK_NK_STRING && pToken->type != TK_NK_FLOAT && pToken->type != TK_NK_BOOL &&
|
||||||
pToken->type != TK_NULL && pToken->type != TK_HEX && pToken->type != TK_OCT && pToken->type != TK_BIN) ||
|
pToken->type != TK_NULL && pToken->type != TK_NK_HEX && pToken->type != TK_NK_OCT && pToken->type != TK_NK_BIN) ||
|
||||||
(pToken->n == 0) || (pToken->type == TK_NK_RP)) {
|
(pToken->n == 0) || (pToken->type == TK_NK_RP)) {
|
||||||
return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z);
|
return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z);
|
||||||
}
|
}
|
||||||
|
@ -370,7 +432,7 @@ static FORCE_INLINE int32_t toDouble(SToken *pToken, double *value, char **endPt
|
||||||
|
|
||||||
// not a valid integer number, return error
|
// not a valid integer number, return error
|
||||||
if ((*endPtr - pToken->z) != pToken->n) {
|
if ((*endPtr - pToken->z) != pToken->n) {
|
||||||
return TK_ILLEGAL;
|
return TK_NK_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pToken->type;
|
return pToken->type;
|
||||||
|
@ -496,7 +558,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_FLOAT: {
|
case TSDB_DATA_TYPE_FLOAT: {
|
||||||
double dv;
|
double dv;
|
||||||
if (TK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
|
if (TK_NK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
|
||||||
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
|
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
|
||||||
}
|
}
|
||||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
|
||||||
|
@ -508,7 +570,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE: {
|
case TSDB_DATA_TYPE_DOUBLE: {
|
||||||
double dv;
|
double dv;
|
||||||
if (TK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
|
if (TK_NK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
|
||||||
return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
|
return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
|
||||||
}
|
}
|
||||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
|
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
|
||||||
|
@ -646,6 +708,37 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo*
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct SKvParam {
|
||||||
|
SKVRowBuilder *builder;
|
||||||
|
SSchema *schema;
|
||||||
|
char buf[TSDB_MAX_TAGS_LEN];
|
||||||
|
} SKvParam;
|
||||||
|
|
||||||
|
static int32_t KvRowAppend(const void *value, int32_t len, void *param) {
|
||||||
|
SKvParam* pa = (SKvParam*) param;
|
||||||
|
|
||||||
|
int32_t type = pa->schema->type;
|
||||||
|
int32_t colId = pa->schema->colId;
|
||||||
|
|
||||||
|
if (TSDB_DATA_TYPE_BINARY == type) {
|
||||||
|
STR_WITH_SIZE_TO_VARSTR(pa->buf, value, len);
|
||||||
|
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
|
||||||
|
} else if (TSDB_DATA_TYPE_NCHAR == type) {
|
||||||
|
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
|
||||||
|
int32_t output = 0;
|
||||||
|
if (!taosMbsToUcs4(value, len, varDataVal(pa->buf), pa->schema->bytes - VARSTR_HEADER_SIZE, &output)) {
|
||||||
|
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
varDataSetLen(pa->buf, output);
|
||||||
|
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
|
||||||
|
} else {
|
||||||
|
tdAddColToKVRow(pa->builder, colId, type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// pSql -> tag1_value, ...)
|
// pSql -> tag1_value, ...)
|
||||||
static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pTagsSchema, uint8_t precision) {
|
static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pTagsSchema, uint8_t precision) {
|
||||||
if (tdInitKVRowBuilder(&pCxt->tagsBuilder) < 0) {
|
if (tdInitKVRowBuilder(&pCxt->tagsBuilder) < 0) {
|
||||||
|
@ -893,7 +986,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE csv_file_path
|
// FILE csv_file_path
|
||||||
if (TK_FILE == sToken.type) {
|
if (TK_NK_FILE == sToken.type) {
|
||||||
// pSql -> csv_file_path
|
// pSql -> csv_file_path
|
||||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||||
if (0 == sToken.n || (TK_NK_STRING != sToken.type && TK_NK_ID != sToken.type)) {
|
if (0 == sToken.n || (TK_NK_STRING != sToken.type && TK_NK_ID != sToken.type)) {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,93 +45,6 @@ int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char*
|
||||||
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parserValidateIdToken(SToken* pToken) {
|
|
||||||
if (pToken == NULL || pToken->z == NULL || pToken->type != TK_NK_ID) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// it is a token quoted with escape char '`'
|
|
||||||
if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
|
|
||||||
if (sep == NULL) { // It is a single part token, not a complex type
|
|
||||||
if (isNumber(pToken)) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
strntolower(pToken->z, pToken->z, pToken->n);
|
|
||||||
} else { // two part
|
|
||||||
int32_t oldLen = pToken->n;
|
|
||||||
char* pStr = pToken->z;
|
|
||||||
|
|
||||||
if (pToken->type == TK_SPACE) {
|
|
||||||
pToken->n = (uint32_t)strtrim(pToken->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
pToken->n = tGetToken(pToken->z, &pToken->type);
|
|
||||||
if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pToken->type != TK_NK_ID) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t firstPartLen = pToken->n;
|
|
||||||
|
|
||||||
pToken->z = sep + 1;
|
|
||||||
pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1);
|
|
||||||
int32_t len = tGetToken(pToken->z, &pToken->type);
|
|
||||||
if (len != pToken->n || pToken->type != TK_NK_ID) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// re-build the whole name string
|
|
||||||
if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
|
|
||||||
// first part do not have quote do nothing
|
|
||||||
} else {
|
|
||||||
pStr[firstPartLen] = TS_PATH_DELIMITER[0];
|
|
||||||
memmove(&pStr[firstPartLen + 1], pToken->z, pToken->n);
|
|
||||||
uint32_t offset = (uint32_t)(pToken->z - (pStr + firstPartLen + 1));
|
|
||||||
memset(pToken->z + pToken->n - offset, ' ', offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0]));
|
|
||||||
pToken->z = pStr;
|
|
||||||
|
|
||||||
strntolower(pToken->z, pToken->z, pToken->n);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t KvRowAppend(const void *value, int32_t len, void *param) {
|
|
||||||
SKvParam* pa = (SKvParam*) param;
|
|
||||||
|
|
||||||
int32_t type = pa->schema->type;
|
|
||||||
int32_t colId = pa->schema->colId;
|
|
||||||
|
|
||||||
if (TSDB_DATA_TYPE_BINARY == type) {
|
|
||||||
STR_WITH_SIZE_TO_VARSTR(pa->buf, value, len);
|
|
||||||
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
|
|
||||||
} else if (TSDB_DATA_TYPE_NCHAR == type) {
|
|
||||||
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
|
|
||||||
int32_t output = 0;
|
|
||||||
if (!taosMbsToUcs4(value, len, varDataVal(pa->buf), pa->schema->bytes - VARSTR_HEADER_SIZE, &output)) {
|
|
||||||
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
varDataSetLen(pa->buf, output);
|
|
||||||
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
|
|
||||||
} else {
|
|
||||||
tdAddColToKVRow(pa->builder, colId, type, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t getTableMetaSize(const STableMeta* pTableMeta) {
|
static uint32_t getTableMetaSize(const STableMeta* pTableMeta) {
|
||||||
assert(pTableMeta != NULL);
|
assert(pTableMeta != NULL);
|
||||||
|
|
||||||
|
@ -184,3 +97,26 @@ STableComInfo getTableInfo(const STableMeta* pTableMeta) {
|
||||||
assert(pTableMeta != NULL);
|
assert(pTableMeta != NULL);
|
||||||
return pTableMeta->tableInfo;
|
return pTableMeta->tableInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen) {
|
||||||
|
// delete escape character: \\, \', \"
|
||||||
|
char delim = src[0];
|
||||||
|
int32_t cnt = 0;
|
||||||
|
int32_t j = 0;
|
||||||
|
for (uint32_t k = 1; k < len - 1; ++k) {
|
||||||
|
if (j >= dlen) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
|
||||||
|
dst[j] = src[k + 1];
|
||||||
|
cnt++;
|
||||||
|
j++;
|
||||||
|
k++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dst[j] = src[k];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
dst[j] = '\0';
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
|
@ -29,32 +29,102 @@ typedef struct SKeyword {
|
||||||
|
|
||||||
// keywords in sql string
|
// keywords in sql string
|
||||||
static SKeyword keywordTable[] = {
|
static SKeyword keywordTable[] = {
|
||||||
// {"ID", TK_ID},
|
{"ALL", TK_ALL},
|
||||||
{"BOOL", TK_BOOL},
|
|
||||||
{"TINYINT", TK_TINYINT},
|
|
||||||
{"SMALLINT", TK_SMALLINT},
|
|
||||||
{"INTEGER", TK_INTEGER},
|
|
||||||
{"INT", TK_INTEGER},
|
|
||||||
{"BIGINT", TK_BIGINT},
|
|
||||||
{"FLOAT", TK_FLOAT},
|
|
||||||
{"DOUBLE", TK_DOUBLE},
|
|
||||||
// {"STRING", TK_STRING},
|
|
||||||
{"TIMESTAMP", TK_TIMESTAMP},
|
|
||||||
{"BINARY", TK_BINARY},
|
|
||||||
{"NCHAR", TK_NCHAR},
|
|
||||||
{"OR", TK_OR},
|
|
||||||
{"AND", TK_AND},
|
{"AND", TK_AND},
|
||||||
|
{"AS", TK_AS},
|
||||||
|
{"ASC", TK_ASC},
|
||||||
|
{"BETWEEN", TK_BETWEEN},
|
||||||
|
{"BINARY", TK_BINARY},
|
||||||
|
{"BIGINT", TK_BIGINT},
|
||||||
|
{"BLOCKS", TK_BLOCKS},
|
||||||
|
{"BOOL", TK_BOOL},
|
||||||
|
{"BY", TK_BY},
|
||||||
|
{"CACHE", TK_CACHE},
|
||||||
|
{"CACHELAST", TK_CACHELAST},
|
||||||
|
{"COMMENT", TK_COMMENT},
|
||||||
|
{"COMP", TK_COMP},
|
||||||
|
{"CREATE", TK_CREATE},
|
||||||
|
{"DATABASE", TK_DATABASE},
|
||||||
|
{"DATABASES", TK_DATABASES},
|
||||||
|
{"DAYS", TK_DAYS},
|
||||||
|
{"DESC", TK_DESC},
|
||||||
|
{"DISTINCT", TK_DISTINCT},
|
||||||
|
{"DOUBLE", TK_DOUBLE},
|
||||||
|
{"EXISTS", TK_EXISTS},
|
||||||
|
// {"FILE", TK_FILE},
|
||||||
|
{"FILL", TK_FILL},
|
||||||
|
{"FLOAT", TK_FLOAT},
|
||||||
|
{"FROM", TK_FROM},
|
||||||
|
{"FSYNC", TK_FSYNC},
|
||||||
|
{"GROUP", TK_GROUP},
|
||||||
|
{"HAVING", TK_HAVING},
|
||||||
|
{"IF", TK_IF},
|
||||||
|
{"IMPORT", TK_IMPORT},
|
||||||
|
{"IN", TK_IN},
|
||||||
|
{"INNER", TK_INNER},
|
||||||
|
{"INT", TK_INT},
|
||||||
|
{"INSERT", TK_INSERT},
|
||||||
|
{"INTEGER", TK_INTEGER},
|
||||||
|
{"INTERVAL", TK_INTERVAL},
|
||||||
|
{"INTO", TK_INTO},
|
||||||
|
{"IS", TK_IS},
|
||||||
|
{"JOIN", TK_JOIN},
|
||||||
|
{"JSON", TK_JSON},
|
||||||
|
{"KEEP", TK_KEEP},
|
||||||
|
{"LIKE", TK_LIKE},
|
||||||
|
{"LIMIT", TK_LIMIT},
|
||||||
|
{"LINEAR", TK_LINEAR},
|
||||||
|
{"MATCH", TK_MATCH},
|
||||||
|
{"MAXROWS", TK_MAXROWS},
|
||||||
|
{"MINROWS", TK_MINROWS},
|
||||||
|
{"MINUS", TK_MINUS},
|
||||||
|
{"NCHAR", TK_NCHAR},
|
||||||
|
{"NMATCH", TK_NMATCH},
|
||||||
|
{"NONE", TK_NONE},
|
||||||
{"NOT", TK_NOT},
|
{"NOT", TK_NOT},
|
||||||
|
{"NOW", TK_NOW},
|
||||||
|
{"NULL", TK_NULL},
|
||||||
|
{"OFFSET", TK_OFFSET},
|
||||||
|
{"PRECISION", TK_PRECISION},
|
||||||
|
{"PREV", TK_PREV},
|
||||||
|
{"ON", TK_ON},
|
||||||
|
{"OR", TK_OR},
|
||||||
|
{"ORDER", TK_ORDER},
|
||||||
|
{"QUORUM", TK_QUORUM},
|
||||||
|
{"REPLICA", TK_REPLICA},
|
||||||
|
{"SELECT", TK_SELECT},
|
||||||
|
{"SESSION", TK_SESSION},
|
||||||
|
{"SHOW", TK_SHOW},
|
||||||
|
{"SINGLE_STABLE", TK_SINGLE_STABLE},
|
||||||
|
{"SLIDING", TK_SLIDING},
|
||||||
|
{"SLIMIT", TK_SLIMIT},
|
||||||
|
{"SMA", TK_SMA},
|
||||||
|
{"SMALLINT", TK_SMALLINT},
|
||||||
|
{"SOFFSET", TK_SOFFSET},
|
||||||
|
{"STATE_WINDOW", TK_STATE_WINDOW},
|
||||||
|
{"STREAM_MODE", TK_STREAM_MODE},
|
||||||
|
{"TABLE", TK_TABLE},
|
||||||
|
{"TABLES", TK_TABLES},
|
||||||
|
{"TAGS", TK_TAGS},
|
||||||
|
{"TIMESTAMP", TK_TIMESTAMP},
|
||||||
|
{"TINYINT", TK_TINYINT},
|
||||||
|
{"TTL", TK_TTL},
|
||||||
|
{"UNION", TK_UNION},
|
||||||
|
{"UNSIGNED", TK_UNSIGNED},
|
||||||
|
{"USE", TK_USE},
|
||||||
|
{"USING", TK_USING},
|
||||||
|
{"VALUES", TK_VALUES},
|
||||||
|
{"VARCHAR", TK_VARCHAR},
|
||||||
|
{"VGROUPS", TK_VGROUPS},
|
||||||
|
{"WAL", TK_WAL},
|
||||||
|
{"WHERE", TK_WHERE},
|
||||||
|
// {"ID", TK_ID},
|
||||||
|
// {"STRING", TK_STRING},
|
||||||
// {"EQ", TK_EQ},
|
// {"EQ", TK_EQ},
|
||||||
// {"NE", TK_NE},
|
// {"NE", TK_NE},
|
||||||
// {"ISNULL", TK_ISNULL},
|
// {"ISNULL", TK_ISNULL},
|
||||||
// {"NOTNULL", TK_NOTNULL},
|
// {"NOTNULL", TK_NOTNULL},
|
||||||
{"IS", TK_IS},
|
|
||||||
{"LIKE", TK_LIKE},
|
|
||||||
{"MATCH", TK_MATCH},
|
|
||||||
// {"GLOB", TK_GLOB},
|
// {"GLOB", TK_GLOB},
|
||||||
{"BETWEEN", TK_BETWEEN},
|
|
||||||
{"IN", TK_IN},
|
|
||||||
// {"GT", TK_GT},
|
// {"GT", TK_GT},
|
||||||
// {"GE", TK_GE},
|
// {"GE", TK_GE},
|
||||||
// {"LT", TK_LT},
|
// {"LT", TK_LT},
|
||||||
|
@ -64,7 +134,6 @@ static SKeyword keywordTable[] = {
|
||||||
// {"LSHIFT", TK_LSHIFT},
|
// {"LSHIFT", TK_LSHIFT},
|
||||||
// {"RSHIFT", TK_RSHIFT},
|
// {"RSHIFT", TK_RSHIFT},
|
||||||
// {"PLUS", TK_PLUS},
|
// {"PLUS", TK_PLUS},
|
||||||
{"MINUS", TK_MINUS},
|
|
||||||
// {"DIVIDE", TK_DIVIDE},
|
// {"DIVIDE", TK_DIVIDE},
|
||||||
// {"TIMES", TK_TIMES},
|
// {"TIMES", TK_TIMES},
|
||||||
// {"STAR", TK_STAR},
|
// {"STAR", TK_STAR},
|
||||||
|
@ -74,8 +143,6 @@ static SKeyword keywordTable[] = {
|
||||||
// {"UMINUS", TK_UMINUS},
|
// {"UMINUS", TK_UMINUS},
|
||||||
// {"UPLUS", TK_UPLUS},
|
// {"UPLUS", TK_UPLUS},
|
||||||
// {"BITNOT", TK_BITNOT},
|
// {"BITNOT", TK_BITNOT},
|
||||||
{"SHOW", TK_SHOW},
|
|
||||||
{"DATABASES", TK_DATABASES},
|
|
||||||
// {"MNODES", TK_MNODES},
|
// {"MNODES", TK_MNODES},
|
||||||
// {"DNODES", TK_DNODES},
|
// {"DNODES", TK_DNODES},
|
||||||
// {"ACCOUNTS", TK_ACCOUNTS},
|
// {"ACCOUNTS", TK_ACCOUNTS},
|
||||||
|
@ -88,25 +155,17 @@ static SKeyword keywordTable[] = {
|
||||||
// {"SCORES", TK_SCORES},
|
// {"SCORES", TK_SCORES},
|
||||||
// {"GRANTS", TK_GRANTS},
|
// {"GRANTS", TK_GRANTS},
|
||||||
// {"DOT", TK_DOT},
|
// {"DOT", TK_DOT},
|
||||||
{"TABLES", TK_TABLES},
|
|
||||||
// {"STABLES", TK_STABLES},
|
// {"STABLES", TK_STABLES},
|
||||||
{"VGROUPS", TK_VGROUPS},
|
|
||||||
// {"DROP", TK_DROP},
|
// {"DROP", TK_DROP},
|
||||||
{"TABLE", TK_TABLE},
|
|
||||||
{"DATABASE", TK_DATABASE},
|
|
||||||
// {"DNODE", TK_DNODE},
|
// {"DNODE", TK_DNODE},
|
||||||
// {"USER", TK_USER},
|
// {"USER", TK_USER},
|
||||||
// {"ACCOUNT", TK_ACCOUNT},
|
// {"ACCOUNT", TK_ACCOUNT},
|
||||||
{"USE", TK_USE},
|
|
||||||
// {"DESCRIBE", TK_DESCRIBE},
|
// {"DESCRIBE", TK_DESCRIBE},
|
||||||
// {"SYNCDB", TK_SYNCDB},
|
// {"SYNCDB", TK_SYNCDB},
|
||||||
// {"ALTER", TK_ALTER},
|
// {"ALTER", TK_ALTER},
|
||||||
// {"PASS", TK_PASS},
|
// {"PASS", TK_PASS},
|
||||||
// {"PRIVILEGE", TK_PRIVILEGE},
|
// {"PRIVILEGE", TK_PRIVILEGE},
|
||||||
// {"LOCAL", TK_LOCAL},
|
// {"LOCAL", TK_LOCAL},
|
||||||
{"IF", TK_IF},
|
|
||||||
{"EXISTS", TK_EXISTS},
|
|
||||||
{"CREATE", TK_CREATE},
|
|
||||||
// {"PPS", TK_PPS},
|
// {"PPS", TK_PPS},
|
||||||
// {"TSERIES", TK_TSERIES},
|
// {"TSERIES", TK_TSERIES},
|
||||||
// {"DBS", TK_DBS},
|
// {"DBS", TK_DBS},
|
||||||
|
@ -114,51 +173,13 @@ static SKeyword keywordTable[] = {
|
||||||
// {"QTIME", TK_QTIME},
|
// {"QTIME", TK_QTIME},
|
||||||
// {"CONNS", TK_CONNS},
|
// {"CONNS", TK_CONNS},
|
||||||
// {"STATE", TK_STATE},
|
// {"STATE", TK_STATE},
|
||||||
{"KEEP", TK_KEEP},
|
|
||||||
{"REPLICA", TK_REPLICA},
|
|
||||||
{"QUORUM", TK_QUORUM},
|
|
||||||
{"DAYS", TK_DAYS},
|
|
||||||
{"MINROWS", TK_MINROWS},
|
|
||||||
{"MAXROWS", TK_MAXROWS},
|
|
||||||
{"BLOCKS", TK_BLOCKS},
|
|
||||||
{"CACHE", TK_CACHE},
|
|
||||||
// {"CTIME", TK_CTIME},
|
// {"CTIME", TK_CTIME},
|
||||||
{"WAL", TK_WAL},
|
|
||||||
{"FSYNC", TK_FSYNC},
|
|
||||||
{"COMP", TK_COMP},
|
|
||||||
{"PRECISION", TK_PRECISION},
|
|
||||||
// {"LP", TK_LP},
|
// {"LP", TK_LP},
|
||||||
// {"RP", TK_RP},
|
// {"RP", TK_RP},
|
||||||
// {"UNSIGNED", TK_UNSIGNED},
|
|
||||||
{"TAGS", TK_TAGS},
|
|
||||||
{"USING", TK_USING},
|
|
||||||
{"AS", TK_AS},
|
|
||||||
// {"COMMA", TK_COMMA},
|
// {"COMMA", TK_COMMA},
|
||||||
{"NULL", TK_NULL},
|
|
||||||
{"SELECT", TK_SELECT},
|
|
||||||
// {"EVERY", TK_EVERY},
|
// {"EVERY", TK_EVERY},
|
||||||
{"FROM", TK_FROM},
|
|
||||||
// {"VARIABLE", TK_VARIABLE},
|
// {"VARIABLE", TK_VARIABLE},
|
||||||
{"INTERVAL", TK_INTERVAL},
|
|
||||||
{"SESSION", TK_SESSION},
|
|
||||||
{"STATE_WINDOW", TK_STATE_WINDOW},
|
|
||||||
{"FILL", TK_FILL},
|
|
||||||
{"SLIDING", TK_SLIDING},
|
|
||||||
{"ORDER", TK_ORDER},
|
|
||||||
{"BY", TK_BY},
|
|
||||||
{"ASC", TK_ASC},
|
|
||||||
{"DESC", TK_DESC},
|
|
||||||
{"GROUP", TK_GROUP},
|
|
||||||
{"HAVING", TK_HAVING},
|
|
||||||
{"LIMIT", TK_LIMIT},
|
|
||||||
{"OFFSET", TK_OFFSET},
|
|
||||||
{"SLIMIT", TK_SLIMIT},
|
|
||||||
{"SOFFSET", TK_SOFFSET},
|
|
||||||
{"WHERE", TK_WHERE},
|
|
||||||
{"NOW", TK_NOW},
|
|
||||||
{"INSERT", TK_INSERT},
|
|
||||||
{"INTO", TK_INTO},
|
|
||||||
{"VALUES", TK_VALUES},
|
|
||||||
// {"UPDATE", TK_UPDATE},
|
// {"UPDATE", TK_UPDATE},
|
||||||
// {"RESET", TK_RESET},
|
// {"RESET", TK_RESET},
|
||||||
// {"QUERY", TK_QUERY},
|
// {"QUERY", TK_QUERY},
|
||||||
|
@ -192,8 +213,6 @@ static SKeyword keywordTable[] = {
|
||||||
// {"IMMEDIATE", TK_IMMEDIATE},
|
// {"IMMEDIATE", TK_IMMEDIATE},
|
||||||
// {"INITIALLY", TK_INITIALLY},
|
// {"INITIALLY", TK_INITIALLY},
|
||||||
// {"INSTEAD", TK_INSTEAD},
|
// {"INSTEAD", TK_INSTEAD},
|
||||||
{"MATCH", TK_MATCH},
|
|
||||||
{"NMATCH", TK_NMATCH},
|
|
||||||
// {"KEY", TK_KEY},
|
// {"KEY", TK_KEY},
|
||||||
// {"OF", TK_OF},
|
// {"OF", TK_OF},
|
||||||
// {"RAISE", TK_RAISE},
|
// {"RAISE", TK_RAISE},
|
||||||
|
@ -203,20 +222,10 @@ static SKeyword keywordTable[] = {
|
||||||
// {"STATEMENT", TK_STATEMENT},
|
// {"STATEMENT", TK_STATEMENT},
|
||||||
// {"TRIGGER", TK_TRIGGER},
|
// {"TRIGGER", TK_TRIGGER},
|
||||||
// {"VIEW", TK_VIEW},
|
// {"VIEW", TK_VIEW},
|
||||||
{"ALL", TK_ALL},
|
|
||||||
// {"SEMI", TK_SEMI},
|
// {"SEMI", TK_SEMI},
|
||||||
{"NONE", TK_NONE},
|
|
||||||
{"PREV", TK_PREV},
|
|
||||||
{"LINEAR", TK_LINEAR},
|
|
||||||
{"IMPORT", TK_IMPORT},
|
|
||||||
// {"TBNAME", TK_TBNAME},
|
// {"TBNAME", TK_TBNAME},
|
||||||
{"JOIN", TK_JOIN},
|
|
||||||
// {"STABLE", TK_STABLE},
|
// {"STABLE", TK_STABLE},
|
||||||
{"FILE", TK_FILE},
|
|
||||||
// {"VNODES", TK_VNODES},
|
// {"VNODES", TK_VNODES},
|
||||||
{"UNION", TK_UNION},
|
|
||||||
{"CACHELAST", TK_CACHELAST},
|
|
||||||
{"DISTINCT", TK_DISTINCT},
|
|
||||||
// {"PARTITIONS", TK_PARTITIONS},
|
// {"PARTITIONS", TK_PARTITIONS},
|
||||||
// {"TOPIC", TK_TOPIC},
|
// {"TOPIC", TK_TOPIC},
|
||||||
// {"TOPICS", TK_TOPICS},
|
// {"TOPICS", TK_TOPICS},
|
||||||
|
@ -228,8 +237,6 @@ static SKeyword keywordTable[] = {
|
||||||
// {"AGGREGATE", TK_AGGREGATE},
|
// {"AGGREGATE", TK_AGGREGATE},
|
||||||
// {"BUFSIZE", TK_BUFSIZE},
|
// {"BUFSIZE", TK_BUFSIZE},
|
||||||
// {"PORT", TK_PORT},
|
// {"PORT", TK_PORT},
|
||||||
{"INNER", TK_INNER},
|
|
||||||
{"ON", TK_ON},
|
|
||||||
// {"MODE", TK_MODE},
|
// {"MODE", TK_MODE},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -277,7 +284,7 @@ static int32_t tKeywordCode(const char* z, int n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keywordHashTable == NULL) {
|
if (keywordHashTable == NULL) {
|
||||||
return TK_ILLEGAL;
|
return TK_NK_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SKeyword** pKey = (SKeyword**)taosHashGet(keywordHashTable, key, n);
|
SKeyword** pKey = (SKeyword**)taosHashGet(keywordHashTable, key, n);
|
||||||
|
@ -298,7 +305,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
case '\r': {
|
case '\r': {
|
||||||
for (i = 1; isspace(z[i]); i++) {
|
for (i = 1; isspace(z[i]); i++) {
|
||||||
}
|
}
|
||||||
*tokenId = TK_SPACE;
|
*tokenId = TK_NK_SPACE;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
case ':': {
|
case ':': {
|
||||||
|
@ -383,7 +390,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
}
|
}
|
||||||
case '!': {
|
case '!': {
|
||||||
if (z[1] != '=') {
|
if (z[1] != '=') {
|
||||||
*tokenId = TK_ILLEGAL;
|
*tokenId = TK_NK_ILLEGAL;
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
*tokenId = TK_NK_NE;
|
*tokenId = TK_NK_NE;
|
||||||
|
@ -412,7 +419,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case '?': {
|
case '?': {
|
||||||
*tokenId = TK_QUESTION;
|
*tokenId = TK_NK_QUESTION;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case '`':
|
case '`':
|
||||||
|
@ -475,7 +482,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
char next = z[1];
|
char next = z[1];
|
||||||
|
|
||||||
if (next == 'b') { // bin number
|
if (next == 'b') { // bin number
|
||||||
*tokenId = TK_BIN;
|
*tokenId = TK_NK_BIN;
|
||||||
for (i = 2; (z[i] == '0' || z[i] == '1'); ++i) {
|
for (i = 2; (z[i] == '0' || z[i] == '1'); ++i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,7 +492,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
} else if (next == 'x') { //hex number
|
} else if (next == 'x') { //hex number
|
||||||
*tokenId = TK_HEX;
|
*tokenId = TK_NK_HEX;
|
||||||
for (i = 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) {
|
for (i = 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,7 +581,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*tokenId = TK_ILLEGAL;
|
*tokenId = TK_NK_ILLEGAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +615,7 @@ SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
||||||
return t0;
|
return t0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IGNORE TK_SPACE, TK_COMMA, and specified tokens
|
// IGNORE TK_NK_SPACE, TK_NK_COMMA, and specified tokens
|
||||||
while (1) {
|
while (1) {
|
||||||
*i += t0.n;
|
*i += t0.n;
|
||||||
|
|
||||||
|
@ -656,7 +663,7 @@ SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
||||||
|
|
||||||
// only id and string are valid
|
// only id and string are valid
|
||||||
if ((TK_NK_STRING != t0.type) && (TK_NK_ID != t0.type)) {
|
if ((TK_NK_STRING != t0.type) && (TK_NK_ID != t0.type)) {
|
||||||
t0.type = TK_ILLEGAL;
|
t0.type = TK_NK_ILLEGAL;
|
||||||
t0.n = 0;
|
t0.n = 0;
|
||||||
|
|
||||||
return t0;
|
return t0;
|
||||||
|
|
|
@ -58,6 +58,11 @@ int32_t __catalogGetTableHashVgroup(struct SCatalog* pCatalog, void *pRpc, const
|
||||||
return mockCatalogService->catalogGetTableHashVgroup(pTableName, vgInfo);
|
return mockCatalogService->catalogGetTableHashVgroup(pTableName, vgInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t __catalogGetTableDistVgInfo(SCatalog* pCatalog, void *pTransporter, const SEpSet* pMgmtEps, const SName* pTableName, SArray** pVgroupList) {
|
||||||
|
// return mockCatalogService->catalogGetTableDistVgInfo(pTableName, pVgroupList);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void initMetaDataEnv() {
|
void initMetaDataEnv() {
|
||||||
mockCatalogService.reset(new MockCatalogService());
|
mockCatalogService.reset(new MockCatalogService());
|
||||||
|
|
||||||
|
@ -65,6 +70,7 @@ void initMetaDataEnv() {
|
||||||
stub.set(catalogGetHandle, __catalogGetHandle);
|
stub.set(catalogGetHandle, __catalogGetHandle);
|
||||||
stub.set(catalogGetTableMeta, __catalogGetTableMeta);
|
stub.set(catalogGetTableMeta, __catalogGetTableMeta);
|
||||||
stub.set(catalogGetTableHashVgroup, __catalogGetTableHashVgroup);
|
stub.set(catalogGetTableHashVgroup, __catalogGetTableHashVgroup);
|
||||||
|
stub.set(catalogGetTableDistVgInfo, __catalogGetTableDistVgInfo);
|
||||||
{
|
{
|
||||||
AddrAny any("libcatalog.so");
|
AddrAny any("libcatalog.so");
|
||||||
std::map<std::string,void*> result;
|
std::map<std::string,void*> result;
|
||||||
|
@ -89,6 +95,14 @@ void initMetaDataEnv() {
|
||||||
stub.set(f.second, __catalogGetTableHashVgroup);
|
stub.set(f.second, __catalogGetTableHashVgroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
AddrAny any("libcatalog.so");
|
||||||
|
std::map<std::string,void*> result;
|
||||||
|
any.get_global_func_addr_dynsym("^catalogGetTableDistVgInfo$", result);
|
||||||
|
for (const auto& f : result) {
|
||||||
|
stub.set(f.second, __catalogGetTableDistVgInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMetaData() {
|
void generateMetaData() {
|
||||||
|
|
|
@ -42,457 +42,41 @@ protected:
|
||||||
|
|
||||||
bool run(int32_t parseCode = TSDB_CODE_SUCCESS, int32_t translateCode = TSDB_CODE_SUCCESS) {
|
bool run(int32_t parseCode = TSDB_CODE_SUCCESS, int32_t translateCode = TSDB_CODE_SUCCESS) {
|
||||||
int32_t code = doParse(&cxt_, &query_);
|
int32_t code = doParse(&cxt_, &query_);
|
||||||
// cout << "doParse return " << code << endl;
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
cout << "sql:[" << cxt_.pSql << "] code:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl;
|
cout << "sql:[" << cxt_.pSql << "] parser code:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl;
|
||||||
return (TSDB_CODE_SUCCESS != parseCode);
|
return (TSDB_CODE_SUCCESS != parseCode);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS != parseCode) {
|
if (TSDB_CODE_SUCCESS != parseCode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
string parserStr = toString(query_->pRoot);
|
||||||
code = doTranslate(&cxt_, query_);
|
code = doTranslate(&cxt_, query_);
|
||||||
// cout << "doTranslate return " << code << endl;
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
cout << "sql:[" << cxt_.pSql << "] code:" << code << ", " << translateCode << ", msg:" << errMagBuf_ << endl;
|
cout << "sql:[" << cxt_.pSql << "] translate code:" << code << ", " << translateCode << ", msg:" << errMagBuf_ << endl;
|
||||||
return (code == translateCode);
|
return (code == translateCode);
|
||||||
}
|
}
|
||||||
if (NULL != query_->pRoot && QUERY_NODE_SELECT_STMT == nodeType(query_->pRoot)) {
|
|
||||||
cout << "input sql : [" << cxt_.pSql << "]" << endl;
|
cout << "input sql : [" << cxt_.pSql << "]" << endl;
|
||||||
// string sql;
|
cout << "parser output: " << endl;
|
||||||
// selectToSql(query_.pRoot, sql);
|
cout << parserStr << endl;
|
||||||
// cout << "output sql : [" << sql << "]" << endl;
|
cout << "translate output: " << endl;
|
||||||
string str;
|
cout << toString(query_->pRoot) << endl;
|
||||||
selectToStr(query_->pRoot, str);
|
|
||||||
cout << "translate str : \n" << str << endl;
|
|
||||||
}
|
|
||||||
return (TSDB_CODE_SUCCESS == translateCode);
|
return (TSDB_CODE_SUCCESS == translateCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int max_err_len = 1024;
|
static const int max_err_len = 1024;
|
||||||
|
|
||||||
void exprNodeToStr(const SNode* node, string& str, bool isProject) {
|
string toString(const SNode* pRoot, bool format = false) {
|
||||||
switch (nodeType(node)) {
|
char* pStr = NULL;
|
||||||
case QUERY_NODE_COLUMN:
|
int32_t len = 0;
|
||||||
case QUERY_NODE_VALUE:
|
int32_t code = nodesNodeToString(pRoot, format, &pStr, &len);
|
||||||
case QUERY_NODE_OPERATOR:
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
case QUERY_NODE_FUNCTION:
|
cout << "sql:[" << cxt_.pSql << "] toString code:" << code << ", strerror:" << tstrerror(code) << endl;
|
||||||
case QUERY_NODE_LOGIC_CONDITION: {
|
throw "nodesNodeToString failed!";
|
||||||
SExprNode* pExpr = (SExprNode*)node;
|
}
|
||||||
str.append(" [" + dataTypeToStr(pExpr->resType) + "]");
|
string str(pStr);
|
||||||
if (isProject) {
|
tfree(pStr);
|
||||||
str.append(" AS " + string(pExpr->aliasName));
|
return str;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 valueNodeToStr(const SValueNode* pVal, string& str) {
|
|
||||||
switch (pVal->node.resType.type) {
|
|
||||||
case TSDB_DATA_TYPE_NULL:
|
|
||||||
str.append("null");
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_BOOL:
|
|
||||||
str.append(pVal->datum.b ? "true" : "false");
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
|
||||||
case TSDB_DATA_TYPE_INT:
|
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
|
||||||
str.append(to_string(pVal->datum.i));
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
|
||||||
str.append(to_string(pVal->datum.d));
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_BINARY:
|
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
|
||||||
case TSDB_DATA_TYPE_VARCHAR:
|
|
||||||
case TSDB_DATA_TYPE_VARBINARY:
|
|
||||||
str.append(pVal->datum.p);
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
|
||||||
str.append(to_string(pVal->datum.u));
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_UTINYINT:
|
|
||||||
case TSDB_DATA_TYPE_USMALLINT:
|
|
||||||
case TSDB_DATA_TYPE_UINT:
|
|
||||||
case TSDB_DATA_TYPE_UBIGINT:
|
|
||||||
str.append(to_string(pVal->datum.u));
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_JSON:
|
|
||||||
case TSDB_DATA_TYPE_DECIMAL:
|
|
||||||
case TSDB_DATA_TYPE_BLOB:
|
|
||||||
str.append("JSON or DECIMAL or BLOB");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void columnNodeToStr(const SColumnNode* pCol, string& str) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operatorToStr(const SOperatorNode* pOp, string& str) {
|
|
||||||
nodeToStr(pOp->pLeft, str, false);
|
|
||||||
str.append(opTypeToStr(pOp->opType));
|
|
||||||
nodeToStr(pOp->pRight, str, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void functionToStr(const SFunctionNode* pFunc, string& str) {
|
|
||||||
str.append(pFunc->functionName);
|
|
||||||
str.append("(");
|
|
||||||
nodeListToStr(pFunc->pParameterList, "", str, false, ", ");
|
|
||||||
str.append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
void groupingSetToStr(SGroupingSetNode* pGroup, string& str) {
|
|
||||||
nodeToStr((SNode*)nodesListGetNode(pGroup->pParameterList, 0), str, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void orderByExprToStr(SOrderByExprNode* pOrderBy, string& str) {
|
|
||||||
nodeToStr(pOrderBy->pExpr, str, false);
|
|
||||||
str.append((ORDER_ASC == pOrderBy->order ? " ASC" : " DESC"));
|
|
||||||
str.append((NULL_ORDER_FIRST == pOrderBy->nullOrder ? " NULLS FIRST" : " NULLS LAST"));
|
|
||||||
}
|
|
||||||
|
|
||||||
string logicConditionTypeToStr(ELogicConditionType type) {
|
|
||||||
switch (type) {
|
|
||||||
case LOGIC_COND_TYPE_AND:
|
|
||||||
return "AND";
|
|
||||||
case LOGIC_COND_TYPE_OR:
|
|
||||||
return "OR";
|
|
||||||
case LOGIC_COND_TYPE_NOT:
|
|
||||||
return "NOT";
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return "Unknown logic cond type";
|
|
||||||
}
|
|
||||||
|
|
||||||
void logicCondToStr(SLogicConditionNode* pCond, string& str) {
|
|
||||||
SNode* node = nullptr;
|
|
||||||
bool first = true;
|
|
||||||
FOREACH(node, pCond->pParameterList) {
|
|
||||||
if (first && LOGIC_COND_TYPE_NOT == pCond->condType) {
|
|
||||||
str.append(logicConditionTypeToStr(pCond->condType) + " ");
|
|
||||||
} else if (!first && LOGIC_COND_TYPE_NOT != pCond->condType) {
|
|
||||||
str.append(" " + logicConditionTypeToStr(pCond->condType) + " ");
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
nodeToStr(node, str, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nodeToStr(const SNode* node, string& str, bool isProject) {
|
|
||||||
if (nullptr == node) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (nodeType(node)) {
|
|
||||||
case QUERY_NODE_COLUMN: {
|
|
||||||
columnNodeToStr((SColumnNode*)node, str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_VALUE: {
|
|
||||||
valueNodeToStr((SValueNode*)node, str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_OPERATOR: {
|
|
||||||
operatorToStr((SOperatorNode*)node, str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_FUNCTION: {
|
|
||||||
functionToStr((SFunctionNode*)node, str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_LOGIC_CONDITION: {
|
|
||||||
logicCondToStr((SLogicConditionNode*)node, str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_GROUPING_SET: {
|
|
||||||
groupingSetToStr((SGroupingSetNode*)node, str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_ORDER_BY_EXPR: {
|
|
||||||
orderByExprToStr((SOrderByExprNode*)node, str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
exprNodeToStr(node, str, isProject);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nodeListToStr(const SNodeList* nodelist, const string& prefix, string& str, bool isProject = false, const string& sep = string("\n")) {
|
|
||||||
SNode* node = nullptr;
|
|
||||||
FOREACH(node, nodelist) {
|
|
||||||
str.append(prefix);
|
|
||||||
nodeToStr(node, str, isProject);
|
|
||||||
str.append(sep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(prefix + "FROM\n");
|
|
||||||
tableToStr(select->pFromTable, prefix + "\t", str);
|
|
||||||
if (nullptr != select->pWhere) {
|
|
||||||
str.append("\n" + prefix + "WHERE\n\t");
|
|
||||||
nodeToStr(select->pWhere, str, false);
|
|
||||||
}
|
|
||||||
if (nullptr != select->pGroupByList) {
|
|
||||||
str.append("\n" + prefix + "GROUP BY\n");
|
|
||||||
nodeListToStr(select->pGroupByList, prefix + "\t", str, true);
|
|
||||||
}
|
|
||||||
if (nullptr != select->pOrderByList) {
|
|
||||||
str.append(prefix + "ORDER BY\n");
|
|
||||||
nodeListToStr(select->pOrderByList, prefix + "\t", str, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void selectToSql(const SNode* node, string& sql) {
|
|
||||||
SSelectStmt* select = (SSelectStmt*)node;
|
|
||||||
sql.append("SELECT ");
|
|
||||||
if (select->isDistinct) {
|
|
||||||
sql.append("DISTINCT ");
|
|
||||||
}
|
|
||||||
if (nullptr == select->pProjectionList) {
|
|
||||||
sql.append("* ");
|
|
||||||
} else {
|
|
||||||
nodeListToSql(select->pProjectionList, sql);
|
|
||||||
sql.append(" ");
|
|
||||||
}
|
|
||||||
sql.append("FROM ");
|
|
||||||
tableToSql(select->pFromTable, sql);
|
|
||||||
if (nullptr != select->pWhere) {
|
|
||||||
sql.append(" WHERE ");
|
|
||||||
nodeToSql(select->pWhere, sql);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tableToSql(const SNode* node, string& sql) {
|
|
||||||
const STableNode* table = (const STableNode*)node;
|
|
||||||
switch (nodeType(node)) {
|
|
||||||
case QUERY_NODE_REAL_TABLE: {
|
|
||||||
SRealTableNode* realTable = (SRealTableNode*)table;
|
|
||||||
if ('\0' != realTable->table.dbName[0]) {
|
|
||||||
sql.append(realTable->table.dbName);
|
|
||||||
sql.append(".");
|
|
||||||
}
|
|
||||||
sql.append(realTable->table.tableName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_TEMP_TABLE: {
|
|
||||||
STempTableNode* tempTable = (STempTableNode*)table;
|
|
||||||
sql.append("(");
|
|
||||||
selectToSql(tempTable->pSubquery, sql);
|
|
||||||
sql.append(") ");
|
|
||||||
sql.append(tempTable->table.tableAlias);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_JOIN_TABLE: {
|
|
||||||
SJoinTableNode* joinTable = (SJoinTableNode*)table;
|
|
||||||
tableToSql(joinTable->pLeft, sql);
|
|
||||||
sql.append(" JOIN ");
|
|
||||||
tableToSql(joinTable->pRight, sql);
|
|
||||||
if (nullptr != joinTable->pOnCond) {
|
|
||||||
sql.append(" ON ");
|
|
||||||
nodeToSql(joinTable->pOnCond, sql);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string opTypeToStr(EOperatorType type) {
|
|
||||||
switch (type) {
|
|
||||||
case OP_TYPE_ADD:
|
|
||||||
return " + ";
|
|
||||||
case OP_TYPE_SUB:
|
|
||||||
return " - ";
|
|
||||||
case OP_TYPE_MULTI:
|
|
||||||
return " * ";
|
|
||||||
case OP_TYPE_DIV:
|
|
||||||
return " / ";
|
|
||||||
case OP_TYPE_MOD:
|
|
||||||
return " % ";
|
|
||||||
case OP_TYPE_GREATER_THAN:
|
|
||||||
return " > ";
|
|
||||||
case OP_TYPE_GREATER_EQUAL:
|
|
||||||
return " >= ";
|
|
||||||
case OP_TYPE_LOWER_THAN:
|
|
||||||
return " < ";
|
|
||||||
case OP_TYPE_LOWER_EQUAL:
|
|
||||||
return " <= ";
|
|
||||||
case OP_TYPE_EQUAL:
|
|
||||||
return " = ";
|
|
||||||
case OP_TYPE_NOT_EQUAL:
|
|
||||||
return " != ";
|
|
||||||
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:
|
|
||||||
case OP_TYPE_JSON_GET_VALUE:
|
|
||||||
case OP_TYPE_JSON_CONTAINS:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return " unknown operator ";
|
|
||||||
}
|
|
||||||
|
|
||||||
void nodeToSql(const SNode* node, string& sql) {
|
|
||||||
if (nullptr == node) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (nodeType(node)) {
|
|
||||||
case QUERY_NODE_COLUMN: {
|
|
||||||
SColumnNode* pCol = (SColumnNode*)node;
|
|
||||||
if ('\0' != pCol->dbName[0]) {
|
|
||||||
sql.append(pCol->dbName);
|
|
||||||
sql.append(".");
|
|
||||||
}
|
|
||||||
if ('\0' != pCol->tableAlias[0]) {
|
|
||||||
sql.append(pCol->tableAlias);
|
|
||||||
sql.append(".");
|
|
||||||
}
|
|
||||||
sql.append(pCol->colName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QUERY_NODE_VALUE:
|
|
||||||
break;
|
|
||||||
case QUERY_NODE_OPERATOR: {
|
|
||||||
SOperatorNode* pOp = (SOperatorNode*)node;
|
|
||||||
nodeToSql(pOp->pLeft, sql);
|
|
||||||
sql.append(opTypeToStr(pOp->opType));
|
|
||||||
nodeToSql(pOp->pRight, sql);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nodeListToSql(const SNodeList* nodelist, string& sql, const string& seq = ",") {
|
|
||||||
SNode* node = nullptr;
|
|
||||||
bool firstNode = true;
|
|
||||||
FOREACH(node, nodelist) {
|
|
||||||
if (!firstNode) {
|
|
||||||
sql.append(", ");
|
|
||||||
}
|
|
||||||
firstNode = false;
|
|
||||||
nodeToSql(node, sql);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
|
@ -700,6 +284,27 @@ TEST_F(ParserTest, selectSemanticError) {
|
||||||
TEST_F(ParserTest, createDatabase) {
|
TEST_F(ParserTest, createDatabase) {
|
||||||
bind("create database wxy_db");
|
bind("create database wxy_db");
|
||||||
ASSERT_TRUE(run());
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("create database if not exists wxy_db "
|
||||||
|
"BLOCKS 100 "
|
||||||
|
"CACHE 100 "
|
||||||
|
"CACHELAST 2 "
|
||||||
|
"COMP 1 "
|
||||||
|
"DAYS 100 "
|
||||||
|
"FSYNC 100 "
|
||||||
|
"MAXROWS 1000 "
|
||||||
|
"MINROWS 100 "
|
||||||
|
"KEEP 100 "
|
||||||
|
"PRECISION 'ms' "
|
||||||
|
"QUORUM 1 "
|
||||||
|
"REPLICA 3 "
|
||||||
|
"TTL 100 "
|
||||||
|
"WAL 2 "
|
||||||
|
"VGROUPS 100 "
|
||||||
|
"SINGLE_STABLE 0 "
|
||||||
|
"STREAM_MODE 1 "
|
||||||
|
);
|
||||||
|
ASSERT_TRUE(run());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserTest, showDatabase) {
|
TEST_F(ParserTest, showDatabase) {
|
||||||
|
@ -715,4 +320,31 @@ TEST_F(ParserTest, useDatabase) {
|
||||||
TEST_F(ParserTest, createTable) {
|
TEST_F(ParserTest, createTable) {
|
||||||
bind("create table t1(ts timestamp, c1 int)");
|
bind("create table t1(ts timestamp, c1 int)");
|
||||||
ASSERT_TRUE(run());
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("create table if not exists test.t1("
|
||||||
|
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 SMALLINT, "
|
||||||
|
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), c14 JSON, c15 VARCHAR(50)) "
|
||||||
|
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)"
|
||||||
|
);
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("create table if not exists test.t1("
|
||||||
|
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 SMALLINT, "
|
||||||
|
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), c14 JSON, c15 VARCHAR(50)) "
|
||||||
|
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, a5 FLOAT, a6 DOUBLE, a7 BINARY(20), a8 SMALLINT, "
|
||||||
|
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), a14 JSON, a15 VARCHAR(50)) "
|
||||||
|
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)"
|
||||||
|
);
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("create table if not exists t1 using st1 tags(1)");
|
||||||
|
ASSERT_TRUE(run());
|
||||||
|
|
||||||
|
bind("create table "
|
||||||
|
"if not exists test.t1 using test.st1 (tc1, tc2, tc3) tags(1, 2.0, 'abc', TIMESTAMP '2022-3-6 11:20:23') "
|
||||||
|
"if not exists test.t2 using test.st1 (tc1, tc2, tc3) tags(2, 2.0, 'abc', TIMESTAMP '2022-3-6 11:20:23') "
|
||||||
|
"if not exists test.t3 using test.st1 (tc1, tc2, tc3) tags(3, 2.0, 'abc', TIMESTAMP '2022-3-6 11:20:23')"
|
||||||
|
);
|
||||||
|
ASSERT_TRUE(run());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue