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_WAL 38
|
||||
#define TK_VGROUPS 39
|
||||
#define TK_SINGLESTABLE 40
|
||||
#define TK_STREAMMODE 41
|
||||
#define TK_SINGLE_STABLE 40
|
||||
#define TK_STREAM_MODE 41
|
||||
#define TK_USE 42
|
||||
#define TK_TABLE 43
|
||||
#define TK_NK_LP 44
|
||||
#define TK_NK_RP 45
|
||||
#define TK_NK_ID 46
|
||||
#define TK_NK_DOT 47
|
||||
#define TK_NK_COMMA 48
|
||||
#define TK_COMMENT 49
|
||||
#define TK_BOOL 50
|
||||
#define TK_TINYINT 51
|
||||
#define TK_SMALLINT 52
|
||||
#define TK_INT 53
|
||||
#define TK_INTEGER 54
|
||||
#define TK_BIGINT 55
|
||||
#define TK_FLOAT 56
|
||||
#define TK_DOUBLE 57
|
||||
#define TK_BINARY 58
|
||||
#define TK_TIMESTAMP 59
|
||||
#define TK_NCHAR 60
|
||||
#define TK_UNSIGNED 61
|
||||
#define TK_JSON 62
|
||||
#define TK_VARCHAR 63
|
||||
#define TK_MEDIUMBLOB 64
|
||||
#define TK_BLOB 65
|
||||
#define TK_VARBINARY 66
|
||||
#define TK_DECIMAL 67
|
||||
#define TK_SHOW 68
|
||||
#define TK_DATABASES 69
|
||||
#define TK_TABLES 70
|
||||
#define TK_NK_FLOAT 71
|
||||
#define TK_NK_BOOL 72
|
||||
#define TK_NK_VARIABLE 73
|
||||
#define TK_BETWEEN 74
|
||||
#define TK_IS 75
|
||||
#define TK_NULL 76
|
||||
#define TK_NK_LT 77
|
||||
#define TK_NK_GT 78
|
||||
#define TK_NK_LE 79
|
||||
#define TK_NK_GE 80
|
||||
#define TK_NK_NE 81
|
||||
#define TK_NK_EQ 82
|
||||
#define TK_LIKE 83
|
||||
#define TK_MATCH 84
|
||||
#define TK_NMATCH 85
|
||||
#define TK_IN 86
|
||||
#define TK_FROM 87
|
||||
#define TK_AS 88
|
||||
#define TK_JOIN 89
|
||||
#define TK_ON 90
|
||||
#define TK_INNER 91
|
||||
#define TK_SELECT 92
|
||||
#define TK_DISTINCT 93
|
||||
#define TK_WHERE 94
|
||||
#define TK_PARTITION 95
|
||||
#define TK_BY 96
|
||||
#define TK_SESSION 97
|
||||
#define TK_STATE_WINDOW 98
|
||||
#define TK_INTERVAL 99
|
||||
#define TK_SLIDING 100
|
||||
#define TK_FILL 101
|
||||
#define TK_VALUE 102
|
||||
#define TK_NONE 103
|
||||
#define TK_PREV 104
|
||||
#define TK_LINEAR 105
|
||||
#define TK_NEXT 106
|
||||
#define TK_GROUP 107
|
||||
#define TK_HAVING 108
|
||||
#define TK_ORDER 109
|
||||
#define TK_SLIMIT 110
|
||||
#define TK_SOFFSET 111
|
||||
#define TK_LIMIT 112
|
||||
#define TK_OFFSET 113
|
||||
#define TK_ASC 114
|
||||
#define TK_DESC 115
|
||||
#define TK_NULLS 116
|
||||
#define TK_FIRST 117
|
||||
#define TK_LAST 118
|
||||
#define TK_STABLE 46
|
||||
#define TK_USING 47
|
||||
#define TK_TAGS 48
|
||||
#define TK_NK_ID 49
|
||||
#define TK_NK_DOT 50
|
||||
#define TK_NK_COMMA 51
|
||||
#define TK_COMMENT 52
|
||||
#define TK_BOOL 53
|
||||
#define TK_TINYINT 54
|
||||
#define TK_SMALLINT 55
|
||||
#define TK_INT 56
|
||||
#define TK_INTEGER 57
|
||||
#define TK_BIGINT 58
|
||||
#define TK_FLOAT 59
|
||||
#define TK_DOUBLE 60
|
||||
#define TK_BINARY 61
|
||||
#define TK_TIMESTAMP 62
|
||||
#define TK_NCHAR 63
|
||||
#define TK_UNSIGNED 64
|
||||
#define TK_JSON 65
|
||||
#define TK_VARCHAR 66
|
||||
#define TK_MEDIUMBLOB 67
|
||||
#define TK_BLOB 68
|
||||
#define TK_VARBINARY 69
|
||||
#define TK_DECIMAL 70
|
||||
#define TK_SMA 71
|
||||
#define TK_SHOW 72
|
||||
#define TK_DATABASES 73
|
||||
#define TK_TABLES 74
|
||||
#define TK_NK_FLOAT 75
|
||||
#define TK_NK_BOOL 76
|
||||
#define TK_NK_VARIABLE 77
|
||||
#define TK_BETWEEN 78
|
||||
#define TK_IS 79
|
||||
#define TK_NULL 80
|
||||
#define TK_NK_LT 81
|
||||
#define TK_NK_GT 82
|
||||
#define TK_NK_LE 83
|
||||
#define TK_NK_GE 84
|
||||
#define TK_NK_NE 85
|
||||
#define TK_NK_EQ 86
|
||||
#define TK_LIKE 87
|
||||
#define TK_MATCH 88
|
||||
#define TK_NMATCH 89
|
||||
#define TK_IN 90
|
||||
#define TK_FROM 91
|
||||
#define TK_AS 92
|
||||
#define TK_JOIN 93
|
||||
#define TK_ON 94
|
||||
#define TK_INNER 95
|
||||
#define TK_SELECT 96
|
||||
#define TK_DISTINCT 97
|
||||
#define TK_WHERE 98
|
||||
#define TK_PARTITION 99
|
||||
#define TK_BY 100
|
||||
#define TK_SESSION 101
|
||||
#define TK_STATE_WINDOW 102
|
||||
#define TK_INTERVAL 103
|
||||
#define TK_SLIDING 104
|
||||
#define TK_FILL 105
|
||||
#define TK_VALUE 106
|
||||
#define TK_NONE 107
|
||||
#define TK_PREV 108
|
||||
#define TK_LINEAR 109
|
||||
#define TK_NEXT 110
|
||||
#define TK_GROUP 111
|
||||
#define TK_HAVING 112
|
||||
#define TK_ORDER 113
|
||||
#define TK_SLIMIT 114
|
||||
#define TK_SOFFSET 115
|
||||
#define TK_LIMIT 116
|
||||
#define TK_OFFSET 117
|
||||
#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_ILLEGAL 302
|
||||
#define TK_HEX 303 // hex number 0x123
|
||||
#define TK_OCT 304 // oct number
|
||||
#define TK_BIN 305 // bin format data 0b111
|
||||
#define TK_FILE 306
|
||||
#define TK_QUESTION 307 // denoting the placeholder of "?",when invoking statement bind query
|
||||
#define TK_NK_ILLEGAL 302
|
||||
#define TK_NK_HEX 303 // hex number 0x123
|
||||
#define TK_NK_OCT 304 // oct number
|
||||
#define TK_NK_BIN 305 // bin format data 0b111
|
||||
#define TK_NK_FILE 306
|
||||
#define TK_NK_QUESTION 307 // denoting the placeholder of "?",when invoking statement bind query
|
||||
|
||||
#define TK_NK_COLON 500
|
||||
#define TK_NK_BITNOT 501
|
||||
#define TK_INSERT 502
|
||||
#define TK_INTO 503
|
||||
#define TK_NOW 504
|
||||
#define TK_TAGS 505
|
||||
#define TK_USING 506
|
||||
#define TK_VALUES 507
|
||||
#define TK_IMPORT 507
|
||||
#define TK_SEMI 508
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef struct STableOptions {
|
|||
int32_t keep;
|
||||
int32_t ttl;
|
||||
char comments[TSDB_STB_COMMENT_LEN];
|
||||
SNodeList* pSma;
|
||||
} STableOptions;
|
||||
|
||||
typedef struct SColumnDefNode {
|
||||
|
@ -73,10 +74,25 @@ typedef struct SCreateTableStmt {
|
|||
char tableName[TSDB_TABLE_NAME_LEN];
|
||||
bool ignoreExists;
|
||||
SNodeList* pCols;
|
||||
SNodeList* pTags;
|
||||
STableOptions options;
|
||||
} 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
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_VNODE_MODIF_STMT,
|
||||
QUERY_NODE_CREATE_DATABASE_STMT,
|
||||
QUERY_NODE_CREATE_TABLE_STMT,
|
||||
QUERY_NODE_CREATE_SUBTABLE_STMT,
|
||||
QUERY_NODE_CREATE_MULTI_TABLE_STMT,
|
||||
QUERY_NODE_USE_DATABASE_STMT,
|
||||
QUERY_NODE_SHOW_DATABASES_STMT, // temp
|
||||
QUERY_NODE_SHOW_TABLES_STMT, // temp
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct SValueNode {
|
|||
SExprNode node; // QUERY_NODE_VALUE
|
||||
char* literal;
|
||||
bool isDuration;
|
||||
bool translate;
|
||||
union {
|
||||
bool b;
|
||||
int64_t i;
|
||||
|
|
|
@ -94,11 +94,11 @@ void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type) {
|
|||
bool sign = true;
|
||||
|
||||
int32_t base = 10;
|
||||
if (type == TK_HEX) {
|
||||
if (type == TK_NK_HEX) {
|
||||
base = 16;
|
||||
} else if (type == TK_OCT) {
|
||||
} else if (type == TK_NK_OCT) {
|
||||
base = 8;
|
||||
} else if (type == TK_BIN) {
|
||||
} else if (type == TK_NK_BIN) {
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include "nodesint.h"
|
||||
#include "plannodes.h"
|
||||
#include "querynodes.h"
|
||||
#include "taos.h"
|
||||
|
@ -221,7 +222,7 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
printf("nodesCloneNode unknown node = %s\n", nodesNodeName(nodeType(pNode)));
|
||||
nodesWarn("nodesCloneNode unknown node = %s", nodesNodeName(nodeType(pNode)));
|
||||
return pDst;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nodesint.h"
|
||||
#include "plannodes.h"
|
||||
#include "querynodes.h"
|
||||
#include "query.h"
|
||||
|
@ -127,9 +128,8 @@ const char* nodesNodeName(ENodeType type) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
static char tmp[20];
|
||||
snprintf(tmp, sizeof(tmp), "Unknown %d", type);
|
||||
return tmp;
|
||||
nodesWarn("nodesNodeName unknown node = %d", type);
|
||||
return "UnknownNode";
|
||||
}
|
||||
|
||||
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* jkValueDuration = "Duration";
|
||||
static const char* jkValueTranslate = "Translate";
|
||||
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;
|
||||
|
||||
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) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
switch (pNode->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_NULL:
|
||||
break;
|
||||
|
@ -920,22 +914,34 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
|
|||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
|
||||
static int32_t jsonToDatum(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) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
switch (pNode->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_NULL:
|
||||
break;
|
||||
|
@ -972,6 +978,25 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
|
|||
default:
|
||||
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;
|
||||
|
@ -1365,7 +1390,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
printf("================================ specificNodeToJson unknown node = %s\n", nodesNodeName(nodeType(pObj)));
|
||||
nodesWarn("specificNodeToJson unknown node = %s", nodesNodeName(nodeType(pObj)));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1434,7 +1459,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
printf("================================ jsonToSpecificNode unknown node = %s\n", nodesNodeName(nodeType(pObj)));
|
||||
nodesWarn("jsonToSpecificNode unknown node = %s", nodesNodeName(nodeType(pObj)));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1450,6 +1475,9 @@ static int32_t nodeToJson(const void* pObj, SJson* pJson) {
|
|||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, nodesNodeName(pNode->type), specificNodeToJson, pNode);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesError("%s ToJson error", nodesNodeName(pNode->type));
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -1464,7 +1492,7 @@ static int32_t jsonToNode(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonToObject(pJson, nodesNodeName(pNode->type), jsonToSpecificNode, pNode);
|
||||
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 "querynodes.h"
|
||||
#include "nodesint.h"
|
||||
#include "plannodes.h"
|
||||
#include "querynodes.h"
|
||||
#include "taos.h"
|
||||
#include "taoserror.h"
|
||||
#include "taos.h"
|
||||
#include "thash.h"
|
||||
|
||||
static SNode* makeNode(ENodeType type, size_t size) {
|
||||
|
@ -84,6 +84,10 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SCreateDatabaseStmt));
|
||||
case QUERY_NODE_CREATE_TABLE_STMT:
|
||||
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:
|
||||
return makeNode(type, sizeof(SUseDatabaseStmt));
|
||||
case QUERY_NODE_SHOW_DATABASES_STMT:
|
||||
|
@ -132,7 +136,7 @@ SNodeptr nodesMakeNode(ENodeType type) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
printf("================================ nodesMakeNode unknown node = %s\n", nodesNodeName(type));
|
||||
nodesError("nodesMakeNode unknown node = %s", nodesNodeName(type));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,15 +110,20 @@ typedef enum ETableOptionType {
|
|||
TABLE_OPTION_KEEP = 0,
|
||||
TABLE_OPTION_TTL,
|
||||
TABLE_OPTION_COMMENT,
|
||||
TABLE_OPTION_SMA,
|
||||
|
||||
TABLE_OPTION_MAX
|
||||
} ETableOptionType;
|
||||
STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt);
|
||||
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);
|
||||
SDataType createDataType(uint8_t type);
|
||||
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);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
%token_prefix TK_
|
||||
%token_type { SToken }
|
||||
%default_type { SNode* }
|
||||
%default_destructor { PARSER_DESTRUCTOR_TRACE; nodesDestroyNode($$); }
|
||||
%default_destructor { nodesDestroyNode($$); }
|
||||
|
||||
%extra_argument { SAstCreateContext* pCxt }
|
||||
|
||||
|
@ -21,16 +21,6 @@
|
|||
#include "ttoken.h"
|
||||
#include "ttokendef.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 {
|
||||
|
@ -51,8 +41,6 @@
|
|||
pCxt->valid = false;
|
||||
}
|
||||
|
||||
%parse_accept { PARSER_COMPLETE; }
|
||||
|
||||
%left OR.
|
||||
%left AND.
|
||||
//%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);}
|
||||
|
||||
%type exists_opt { bool }
|
||||
%destructor exists_opt { }
|
||||
exists_opt(A) ::= IF NOT EXISTS. { A = true; }
|
||||
exists_opt(A) ::= . { A = false; }
|
||||
|
||||
|
@ -76,7 +65,7 @@ exists_opt(A) ::= .
|
|||
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) 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) 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); }
|
||||
|
@ -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) 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) SINGLESTABLE 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) SINGLE_STABLE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_SINGLESTABLE, &C); }
|
||||
db_options(A) ::= db_options(B) STREAM_MODE NK_INTEGER(C). { A = setDatabaseOption(pCxt, B, DB_OPTION_STREAMMODE, &C); }
|
||||
|
||||
/************************************************ create database *****************************************************/
|
||||
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)
|
||||
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 }
|
||||
%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_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* }
|
||||
%destructor table_options { tfree($$); }
|
||||
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) 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 ***************************************************************/
|
||||
cmd ::= SHOW DATABASES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); }
|
||||
cmd ::= SHOW TABLES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TABLES_STMT); }
|
||||
|
||||
/************************************************ select *************************************************************/
|
||||
cmd ::= query_expression(A). { PARSER_TRACE; pCxt->pRootNode = A; }
|
||||
cmd ::= query_expression(A). { pCxt->pRootNode = A; }
|
||||
|
||||
/************************************************ literal *************************************************************/
|
||||
literal(A) ::= NK_INTEGER(B). { PARSER_TRACE; 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_STRING(B). { PARSER_TRACE; 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) ::= TIMESTAMP(B) NK_STRING(C). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &C, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &C)); }
|
||||
literal(A) ::= duration_literal(B). { PARSER_TRACE; A = B; }
|
||||
literal(A) ::= NK_INTEGER(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &B)); }
|
||||
literal(A) ::= NK_FLOAT(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &B)); }
|
||||
literal(A) ::= NK_STRING(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &B)); }
|
||||
literal(A) ::= NK_BOOL(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &B)); }
|
||||
literal(A) ::= TIMESTAMP(B) NK_STRING(C). { A = createRawExprNodeExt(pCxt, &B, &C, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &C)); }
|
||||
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* }
|
||||
%destructor literal_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
literal_list(A) ::= literal(B). { PARSER_TRACE; 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)); }
|
||||
%destructor literal_list { nodesDestroyList($$); }
|
||||
literal_list(A) ::= literal(B). { A = createNodeList(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||
literal_list(A) ::= literal_list(B) NK_COMMA literal(C). { A = addNodeToList(pCxt, B, releaseRawExprNode(pCxt, C)); }
|
||||
|
||||
/************************************************ names and identifiers ***********************************************/
|
||||
%type db_name { SToken }
|
||||
%destructor db_name { PARSER_DESTRUCTOR_TRACE; }
|
||||
db_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
%destructor db_name { }
|
||||
db_name(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
%type table_name { SToken }
|
||||
%destructor table_name { PARSER_DESTRUCTOR_TRACE; }
|
||||
table_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
%destructor table_name { }
|
||||
table_name(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
%type column_name { SToken }
|
||||
%destructor column_name { PARSER_DESTRUCTOR_TRACE; }
|
||||
column_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
%destructor column_name { }
|
||||
column_name(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
%type function_name { SToken }
|
||||
%destructor function_name { PARSER_DESTRUCTOR_TRACE; }
|
||||
function_name(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
%destructor function_name { }
|
||||
function_name(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
%type table_alias { SToken }
|
||||
%destructor table_alias { PARSER_DESTRUCTOR_TRACE; }
|
||||
table_alias(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
%destructor table_alias { }
|
||||
table_alias(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
%type column_alias { SToken }
|
||||
%destructor column_alias { PARSER_DESTRUCTOR_TRACE; }
|
||||
column_alias(A) ::= NK_ID(B). { PARSER_TRACE; A = B; }
|
||||
%destructor column_alias { }
|
||||
column_alias(A) ::= NK_ID(B). { A = B; }
|
||||
|
||||
/************************************************ expression **********************************************************/
|
||||
expression(A) ::= literal(B). { PARSER_TRACE; A = B; }
|
||||
//expression(A) ::= NK_QUESTION(B). { PARSER_TRACE; A = B; }
|
||||
//expression(A) ::= pseudo_column(B). { PARSER_TRACE; A = B; }
|
||||
expression(A) ::= column_reference(B). { PARSER_TRACE; 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 NK_STAR(C) NK_RP(D). { PARSER_TRACE; 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) ::= case_expression(B). { PARSER_TRACE; A = B; }
|
||||
expression(A) ::= subquery(B). { PARSER_TRACE; A = B; }
|
||||
expression(A) ::= NK_LP(B) expression(C) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &D, releaseRawExprNode(pCxt, C)); }
|
||||
expression(A) ::= literal(B). { A = B; }
|
||||
//expression(A) ::= NK_QUESTION(B). { A = B; }
|
||||
//expression(A) ::= pseudo_column(B). { A = B; }
|
||||
expression(A) ::= column_reference(B). { A = B; }
|
||||
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). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, createNodeList(pCxt, createColumnNode(pCxt, NULL, &C)))); }
|
||||
//expression(A) ::= cast_expression(B). { A = B; }
|
||||
//expression(A) ::= case_expression(B). { A = B; }
|
||||
expression(A) ::= subquery(B). { A = B; }
|
||||
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). {
|
||||
PARSER_TRACE;
|
||||
SToken t = getTokenFromRawExprNode(pCxt, C);
|
||||
A = createRawExprNodeExt(pCxt, &B, &t, releaseRawExprNode(pCxt, C));
|
||||
}
|
||||
expression(A) ::= NK_MINUS(B) expression(C). {
|
||||
PARSER_TRACE;
|
||||
SToken t = getTokenFromRawExprNode(pCxt, C);
|
||||
A = createRawExprNodeExt(pCxt, &B, &t, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, C), NULL));
|
||||
}
|
||||
expression(A) ::= expression(B) NK_PLUS expression(C). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(pCxt, C);
|
||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MOD, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)));
|
||||
}
|
||||
|
||||
%type expression_list { SNodeList* }
|
||||
%destructor expression_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
expression_list(A) ::= expression(B). { PARSER_TRACE; 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)); }
|
||||
%destructor expression_list { nodesDestroyList($$); }
|
||||
expression_list(A) ::= expression(B). { A = createNodeList(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||
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) ::= table_name(B) NK_DOT column_name(C). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &B, &C, createColumnNode(pCxt, &B, &C)); }
|
||||
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). { 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(A) ::= expression(B) compare_op(C) expression(D). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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) BETWEEN expression(C) AND expression(D). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
A = createRawExprNodeExt(pCxt, &s, &C, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, B), NULL));
|
||||
}
|
||||
predicate(A) ::= expression(B) IS NOT NULL(C). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
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). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(pCxt, D);
|
||||
A = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, C, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, D)));
|
||||
}
|
||||
|
||||
%type compare_op { EOperatorType }
|
||||
%destructor compare_op { PARSER_DESTRUCTOR_TRACE; }
|
||||
compare_op(A) ::= NK_LT. { PARSER_TRACE; A = OP_TYPE_LOWER_THAN; }
|
||||
compare_op(A) ::= NK_GT. { PARSER_TRACE; A = OP_TYPE_GREATER_THAN; }
|
||||
compare_op(A) ::= NK_LE. { PARSER_TRACE; A = OP_TYPE_LOWER_EQUAL; }
|
||||
compare_op(A) ::= NK_GE. { PARSER_TRACE; A = OP_TYPE_GREATER_EQUAL; }
|
||||
compare_op(A) ::= NK_NE. { PARSER_TRACE; A = OP_TYPE_NOT_EQUAL; }
|
||||
compare_op(A) ::= NK_EQ. { PARSER_TRACE; A = OP_TYPE_EQUAL; }
|
||||
compare_op(A) ::= LIKE. { PARSER_TRACE; A = OP_TYPE_LIKE; }
|
||||
compare_op(A) ::= NOT LIKE. { PARSER_TRACE; A = OP_TYPE_NOT_LIKE; }
|
||||
compare_op(A) ::= MATCH. { PARSER_TRACE; A = OP_TYPE_MATCH; }
|
||||
compare_op(A) ::= NMATCH. { PARSER_TRACE; A = OP_TYPE_NMATCH; }
|
||||
%destructor compare_op { }
|
||||
compare_op(A) ::= NK_LT. { A = OP_TYPE_LOWER_THAN; }
|
||||
compare_op(A) ::= NK_GT. { A = OP_TYPE_GREATER_THAN; }
|
||||
compare_op(A) ::= NK_LE. { A = OP_TYPE_LOWER_EQUAL; }
|
||||
compare_op(A) ::= NK_GE. { A = OP_TYPE_GREATER_EQUAL; }
|
||||
compare_op(A) ::= NK_NE. { A = OP_TYPE_NOT_EQUAL; }
|
||||
compare_op(A) ::= NK_EQ. { A = OP_TYPE_EQUAL; }
|
||||
compare_op(A) ::= LIKE. { A = OP_TYPE_LIKE; }
|
||||
compare_op(A) ::= NOT LIKE. { A = OP_TYPE_NOT_LIKE; }
|
||||
compare_op(A) ::= MATCH. { A = OP_TYPE_MATCH; }
|
||||
compare_op(A) ::= NMATCH. { A = OP_TYPE_NMATCH; }
|
||||
|
||||
%type in_op { EOperatorType }
|
||||
%destructor in_op { PARSER_DESTRUCTOR_TRACE; }
|
||||
in_op(A) ::= IN. { PARSER_TRACE; A = OP_TYPE_IN; }
|
||||
in_op(A) ::= NOT IN. { PARSER_TRACE; A = OP_TYPE_NOT_IN; }
|
||||
%destructor in_op { }
|
||||
in_op(A) ::= IN. { A = OP_TYPE_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(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). {
|
||||
PARSER_TRACE;
|
||||
SToken e = getTokenFromRawExprNode(pCxt, B);
|
||||
A = createRawExprNodeExt(pCxt, &C, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, B), NULL));
|
||||
}
|
||||
boolean_value_expression(A) ::=
|
||||
boolean_value_expression(B) OR boolean_value_expression(C). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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(B) AND boolean_value_expression(C). {
|
||||
PARSER_TRACE;
|
||||
SToken s = getTokenFromRawExprNode(pCxt, B);
|
||||
SToken e = getTokenFromRawExprNode(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) ::= NK_LP(C) boolean_value_expression(B) NK_RP(D). { PARSER_TRACE; A = createRawExprNodeExt(pCxt, &C, &D, releaseRawExprNode(pCxt, B)); }
|
||||
boolean_primary(A) ::= predicate(B). { A = 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(A) ::= expression(B). { A = B; }
|
||||
common_expression(A) ::= boolean_value_expression(B). { A = B; }
|
||||
|
||||
/************************************************ 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_list(B) NK_COMMA table_reference(C). { PARSER_TRACE; A = createJoinTableNode(pCxt, JOIN_TYPE_INNER, B, C, NULL); }
|
||||
table_reference_list(A) ::= table_reference(B). { A = B; }
|
||||
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(A) ::= table_primary(B). { PARSER_TRACE; A = B; }
|
||||
table_reference(A) ::= joined_table(B). { PARSER_TRACE; A = B; }
|
||||
table_reference(A) ::= table_primary(B). { 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) ::= db_name(B) NK_DOT table_name(C) alias_opt(D). { PARSER_TRACE; 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) ::= parenthesized_joined_table(B). { PARSER_TRACE; A = B; }
|
||||
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). { A = createRealTableNode(pCxt, &B, &C, &D); }
|
||||
table_primary(A) ::= subquery(B) alias_opt(C). { A = createTempTableNode(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||
table_primary(A) ::= parenthesized_joined_table(B). { A = B; }
|
||||
|
||||
%type alias_opt { SToken }
|
||||
%destructor alias_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
alias_opt(A) ::= . { PARSER_TRACE; A = nil_token; }
|
||||
alias_opt(A) ::= table_alias(B). { PARSER_TRACE; A = B; }
|
||||
alias_opt(A) ::= AS table_alias(B). { PARSER_TRACE; A = B; }
|
||||
%destructor alias_opt { }
|
||||
alias_opt(A) ::= . { A = nil_token; }
|
||||
alias_opt(A) ::= table_alias(B). { 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 parenthesized_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. { A = B; }
|
||||
|
||||
/************************************************ joined_table ********************************************************/
|
||||
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 }
|
||||
%destructor join_type { PARSER_DESTRUCTOR_TRACE; }
|
||||
join_type(A) ::= . { PARSER_TRACE; A = JOIN_TYPE_INNER; }
|
||||
join_type(A) ::= INNER. { PARSER_TRACE; A = JOIN_TYPE_INNER; }
|
||||
%destructor join_type { }
|
||||
join_type(A) ::= . { A = JOIN_TYPE_INNER; }
|
||||
join_type(A) ::= INNER. { A = JOIN_TYPE_INNER; }
|
||||
|
||||
/************************************************ query_specification *************************************************/
|
||||
query_specification(A) ::=
|
||||
SELECT set_quantifier_opt(B) select_list(C) from_clause(D) where_clause_opt(E)
|
||||
partition_by_clause_opt(F) twindow_clause_opt(G)
|
||||
group_by_clause_opt(H) having_clause_opt(I). {
|
||||
PARSER_TRACE;
|
||||
A = createSelectStmt(pCxt, B, C, D);
|
||||
A = addWhereClause(pCxt, A, E);
|
||||
A = addPartitionByClause(pCxt, A, F);
|
||||
|
@ -388,134 +396,132 @@ query_specification(A) ::=
|
|||
}
|
||||
|
||||
%type set_quantifier_opt { bool }
|
||||
%destructor set_quantifier_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
set_quantifier_opt(A) ::= . { PARSER_TRACE; A = false; }
|
||||
set_quantifier_opt(A) ::= DISTINCT. { PARSER_TRACE; A = true; }
|
||||
set_quantifier_opt(A) ::= ALL. { PARSER_TRACE; A = false; }
|
||||
%destructor set_quantifier_opt { }
|
||||
set_quantifier_opt(A) ::= . { A = false; }
|
||||
set_quantifier_opt(A) ::= DISTINCT. { A = true; }
|
||||
set_quantifier_opt(A) ::= ALL. { A = false; }
|
||||
|
||||
%type select_list { SNodeList* }
|
||||
%destructor select_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
select_list(A) ::= NK_STAR. { PARSER_TRACE; A = NULL; }
|
||||
select_list(A) ::= select_sublist(B). { PARSER_TRACE; A = B; }
|
||||
%destructor select_list { nodesDestroyList($$); }
|
||||
select_list(A) ::= NK_STAR. { A = NULL; }
|
||||
select_list(A) ::= select_sublist(B). { A = B; }
|
||||
|
||||
%type select_sublist { SNodeList* }
|
||||
%destructor select_sublist { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
select_sublist(A) ::= select_item(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
||||
select_sublist(A) ::= select_sublist(B) NK_COMMA select_item(C). { PARSER_TRACE; A = addNodeToList(pCxt, B, C); }
|
||||
%destructor select_sublist { nodesDestroyList($$); }
|
||||
select_sublist(A) ::= select_item(B). { A = createNodeList(pCxt, B); }
|
||||
select_sublist(A) ::= select_sublist(B) NK_COMMA select_item(C). { A = addNodeToList(pCxt, B, C); }
|
||||
|
||||
select_item(A) ::= common_expression(B). {
|
||||
PARSER_TRACE;
|
||||
SToken t = getTokenFromRawExprNode(pCxt, B);
|
||||
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) AS column_alias(C). { PARSER_TRACE; 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) ::= common_expression(B) column_alias(C). { 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). { A = createColumnNode(pCxt, &B, &C); }
|
||||
|
||||
where_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
where_clause_opt(A) ::= WHERE search_condition(B). { PARSER_TRACE; A = B; }
|
||||
where_clause_opt(A) ::= . { A = NULL; }
|
||||
where_clause_opt(A) ::= WHERE search_condition(B). { A = B; }
|
||||
|
||||
%type partition_by_clause_opt { SNodeList* }
|
||||
%destructor partition_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
partition_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
partition_by_clause_opt(A) ::= PARTITION BY expression_list(B). { PARSER_TRACE; A = B; }
|
||||
%destructor partition_by_clause_opt { nodesDestroyList($$); }
|
||||
partition_by_clause_opt(A) ::= . { A = NULL; }
|
||||
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) ::=
|
||||
SESSION NK_LP column_reference(B) NK_COMMA NK_INTEGER(C) NK_RP. { PARSER_TRACE; 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)); }
|
||||
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. { A = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||
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) ::=
|
||||
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) ::= SLIDING NK_LP duration_literal(B) NK_RP. { PARSER_TRACE; A = B; }
|
||||
sliding_opt(A) ::= . { A = NULL; }
|
||||
sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { A = B; }
|
||||
|
||||
fill_opt(A) ::= . { PARSER_TRACE; 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 VALUE NK_COMMA literal_list(B) NK_RP. { PARSER_TRACE; A = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, B)); }
|
||||
fill_opt(A) ::= . { A = 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. { A = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, B)); }
|
||||
|
||||
%type fill_mode { EFillMode }
|
||||
%destructor fill_mode { PARSER_DESTRUCTOR_TRACE; }
|
||||
fill_mode(A) ::= NONE. { PARSER_TRACE; A = FILL_MODE_NONE; }
|
||||
fill_mode(A) ::= PREV. { PARSER_TRACE; A = FILL_MODE_PREV; }
|
||||
fill_mode(A) ::= NULL. { PARSER_TRACE; A = FILL_MODE_NULL; }
|
||||
fill_mode(A) ::= LINEAR. { PARSER_TRACE; A = FILL_MODE_LINEAR; }
|
||||
fill_mode(A) ::= NEXT. { PARSER_TRACE; A = FILL_MODE_NEXT; }
|
||||
%destructor fill_mode { }
|
||||
fill_mode(A) ::= NONE. { A = FILL_MODE_NONE; }
|
||||
fill_mode(A) ::= PREV. { A = FILL_MODE_PREV; }
|
||||
fill_mode(A) ::= NULL. { A = FILL_MODE_NULL; }
|
||||
fill_mode(A) ::= LINEAR. { A = FILL_MODE_LINEAR; }
|
||||
fill_mode(A) ::= NEXT. { A = FILL_MODE_NEXT; }
|
||||
|
||||
%type group_by_clause_opt { SNodeList* }
|
||||
%destructor group_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
group_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
group_by_clause_opt(A) ::= GROUP BY group_by_list(B). { PARSER_TRACE; A = B; }
|
||||
%destructor group_by_clause_opt { nodesDestroyList($$); }
|
||||
group_by_clause_opt(A) ::= . { A = NULL; }
|
||||
group_by_clause_opt(A) ::= GROUP BY group_by_list(B). { A = B; }
|
||||
|
||||
%type group_by_list { SNodeList* }
|
||||
%destructor group_by_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
group_by_list(A) ::= expression(B). { PARSER_TRACE; 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))); }
|
||||
%destructor group_by_list { nodesDestroyList($$); }
|
||||
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). { A = addNodeToList(pCxt, B, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, C))); }
|
||||
|
||||
having_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
having_clause_opt(A) ::= HAVING search_condition(B). { PARSER_TRACE; A = B; }
|
||||
having_clause_opt(A) ::= . { A = NULL; }
|
||||
having_clause_opt(A) ::= HAVING search_condition(B). { A = B; }
|
||||
|
||||
/************************************************ query_expression ****************************************************/
|
||||
query_expression(A) ::=
|
||||
query_expression_body(B)
|
||||
order_by_clause_opt(C) slimit_clause_opt(D) limit_clause_opt(E). {
|
||||
PARSER_TRACE;
|
||||
A = addOrderByClause(pCxt, B, C);
|
||||
A = addSlimitClause(pCxt, A, D);
|
||||
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(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) ::=
|
||||
// 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* }
|
||||
%destructor order_by_clause_opt { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
order_by_clause_opt(A) ::= . { PARSER_TRACE; A = NULL; }
|
||||
order_by_clause_opt(A) ::= ORDER BY sort_specification_list(B). { PARSER_TRACE; A = B; }
|
||||
%destructor order_by_clause_opt { nodesDestroyList($$); }
|
||||
order_by_clause_opt(A) ::= . { A = NULL; }
|
||||
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) ::= SLIMIT NK_INTEGER(B). { PARSER_TRACE; 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(C) NK_COMMA NK_INTEGER(B). { PARSER_TRACE; A = createLimitNode(pCxt, &B, &C); }
|
||||
slimit_clause_opt(A) ::= . { A = 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). { 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) ::= LIMIT NK_INTEGER(B). { PARSER_TRACE; 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(C) NK_COMMA NK_INTEGER(B). { PARSER_TRACE; A = createLimitNode(pCxt, &B, &C); }
|
||||
limit_clause_opt(A) ::= . { A = 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). { 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(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(A) ::= common_expression(B). { PARSER_TRACE; A = releaseRawExprNode(pCxt, B); }
|
||||
search_condition(A) ::= common_expression(B). { A = releaseRawExprNode(pCxt, B); }
|
||||
|
||||
/************************************************ sort_specification_list *********************************************/
|
||||
%type sort_specification_list { SNodeList* }
|
||||
%destructor sort_specification_list { PARSER_DESTRUCTOR_TRACE; nodesDestroyList($$); }
|
||||
sort_specification_list(A) ::= sort_specification(B). { PARSER_TRACE; A = createNodeList(pCxt, B); }
|
||||
%destructor sort_specification_list { nodesDestroyList($$); }
|
||||
sort_specification_list(A) ::= sort_specification(B). { A = createNodeList(pCxt, B); }
|
||||
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) ::=
|
||||
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
|
||||
%destructor ordering_specification_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
ordering_specification_opt(A) ::= . { PARSER_TRACE; A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= ASC. { PARSER_TRACE; A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= DESC. { PARSER_TRACE; A = ORDER_DESC; }
|
||||
%destructor ordering_specification_opt { }
|
||||
ordering_specification_opt(A) ::= . { A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= ASC. { A = ORDER_ASC; }
|
||||
ordering_specification_opt(A) ::= DESC. { A = ORDER_DESC; }
|
||||
|
||||
%type null_ordering_opt ENullOrder
|
||||
%destructor null_ordering_opt { PARSER_DESTRUCTOR_TRACE; }
|
||||
null_ordering_opt(A) ::= . { PARSER_TRACE; A = NULL_ORDER_DEFAULT; }
|
||||
null_ordering_opt(A) ::= NULLS FIRST. { PARSER_TRACE; A = NULL_ORDER_FIRST; }
|
||||
null_ordering_opt(A) ::= NULLS LAST. { PARSER_TRACE; A = NULL_ORDER_LAST; }
|
||||
%destructor null_ordering_opt { }
|
||||
null_ordering_opt(A) ::= . { A = NULL_ORDER_DEFAULT; }
|
||||
null_ordering_opt(A) ::= NULLS FIRST. { A = NULL_ORDER_FIRST; }
|
||||
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 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);
|
||||
SSchema *getTableColumnSchema(const STableMeta *pTableMeta);
|
||||
SSchema *getTableTagSchema(const STableMeta* pTableMeta);
|
||||
|
@ -49,6 +39,8 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta);
|
|||
int32_t getNumOfTags(const STableMeta* pTableMeta);
|
||||
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
||||
|
||||
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct SToken {
|
|||
* @return
|
||||
*/
|
||||
#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
|
||||
|
@ -67,11 +67,11 @@ bool taosIsKeyWordToken(const char *z, int32_t len);
|
|||
/**
|
||||
* check if it is a token or not
|
||||
* @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) {
|
||||
const char* z = pToken->z;
|
||||
int32_t type = TK_ILLEGAL;
|
||||
int32_t type = TK_NK_ILLEGAL;
|
||||
|
||||
uint32_t i = 0;
|
||||
for(; i < pToken->n; ++i) {
|
||||
|
@ -88,7 +88,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
|||
* .123e4
|
||||
*/
|
||||
if (!isdigit(z[i+1])) {
|
||||
return TK_ILLEGAL;
|
||||
return TK_NK_ILLEGAL;
|
||||
}
|
||||
|
||||
for (i += 2; isdigit(z[i]); i++) {
|
||||
|
@ -109,13 +109,13 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
|||
case '0': {
|
||||
char next = z[i + 1];
|
||||
if (next == 'b') { // bin number
|
||||
type = TK_BIN;
|
||||
type = TK_NK_BIN;
|
||||
for (i += 2; (z[i] == '0' || z[i] == '1'); ++i) {
|
||||
}
|
||||
|
||||
goto _end;
|
||||
} 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) {
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
|||
}
|
||||
|
||||
if (seg > 1) {
|
||||
return TK_ILLEGAL;
|
||||
return TK_NK_ILLEGAL;
|
||||
}
|
||||
|
||||
if ((z[i] == 'e' || z[i] == 'E') &&
|
||||
|
@ -164,12 +164,12 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
|
|||
goto _end;
|
||||
}
|
||||
default:
|
||||
return TK_ILLEGAL;
|
||||
return TK_NK_ILLEGAL;
|
||||
}
|
||||
}
|
||||
|
||||
_end:
|
||||
return (i < pToken->n)? TK_ILLEGAL:type;
|
||||
return (i < pToken->n)? TK_NK_ILLEGAL:type;
|
||||
}
|
||||
|
||||
void taosCleanupKeywordsTable();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "astCreateFuncs.h"
|
||||
#include "parserUtil.h"
|
||||
|
||||
#define CHECK_OUT_OF_MEM(p) \
|
||||
do { \
|
||||
|
@ -149,16 +150,16 @@ static SDatabaseOptions* setDbKeep(SAstCreateContext* pCxt, SDatabaseOptions* pO
|
|||
}
|
||||
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
} else {
|
||||
char tmp[10];
|
||||
strncpy(tmp, pVal->z, pVal->n);
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option precision: %s", tmp);
|
||||
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option precision: %s", val);
|
||||
pCxt->valid = false;
|
||||
}
|
||||
return pOptions;
|
||||
|
@ -296,7 +297,7 @@ static STableOptions* setTableComment(SAstCreateContext* pCxt, STableOptions* pO
|
|||
pCxt->valid = false;
|
||||
return pOptions;
|
||||
}
|
||||
strncpy(pOptions->comments, pVal->z, pVal->n);
|
||||
trimString(pVal->z, pVal->n, pOptions->comments, sizeof(pOptions->comments));
|
||||
return pOptions;
|
||||
}
|
||||
|
||||
|
@ -413,6 +414,8 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
|
|||
if (TSDB_DATA_TYPE_TIMESTAMP == dataType) {
|
||||
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
||||
}
|
||||
val->isDuration = false;
|
||||
val->translate = false;
|
||||
return (SNode*)val;
|
||||
}
|
||||
|
||||
|
@ -422,6 +425,7 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral)
|
|||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||
CHECK_OUT_OF_MEM(val->literal);
|
||||
val->isDuration = true;
|
||||
val->translate = false;
|
||||
val->node.resType.type = TSDB_DATA_TYPE_BIGINT;
|
||||
val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
|
||||
|
@ -708,13 +712,18 @@ STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions,
|
|||
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) {
|
||||
SColumnDefNode* pCol = (SColumnDefNode*)nodesMakeNode(QUERY_NODE_COLUMN_DEF);
|
||||
CHECK_OUT_OF_MEM(pCol);
|
||||
strncpy(pCol->colName, pColName->z, pColName->n);
|
||||
pCol->dataType = dataType;
|
||||
if (NULL != pComment) {
|
||||
strncpy(pCol->comments, pComment->z, pComment->n);
|
||||
trimString(pComment->z, pComment->n, pCol->comments, sizeof(pCol->comments));
|
||||
}
|
||||
return (SNode*)pCol;
|
||||
}
|
||||
|
@ -730,19 +739,51 @@ SDataType createVarLenDataType(uint8_t type, const SToken* pLen) {
|
|||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
pStmt->ignoreExists = ignoreExists;
|
||||
pStmt->pCols = pCols;
|
||||
pStmt->pTags = pTags;
|
||||
pStmt->options = *pOptions;
|
||||
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) {
|
||||
SUseDatabaseStmt* pStmt = (SUseDatabaseStmt*)nodesMakeNode(QUERY_NODE_USE_DATABASE_STMT);
|
||||
CHECK_OUT_OF_MEM(pStmt);
|
||||
|
|
|
@ -26,22 +26,6 @@ extern void NewParse(void*, int, SToken, void*);
|
|||
extern void NewParseFree(void*, FFree);
|
||||
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) {
|
||||
SAstCreateContext cxt;
|
||||
initAstCreateContext(pParseCxt, &cxt);
|
||||
|
@ -58,23 +42,23 @@ int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
|
|||
i += t0.n;
|
||||
|
||||
switch (t0.type) {
|
||||
case TK_SPACE:
|
||||
case TK_COMMENT: {
|
||||
case TK_NK_SPACE:
|
||||
case TK_NK_COMMENT: {
|
||||
break;
|
||||
}
|
||||
case TK_SEMI: {
|
||||
NewParse(pParser, 0, t0, &cxt);
|
||||
goto abort_parse;
|
||||
}
|
||||
case TK_QUESTION:
|
||||
case TK_ILLEGAL: {
|
||||
case TK_NK_QUESTION:
|
||||
case TK_NK_ILLEGAL: {
|
||||
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
|
||||
cxt.valid = false;
|
||||
goto abort_parse;
|
||||
}
|
||||
case TK_HEX:
|
||||
case TK_OCT:
|
||||
case TK_BIN: {
|
||||
case TK_NK_HEX:
|
||||
case TK_NK_OCT:
|
||||
case TK_NK_BIN: {
|
||||
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z);
|
||||
cxt.valid = false;
|
||||
goto abort_parse;
|
||||
|
@ -95,7 +79,7 @@ abort_parse:
|
|||
if (NULL == *pQuery) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
setQuery(&cxt, *pQuery);
|
||||
(*pQuery)->pRoot = cxt.pRootNode;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
if (format) {
|
||||
varDataSetLen(dst, len);
|
||||
dstVal = varDataVal(dst);
|
||||
}
|
||||
// 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 (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;
|
||||
return trimString(src, len, dstVal, len);
|
||||
}
|
||||
|
||||
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);
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
trimStringCopy(pVal->literal, n, true, pVal->datum.p);
|
||||
trimStringWithVarFormat(pVal->literal, n, true, pVal->datum.p);
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
|
@ -361,7 +345,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||
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) {
|
||||
tfree(tmp);
|
||||
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
|
||||
|
@ -378,6 +362,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
pVal->translate = true;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -856,6 +841,47 @@ static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseS
|
|||
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) {
|
||||
SName name = {0};
|
||||
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:
|
||||
code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_CREATE_TABLE_STMT:
|
||||
code = translateCreateSTable(pCxt, (SCreateTableStmt*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_USE_DATABASE_STMT:
|
||||
code = translateUseDatabase(pCxt, (SUseDatabaseStmt*)pNode);
|
||||
break;
|
||||
|
@ -1020,7 +1049,7 @@ static int32_t doBuildSingleTableBatchReq(SName* pTableName, SNodeList* pColumns
|
|||
pBatch->info = *pVgroupInfo;
|
||||
pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
|
||||
if (pBatch->req.pArray == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
taosArrayPush(pBatch->req.pArray, &req);
|
||||
|
@ -1031,7 +1060,7 @@ static int32_t serializeVgroupTablesBatchImpl(SVgroupTablesBatch* pTbBatch, SArr
|
|||
int tlen = sizeof(SMsgHead) + tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req));
|
||||
void* buf = malloc(tlen);
|
||||
if (buf == NULL) {
|
||||
// TODO: handle error
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
|
||||
|
@ -1068,15 +1097,11 @@ static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) {
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
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.tname, pStmt->tableName);
|
||||
SVgroupInfo info = {0};
|
||||
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);
|
||||
if (pBufArray == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
serializeVgroupTablesBatchImpl(&tbatch, pBufArray);
|
||||
destroyCreateTbReqBatch(&tbatch);
|
||||
|
||||
SVnodeModifOpStmt* pNewStmt = nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT);
|
||||
if (pNewStmt == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
pNewStmt->sqlNodeType = nodeType(pQuery->pRoot);
|
||||
pNewStmt->pDataBlocks = pBufArray;
|
||||
pQuery->sqlNodeType = nodeType(pQuery->pRoot);
|
||||
|
@ -1105,6 +1133,31 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
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) {
|
||||
STranslateContext cxt = {
|
||||
.pParseCxt = pParseCxt,
|
||||
|
@ -1122,13 +1175,7 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
|
|||
code = translateQuery(&cxt, pQuery->pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pQuery->directRpc) {
|
||||
pQuery->pCmdMsg = cxt.pCmdMsg;
|
||||
cxt.pCmdMsg = NULL;
|
||||
}
|
||||
if (pQuery->haveResultSet) {
|
||||
code = setReslutSchema(&cxt, pQuery);
|
||||
}
|
||||
code = setQuery(&cxt, pQuery);
|
||||
}
|
||||
destroyTranslateContext(&cxt);
|
||||
return code;
|
||||
|
|
|
@ -80,6 +80,68 @@ static int32_t skipInsertInto(SInsertParseContext* pCxt) {
|
|||
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) {
|
||||
if (parserValidateIdToken(pStname) != TSDB_CODE_SUCCESS) {
|
||||
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) {
|
||||
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)) {
|
||||
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
|
||||
if ((*endPtr - pToken->z) != pToken->n) {
|
||||
return TK_ILLEGAL;
|
||||
return TK_NK_ILLEGAL;
|
||||
}
|
||||
|
||||
return pToken->type;
|
||||
|
@ -496,7 +558,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
|
|||
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
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);
|
||||
}
|
||||
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: {
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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, ...)
|
||||
static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pTagsSchema, uint8_t precision) {
|
||||
if (tdInitKVRowBuilder(&pCxt->tagsBuilder) < 0) {
|
||||
|
@ -893,7 +986,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
|
|||
}
|
||||
|
||||
// FILE csv_file_path
|
||||
if (TK_FILE == sToken.type) {
|
||||
if (TK_NK_FILE == sToken.type) {
|
||||
// pSql -> csv_file_path
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
assert(pTableMeta != NULL);
|
||||
|
||||
|
@ -184,3 +97,26 @@ STableComInfo getTableInfo(const STableMeta* pTableMeta) {
|
|||
assert(pTableMeta != NULL);
|
||||
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
|
||||
static SKeyword keywordTable[] = {
|
||||
// {"ID", TK_ID},
|
||||
{"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},
|
||||
{"ALL", TK_ALL},
|
||||
{"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},
|
||||
{"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},
|
||||
// {"NE", TK_NE},
|
||||
// {"ISNULL", TK_ISNULL},
|
||||
// {"NOTNULL", TK_NOTNULL},
|
||||
{"IS", TK_IS},
|
||||
{"LIKE", TK_LIKE},
|
||||
{"MATCH", TK_MATCH},
|
||||
// {"GLOB", TK_GLOB},
|
||||
{"BETWEEN", TK_BETWEEN},
|
||||
{"IN", TK_IN},
|
||||
// {"GT", TK_GT},
|
||||
// {"GE", TK_GE},
|
||||
// {"LT", TK_LT},
|
||||
|
@ -64,7 +134,6 @@ static SKeyword keywordTable[] = {
|
|||
// {"LSHIFT", TK_LSHIFT},
|
||||
// {"RSHIFT", TK_RSHIFT},
|
||||
// {"PLUS", TK_PLUS},
|
||||
{"MINUS", TK_MINUS},
|
||||
// {"DIVIDE", TK_DIVIDE},
|
||||
// {"TIMES", TK_TIMES},
|
||||
// {"STAR", TK_STAR},
|
||||
|
@ -74,8 +143,6 @@ static SKeyword keywordTable[] = {
|
|||
// {"UMINUS", TK_UMINUS},
|
||||
// {"UPLUS", TK_UPLUS},
|
||||
// {"BITNOT", TK_BITNOT},
|
||||
{"SHOW", TK_SHOW},
|
||||
{"DATABASES", TK_DATABASES},
|
||||
// {"MNODES", TK_MNODES},
|
||||
// {"DNODES", TK_DNODES},
|
||||
// {"ACCOUNTS", TK_ACCOUNTS},
|
||||
|
@ -88,25 +155,17 @@ static SKeyword keywordTable[] = {
|
|||
// {"SCORES", TK_SCORES},
|
||||
// {"GRANTS", TK_GRANTS},
|
||||
// {"DOT", TK_DOT},
|
||||
{"TABLES", TK_TABLES},
|
||||
// {"STABLES", TK_STABLES},
|
||||
{"VGROUPS", TK_VGROUPS},
|
||||
// {"DROP", TK_DROP},
|
||||
{"TABLE", TK_TABLE},
|
||||
{"DATABASE", TK_DATABASE},
|
||||
// {"DNODE", TK_DNODE},
|
||||
// {"USER", TK_USER},
|
||||
// {"ACCOUNT", TK_ACCOUNT},
|
||||
{"USE", TK_USE},
|
||||
// {"DESCRIBE", TK_DESCRIBE},
|
||||
// {"SYNCDB", TK_SYNCDB},
|
||||
// {"ALTER", TK_ALTER},
|
||||
// {"PASS", TK_PASS},
|
||||
// {"PRIVILEGE", TK_PRIVILEGE},
|
||||
// {"LOCAL", TK_LOCAL},
|
||||
{"IF", TK_IF},
|
||||
{"EXISTS", TK_EXISTS},
|
||||
{"CREATE", TK_CREATE},
|
||||
// {"PPS", TK_PPS},
|
||||
// {"TSERIES", TK_TSERIES},
|
||||
// {"DBS", TK_DBS},
|
||||
|
@ -114,51 +173,13 @@ static SKeyword keywordTable[] = {
|
|||
// {"QTIME", TK_QTIME},
|
||||
// {"CONNS", TK_CONNS},
|
||||
// {"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},
|
||||
{"WAL", TK_WAL},
|
||||
{"FSYNC", TK_FSYNC},
|
||||
{"COMP", TK_COMP},
|
||||
{"PRECISION", TK_PRECISION},
|
||||
// {"LP", TK_LP},
|
||||
// {"RP", TK_RP},
|
||||
// {"UNSIGNED", TK_UNSIGNED},
|
||||
{"TAGS", TK_TAGS},
|
||||
{"USING", TK_USING},
|
||||
{"AS", TK_AS},
|
||||
|
||||
// {"COMMA", TK_COMMA},
|
||||
{"NULL", TK_NULL},
|
||||
{"SELECT", TK_SELECT},
|
||||
// {"EVERY", TK_EVERY},
|
||||
{"FROM", TK_FROM},
|
||||
// {"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},
|
||||
// {"RESET", TK_RESET},
|
||||
// {"QUERY", TK_QUERY},
|
||||
|
@ -192,8 +213,6 @@ static SKeyword keywordTable[] = {
|
|||
// {"IMMEDIATE", TK_IMMEDIATE},
|
||||
// {"INITIALLY", TK_INITIALLY},
|
||||
// {"INSTEAD", TK_INSTEAD},
|
||||
{"MATCH", TK_MATCH},
|
||||
{"NMATCH", TK_NMATCH},
|
||||
// {"KEY", TK_KEY},
|
||||
// {"OF", TK_OF},
|
||||
// {"RAISE", TK_RAISE},
|
||||
|
@ -203,20 +222,10 @@ static SKeyword keywordTable[] = {
|
|||
// {"STATEMENT", TK_STATEMENT},
|
||||
// {"TRIGGER", TK_TRIGGER},
|
||||
// {"VIEW", TK_VIEW},
|
||||
{"ALL", TK_ALL},
|
||||
// {"SEMI", TK_SEMI},
|
||||
{"NONE", TK_NONE},
|
||||
{"PREV", TK_PREV},
|
||||
{"LINEAR", TK_LINEAR},
|
||||
{"IMPORT", TK_IMPORT},
|
||||
// {"TBNAME", TK_TBNAME},
|
||||
{"JOIN", TK_JOIN},
|
||||
// {"STABLE", TK_STABLE},
|
||||
{"FILE", TK_FILE},
|
||||
// {"VNODES", TK_VNODES},
|
||||
{"UNION", TK_UNION},
|
||||
{"CACHELAST", TK_CACHELAST},
|
||||
{"DISTINCT", TK_DISTINCT},
|
||||
// {"PARTITIONS", TK_PARTITIONS},
|
||||
// {"TOPIC", TK_TOPIC},
|
||||
// {"TOPICS", TK_TOPICS},
|
||||
|
@ -228,8 +237,6 @@ static SKeyword keywordTable[] = {
|
|||
// {"AGGREGATE", TK_AGGREGATE},
|
||||
// {"BUFSIZE", TK_BUFSIZE},
|
||||
// {"PORT", TK_PORT},
|
||||
{"INNER", TK_INNER},
|
||||
{"ON", TK_ON},
|
||||
// {"MODE", TK_MODE},
|
||||
};
|
||||
|
||||
|
@ -277,7 +284,7 @@ static int32_t tKeywordCode(const char* z, int n) {
|
|||
}
|
||||
|
||||
if (keywordHashTable == NULL) {
|
||||
return TK_ILLEGAL;
|
||||
return TK_NK_ILLEGAL;
|
||||
}
|
||||
|
||||
SKeyword** pKey = (SKeyword**)taosHashGet(keywordHashTable, key, n);
|
||||
|
@ -298,7 +305,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
|||
case '\r': {
|
||||
for (i = 1; isspace(z[i]); i++) {
|
||||
}
|
||||
*tokenId = TK_SPACE;
|
||||
*tokenId = TK_NK_SPACE;
|
||||
return i;
|
||||
}
|
||||
case ':': {
|
||||
|
@ -383,7 +390,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
|||
}
|
||||
case '!': {
|
||||
if (z[1] != '=') {
|
||||
*tokenId = TK_ILLEGAL;
|
||||
*tokenId = TK_NK_ILLEGAL;
|
||||
return 2;
|
||||
} else {
|
||||
*tokenId = TK_NK_NE;
|
||||
|
@ -412,7 +419,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
|||
return 1;
|
||||
}
|
||||
case '?': {
|
||||
*tokenId = TK_QUESTION;
|
||||
*tokenId = TK_NK_QUESTION;
|
||||
return 1;
|
||||
}
|
||||
case '`':
|
||||
|
@ -475,7 +482,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
|||
char next = z[1];
|
||||
|
||||
if (next == 'b') { // bin number
|
||||
*tokenId = TK_BIN;
|
||||
*tokenId = TK_NK_BIN;
|
||||
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;
|
||||
} 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) {
|
||||
}
|
||||
|
||||
|
@ -574,7 +581,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
|||
}
|
||||
}
|
||||
|
||||
*tokenId = TK_ILLEGAL;
|
||||
*tokenId = TK_NK_ILLEGAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -608,7 +615,7 @@ SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
|||
return t0;
|
||||
}
|
||||
|
||||
// IGNORE TK_SPACE, TK_COMMA, and specified tokens
|
||||
// IGNORE TK_NK_SPACE, TK_NK_COMMA, and specified tokens
|
||||
while (1) {
|
||||
*i += t0.n;
|
||||
|
||||
|
@ -656,7 +663,7 @@ SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
|||
|
||||
// only id and string are valid
|
||||
if ((TK_NK_STRING != t0.type) && (TK_NK_ID != t0.type)) {
|
||||
t0.type = TK_ILLEGAL;
|
||||
t0.type = TK_NK_ILLEGAL;
|
||||
t0.n = 0;
|
||||
|
||||
return t0;
|
||||
|
|
|
@ -58,6 +58,11 @@ int32_t __catalogGetTableHashVgroup(struct SCatalog* pCatalog, void *pRpc, const
|
|||
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() {
|
||||
mockCatalogService.reset(new MockCatalogService());
|
||||
|
||||
|
@ -65,6 +70,7 @@ void initMetaDataEnv() {
|
|||
stub.set(catalogGetHandle, __catalogGetHandle);
|
||||
stub.set(catalogGetTableMeta, __catalogGetTableMeta);
|
||||
stub.set(catalogGetTableHashVgroup, __catalogGetTableHashVgroup);
|
||||
stub.set(catalogGetTableDistVgInfo, __catalogGetTableDistVgInfo);
|
||||
{
|
||||
AddrAny any("libcatalog.so");
|
||||
std::map<std::string,void*> result;
|
||||
|
@ -89,6 +95,14 @@ void initMetaDataEnv() {
|
|||
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() {
|
||||
|
|
|
@ -42,457 +42,41 @@ protected:
|
|||
|
||||
bool run(int32_t parseCode = TSDB_CODE_SUCCESS, int32_t translateCode = TSDB_CODE_SUCCESS) {
|
||||
int32_t code = doParse(&cxt_, &query_);
|
||||
// cout << "doParse return " << code << endl;
|
||||
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);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != parseCode) {
|
||||
return false;
|
||||
}
|
||||
string parserStr = toString(query_->pRoot);
|
||||
code = doTranslate(&cxt_, query_);
|
||||
// cout << "doTranslate return " << code << endl;
|
||||
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);
|
||||
}
|
||||
if (NULL != query_->pRoot && QUERY_NODE_SELECT_STMT == nodeType(query_->pRoot)) {
|
||||
cout << "input sql : [" << cxt_.pSql << "]" << endl;
|
||||
// string sql;
|
||||
// selectToSql(query_.pRoot, sql);
|
||||
// cout << "output sql : [" << sql << "]" << endl;
|
||||
string str;
|
||||
selectToStr(query_->pRoot, str);
|
||||
cout << "translate str : \n" << str << endl;
|
||||
}
|
||||
cout << "parser output: " << endl;
|
||||
cout << parserStr << endl;
|
||||
cout << "translate output: " << endl;
|
||||
cout << toString(query_->pRoot) << endl;
|
||||
return (TSDB_CODE_SUCCESS == translateCode);
|
||||
}
|
||||
|
||||
private:
|
||||
static const int max_err_len = 1024;
|
||||
|
||||
void exprNodeToStr(const SNode* node, string& str, bool isProject) {
|
||||
switch (nodeType(node)) {
|
||||
case QUERY_NODE_COLUMN:
|
||||
case QUERY_NODE_VALUE:
|
||||
case QUERY_NODE_OPERATOR:
|
||||
case QUERY_NODE_FUNCTION:
|
||||
case QUERY_NODE_LOGIC_CONDITION: {
|
||||
SExprNode* pExpr = (SExprNode*)node;
|
||||
str.append(" [" + dataTypeToStr(pExpr->resType) + "]");
|
||||
if (isProject) {
|
||||
str.append(" AS " + string(pExpr->aliasName));
|
||||
}
|
||||
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);
|
||||
}
|
||||
string toString(const SNode* pRoot, bool format = false) {
|
||||
char* pStr = NULL;
|
||||
int32_t len = 0;
|
||||
int32_t code = nodesNodeToString(pRoot, format, &pStr, &len);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
cout << "sql:[" << cxt_.pSql << "] toString code:" << code << ", strerror:" << tstrerror(code) << endl;
|
||||
throw "nodesNodeToString failed!";
|
||||
}
|
||||
string str(pStr);
|
||||
tfree(pStr);
|
||||
return str;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
|
@ -700,6 +284,27 @@ TEST_F(ParserTest, selectSemanticError) {
|
|||
TEST_F(ParserTest, createDatabase) {
|
||||
bind("create database wxy_db");
|
||||
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) {
|
||||
|
@ -715,4 +320,31 @@ TEST_F(ParserTest, useDatabase) {
|
|||
TEST_F(ParserTest, createTable) {
|
||||
bind("create table t1(ts timestamp, c1 int)");
|
||||
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