提交 08fb912a 编写于 作者: X Xiaoyu Wang

TD-13852 create super table implement

上级 be73f15a
...@@ -55,102 +55,104 @@ ...@@ -55,102 +55,104 @@
#define TK_TTL 37 #define TK_TTL 37
#define TK_WAL 38 #define TK_WAL 38
#define TK_VGROUPS 39 #define TK_VGROUPS 39
#define TK_SINGLESTABLE 40 #define TK_SINGLE_STABLE 40
#define TK_STREAMMODE 41 #define TK_STREAM_MODE 41
#define TK_USE 42 #define TK_USE 42
#define TK_TABLE 43 #define TK_TABLE 43
#define TK_NK_LP 44 #define TK_NK_LP 44
#define TK_NK_RP 45 #define TK_NK_RP 45
#define TK_NK_ID 46 #define TK_STABLE 46
#define TK_NK_DOT 47 #define TK_USING 47
#define TK_NK_COMMA 48 #define TK_TAGS 48
#define TK_COMMENT 49 #define TK_NK_ID 49
#define TK_BOOL 50 #define TK_NK_DOT 50
#define TK_TINYINT 51 #define TK_NK_COMMA 51
#define TK_SMALLINT 52 #define TK_COMMENT 52
#define TK_INT 53 #define TK_BOOL 53
#define TK_INTEGER 54 #define TK_TINYINT 54
#define TK_BIGINT 55 #define TK_SMALLINT 55
#define TK_FLOAT 56 #define TK_INT 56
#define TK_DOUBLE 57 #define TK_INTEGER 57
#define TK_BINARY 58 #define TK_BIGINT 58
#define TK_TIMESTAMP 59 #define TK_FLOAT 59
#define TK_NCHAR 60 #define TK_DOUBLE 60
#define TK_UNSIGNED 61 #define TK_BINARY 61
#define TK_JSON 62 #define TK_TIMESTAMP 62
#define TK_VARCHAR 63 #define TK_NCHAR 63
#define TK_MEDIUMBLOB 64 #define TK_UNSIGNED 64
#define TK_BLOB 65 #define TK_JSON 65
#define TK_VARBINARY 66 #define TK_VARCHAR 66
#define TK_DECIMAL 67 #define TK_MEDIUMBLOB 67
#define TK_SHOW 68 #define TK_BLOB 68
#define TK_DATABASES 69 #define TK_VARBINARY 69
#define TK_TABLES 70 #define TK_DECIMAL 70
#define TK_NK_FLOAT 71 #define TK_SMA 71
#define TK_NK_BOOL 72 #define TK_SHOW 72
#define TK_NK_VARIABLE 73 #define TK_DATABASES 73
#define TK_BETWEEN 74 #define TK_TABLES 74
#define TK_IS 75 #define TK_NK_FLOAT 75
#define TK_NULL 76 #define TK_NK_BOOL 76
#define TK_NK_LT 77 #define TK_NK_VARIABLE 77
#define TK_NK_GT 78 #define TK_BETWEEN 78
#define TK_NK_LE 79 #define TK_IS 79
#define TK_NK_GE 80 #define TK_NULL 80
#define TK_NK_NE 81 #define TK_NK_LT 81
#define TK_NK_EQ 82 #define TK_NK_GT 82
#define TK_LIKE 83 #define TK_NK_LE 83
#define TK_MATCH 84 #define TK_NK_GE 84
#define TK_NMATCH 85 #define TK_NK_NE 85
#define TK_IN 86 #define TK_NK_EQ 86
#define TK_FROM 87 #define TK_LIKE 87
#define TK_AS 88 #define TK_MATCH 88
#define TK_JOIN 89 #define TK_NMATCH 89
#define TK_ON 90 #define TK_IN 90
#define TK_INNER 91 #define TK_FROM 91
#define TK_SELECT 92 #define TK_AS 92
#define TK_DISTINCT 93 #define TK_JOIN 93
#define TK_WHERE 94 #define TK_ON 94
#define TK_PARTITION 95 #define TK_INNER 95
#define TK_BY 96 #define TK_SELECT 96
#define TK_SESSION 97 #define TK_DISTINCT 97
#define TK_STATE_WINDOW 98 #define TK_WHERE 98
#define TK_INTERVAL 99 #define TK_PARTITION 99
#define TK_SLIDING 100 #define TK_BY 100
#define TK_FILL 101 #define TK_SESSION 101
#define TK_VALUE 102 #define TK_STATE_WINDOW 102
#define TK_NONE 103 #define TK_INTERVAL 103
#define TK_PREV 104 #define TK_SLIDING 104
#define TK_LINEAR 105 #define TK_FILL 105
#define TK_NEXT 106 #define TK_VALUE 106
#define TK_GROUP 107 #define TK_NONE 107
#define TK_HAVING 108 #define TK_PREV 108
#define TK_ORDER 109 #define TK_LINEAR 109
#define TK_SLIMIT 110 #define TK_NEXT 110
#define TK_SOFFSET 111 #define TK_GROUP 111
#define TK_LIMIT 112 #define TK_HAVING 112
#define TK_OFFSET 113 #define TK_ORDER 113
#define TK_ASC 114 #define TK_SLIMIT 114
#define TK_DESC 115 #define TK_SOFFSET 115
#define TK_NULLS 116 #define TK_LIMIT 116
#define TK_FIRST 117 #define TK_OFFSET 117
#define TK_LAST 118 #define TK_ASC 118
#define TK_DESC 119
#define TK_NULLS 120
#define TK_FIRST 121
#define TK_LAST 122
#define TK_SPACE 300 #define TK_NK_SPACE 300
#define TK_NK_COMMENT 301 #define TK_NK_COMMENT 301
#define TK_ILLEGAL 302 #define TK_NK_ILLEGAL 302
#define TK_HEX 303 // hex number 0x123 #define TK_NK_HEX 303 // hex number 0x123
#define TK_OCT 304 // oct number #define TK_NK_OCT 304 // oct number
#define TK_BIN 305 // bin format data 0b111 #define TK_NK_BIN 305 // bin format data 0b111
#define TK_FILE 306 #define TK_NK_FILE 306
#define TK_QUESTION 307 // denoting the placeholder of "?",when invoking statement bind query #define TK_NK_QUESTION 307 // denoting the placeholder of "?",when invoking statement bind query
#define TK_NK_COLON 500 #define TK_NK_COLON 500
#define TK_NK_BITNOT 501 #define TK_NK_BITNOT 501
#define TK_INSERT 502 #define TK_INSERT 502
#define TK_INTO 503 #define TK_INTO 503
#define TK_NOW 504 #define TK_NOW 504
#define TK_TAGS 505
#define TK_USING 506
#define TK_VALUES 507 #define TK_VALUES 507
#define TK_IMPORT 507 #define TK_IMPORT 507
#define TK_SEMI 508 #define TK_SEMI 508
......
...@@ -58,6 +58,7 @@ typedef struct STableOptions { ...@@ -58,6 +58,7 @@ typedef struct STableOptions {
int32_t keep; int32_t keep;
int32_t ttl; int32_t ttl;
char comments[TSDB_STB_COMMENT_LEN]; char comments[TSDB_STB_COMMENT_LEN];
SNodeList* pSma;
} STableOptions; } STableOptions;
typedef struct SColumnDefNode { typedef struct SColumnDefNode {
...@@ -73,10 +74,25 @@ typedef struct SCreateTableStmt { ...@@ -73,10 +74,25 @@ typedef struct SCreateTableStmt {
char tableName[TSDB_TABLE_NAME_LEN]; char tableName[TSDB_TABLE_NAME_LEN];
bool ignoreExists; bool ignoreExists;
SNodeList* pCols; SNodeList* pCols;
SNodeList* pTags;
STableOptions options; STableOptions options;
} SCreateTableStmt; } SCreateTableStmt;
// CREATE TABLE [IF NOT EXISTS] [db_name.]tb_name (create_definition [, create_definitionn] ...) [table_options] typedef struct SCreateSubTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
char useDbName[TSDB_DB_NAME_LEN];
char useTableName[TSDB_TABLE_NAME_LEN];
bool ignoreExists;
SNodeList* pSpecificTags;
SNodeList* pValsOfTags;
} SCreateSubTableStmt;
typedef struct SCreateMultiTableStmt {
ENodeType type;
SNodeList* pSubTables;
} SCreateMultiTableStmt;
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -73,6 +73,8 @@ typedef enum ENodeType { ...@@ -73,6 +73,8 @@ typedef enum ENodeType {
QUERY_NODE_VNODE_MODIF_STMT, QUERY_NODE_VNODE_MODIF_STMT,
QUERY_NODE_CREATE_DATABASE_STMT, QUERY_NODE_CREATE_DATABASE_STMT,
QUERY_NODE_CREATE_TABLE_STMT, QUERY_NODE_CREATE_TABLE_STMT,
QUERY_NODE_CREATE_SUBTABLE_STMT,
QUERY_NODE_CREATE_MULTI_TABLE_STMT,
QUERY_NODE_USE_DATABASE_STMT, QUERY_NODE_USE_DATABASE_STMT,
QUERY_NODE_SHOW_DATABASES_STMT, // temp QUERY_NODE_SHOW_DATABASES_STMT, // temp
QUERY_NODE_SHOW_TABLES_STMT, // temp QUERY_NODE_SHOW_TABLES_STMT, // temp
......
...@@ -74,6 +74,7 @@ typedef struct SValueNode { ...@@ -74,6 +74,7 @@ typedef struct SValueNode {
SExprNode node; // QUERY_NODE_VALUE SExprNode node; // QUERY_NODE_VALUE
char* literal; char* literal;
bool isDuration; bool isDuration;
bool translate;
union { union {
bool b; bool b;
int64_t i; int64_t i;
......
...@@ -94,11 +94,11 @@ void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type) { ...@@ -94,11 +94,11 @@ void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type) {
bool sign = true; bool sign = true;
int32_t base = 10; int32_t base = 10;
if (type == TK_HEX) { if (type == TK_NK_HEX) {
base = 16; base = 16;
} else if (type == TK_OCT) { } else if (type == TK_NK_OCT) {
base = 8; base = 8;
} else if (type == TK_BIN) { } else if (type == TK_NK_BIN) {
base = 2; base = 2;
} }
......
/*
* 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 @@ ...@@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "nodesint.h"
#include "plannodes.h" #include "plannodes.h"
#include "querynodes.h" #include "querynodes.h"
#include "taos.h" #include "taos.h"
...@@ -221,7 +222,7 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) { ...@@ -221,7 +222,7 @@ SNodeptr nodesCloneNode(const SNodeptr pNode) {
default: default:
break; break;
} }
printf("nodesCloneNode unknown node = %s\n", nodesNodeName(nodeType(pNode))); nodesWarn("nodesCloneNode unknown node = %s", nodesNodeName(nodeType(pNode)));
return pDst; return pDst;
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "nodesint.h"
#include "plannodes.h" #include "plannodes.h"
#include "querynodes.h" #include "querynodes.h"
#include "query.h" #include "query.h"
...@@ -127,9 +128,8 @@ const char* nodesNodeName(ENodeType type) { ...@@ -127,9 +128,8 @@ const char* nodesNodeName(ENodeType type) {
default: default:
break; break;
} }
static char tmp[20]; nodesWarn("nodesNodeName unknown node = %d", type);
snprintf(tmp, sizeof(tmp), "Unknown %d", type); return "UnknownNode";
return tmp;
} }
static int32_t nodeListToJson(SJson* pJson, const char* pName, const SNodeList* pList) { static int32_t nodeListToJson(SJson* pJson, const char* pName, const SNodeList* pList) {
...@@ -871,8 +871,53 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) { ...@@ -871,8 +871,53 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) {
static const char* jkValueLiteral = "Literal"; static const char* jkValueLiteral = "Literal";
static const char* jkValueDuration = "Duration"; static const char* jkValueDuration = "Duration";
static const char* jkValueTranslate = "Translate";
static const char* jkValueDatum = "Datum"; static const char* jkValueDatum = "Datum";
static int32_t datumToJson(const void* pObj, SJson* pJson) {
const SValueNode* pNode = (const SValueNode*)pObj;
int32_t code = TSDB_CODE_SUCCESS;
switch (pNode->node.resType.type) {
case TSDB_DATA_TYPE_NULL:
break;
case TSDB_DATA_TYPE_BOOL:
code = tjsonAddIntegerToObject(pJson, jkValueDatum, pNode->datum.b);
break;
case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP:
code = tjsonAddIntegerToObject(pJson, jkValueDatum, pNode->datum.i);
break;
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT:
code = tjsonAddIntegerToObject(pJson, jkValueDatum, pNode->datum.u);
break;
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE:
code = tjsonAddDoubleToObject(pJson, jkValueDatum, pNode->datum.d);
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY:
code = tjsonAddStringToObject(pJson, jkValueDatum, pNode->datum.p);
break;
case TSDB_DATA_TYPE_JSON:
case TSDB_DATA_TYPE_DECIMAL:
case TSDB_DATA_TYPE_BLOB:
// todo
default:
break;
}
return code ;
}
static int32_t valueNodeToJson(const void* pObj, SJson* pJson) { static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
const SValueNode* pNode = (const SValueNode*)pObj; const SValueNode* pNode = (const SValueNode*)pObj;
...@@ -884,42 +929,54 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) { ...@@ -884,42 +929,54 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
code = tjsonAddBoolToObject(pJson, jkValueDuration, pNode->isDuration); code = tjsonAddBoolToObject(pJson, jkValueDuration, pNode->isDuration);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
switch (pNode->node.resType.type) { code = tjsonAddBoolToObject(pJson, jkValueTranslate, pNode->translate);
case TSDB_DATA_TYPE_NULL: }
break; if (TSDB_CODE_SUCCESS == code && pNode->translate) {
case TSDB_DATA_TYPE_BOOL: code = datumToJson(pNode, pJson);
code = tjsonAddIntegerToObject(pJson, jkValueDatum, pNode->datum.b); }
break;
case TSDB_DATA_TYPE_TINYINT: return code;
case TSDB_DATA_TYPE_SMALLINT: }
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_BIGINT: static int32_t jsonToDatum(const SJson* pJson, void* pObj) {
case TSDB_DATA_TYPE_TIMESTAMP: SValueNode* pNode = (SValueNode*)pObj;
code = tjsonAddIntegerToObject(pJson, jkValueDatum, pNode->datum.i);
break; int32_t code = TSDB_CODE_SUCCESS;
case TSDB_DATA_TYPE_UTINYINT: switch (pNode->node.resType.type) {
case TSDB_DATA_TYPE_USMALLINT: case TSDB_DATA_TYPE_NULL:
case TSDB_DATA_TYPE_UINT: break;
case TSDB_DATA_TYPE_UBIGINT: case TSDB_DATA_TYPE_BOOL:
code = tjsonAddIntegerToObject(pJson, jkValueDatum, pNode->datum.u); code = tjsonGetBoolValue(pJson, jkValueDatum, &pNode->datum.b);
break; break;
case TSDB_DATA_TYPE_FLOAT: case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_DOUBLE: case TSDB_DATA_TYPE_SMALLINT:
code = tjsonAddDoubleToObject(pJson, jkValueDatum, pNode->datum.d); case TSDB_DATA_TYPE_INT:
break; case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_TIMESTAMP:
case TSDB_DATA_TYPE_NCHAR: code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
case TSDB_DATA_TYPE_VARCHAR: break;
case TSDB_DATA_TYPE_VARBINARY: case TSDB_DATA_TYPE_UTINYINT:
code = tjsonAddStringToObject(pJson, jkValueDatum, pNode->datum.p); case TSDB_DATA_TYPE_USMALLINT:
break; case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_JSON: case TSDB_DATA_TYPE_UBIGINT:
case TSDB_DATA_TYPE_DECIMAL: code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
case TSDB_DATA_TYPE_BLOB: break;
// todo case TSDB_DATA_TYPE_FLOAT:
default: case TSDB_DATA_TYPE_DOUBLE:
break; code = tjsonGetDoubleValue(pJson, jkValueDatum, &pNode->datum.d);
} break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY:
code = tjsonDupStringValue(pJson, jkValueDatum, &pNode->datum.p);
break;
case TSDB_DATA_TYPE_JSON:
case TSDB_DATA_TYPE_DECIMAL:
case TSDB_DATA_TYPE_BLOB:
// todo
default:
break;
} }
return code; return code;
...@@ -936,42 +993,10 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) { ...@@ -936,42 +993,10 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) {
code = tjsonGetBoolValue(pJson, jkValueDuration, &pNode->isDuration); code = tjsonGetBoolValue(pJson, jkValueDuration, &pNode->isDuration);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
switch (pNode->node.resType.type) { code = tjsonGetBoolValue(pJson, jkValueTranslate, &pNode->translate);
case TSDB_DATA_TYPE_NULL: }
break; if (TSDB_CODE_SUCCESS == code && pNode->translate) {
case TSDB_DATA_TYPE_BOOL: code = jsonToDatum(pJson, pNode);
code = tjsonGetBoolValue(pJson, jkValueDatum, &pNode->datum.b);
break;
case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP:
code = tjsonGetBigIntValue(pJson, jkValueDatum, &pNode->datum.i);
break;
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT:
code = tjsonGetUBigIntValue(pJson, jkValueDatum, &pNode->datum.u);
break;
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE:
code = tjsonGetDoubleValue(pJson, jkValueDatum, &pNode->datum.d);
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_VARCHAR:
case TSDB_DATA_TYPE_VARBINARY:
code = tjsonDupStringValue(pJson, jkValueDatum, &pNode->datum.p);
break;
case TSDB_DATA_TYPE_JSON:
case TSDB_DATA_TYPE_DECIMAL:
case TSDB_DATA_TYPE_BLOB:
// todo
default:
break;
}
} }
return code; return code;
...@@ -1365,7 +1390,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { ...@@ -1365,7 +1390,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
default: default:
break; break;
} }
printf("================================ specificNodeToJson unknown node = %s\n", nodesNodeName(nodeType(pObj))); nodesWarn("specificNodeToJson unknown node = %s", nodesNodeName(nodeType(pObj)));
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -1434,7 +1459,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { ...@@ -1434,7 +1459,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
default: default:
break; break;
} }
printf("================================ jsonToSpecificNode unknown node = %s\n", nodesNodeName(nodeType(pObj))); nodesWarn("jsonToSpecificNode unknown node = %s", nodesNodeName(nodeType(pObj)));
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
...@@ -1450,6 +1475,9 @@ static int32_t nodeToJson(const void* pObj, SJson* pJson) { ...@@ -1450,6 +1475,9 @@ static int32_t nodeToJson(const void* pObj, SJson* pJson) {
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, nodesNodeName(pNode->type), specificNodeToJson, pNode); code = tjsonAddObject(pJson, nodesNodeName(pNode->type), specificNodeToJson, pNode);
if (TSDB_CODE_SUCCESS != code) {
nodesError("%s ToJson error", nodesNodeName(pNode->type));
}
} }
return code; return code;
...@@ -1464,7 +1492,7 @@ static int32_t jsonToNode(const SJson* pJson, void* pObj) { ...@@ -1464,7 +1492,7 @@ static int32_t jsonToNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = tjsonToObject(pJson, nodesNodeName(pNode->type), jsonToSpecificNode, pNode); code = tjsonToObject(pJson, nodesNodeName(pNode->type), jsonToSpecificNode, pNode);
if (TSDB_CODE_SUCCESS != code) { if (TSDB_CODE_SUCCESS != code) {
printf("%s toNode error\n", nodesNodeName(pNode->type)); nodesError("%s toNode error", nodesNodeName(pNode->type));
} }
} }
......
...@@ -14,11 +14,11 @@ ...@@ -14,11 +14,11 @@
*/ */
#include "cmdnodes.h" #include "cmdnodes.h"
#include "querynodes.h" #include "nodesint.h"
#include "plannodes.h" #include "plannodes.h"
#include "querynodes.h"
#include "taos.h" #include "taos.h"
#include "taoserror.h" #include "taoserror.h"
#include "taos.h"
#include "thash.h" #include "thash.h"
static SNode* makeNode(ENodeType type, size_t size) { static SNode* makeNode(ENodeType type, size_t size) {
...@@ -84,6 +84,10 @@ SNodeptr nodesMakeNode(ENodeType type) { ...@@ -84,6 +84,10 @@ SNodeptr nodesMakeNode(ENodeType type) {
return makeNode(type, sizeof(SCreateDatabaseStmt)); return makeNode(type, sizeof(SCreateDatabaseStmt));
case QUERY_NODE_CREATE_TABLE_STMT: case QUERY_NODE_CREATE_TABLE_STMT:
return makeNode(type, sizeof(SCreateTableStmt)); return makeNode(type, sizeof(SCreateTableStmt));
case QUERY_NODE_CREATE_SUBTABLE_STMT:
return makeNode(type, sizeof(SCreateSubTableStmt));
case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
return makeNode(type, sizeof(SCreateMultiTableStmt));
case QUERY_NODE_USE_DATABASE_STMT: case QUERY_NODE_USE_DATABASE_STMT:
return makeNode(type, sizeof(SUseDatabaseStmt)); return makeNode(type, sizeof(SUseDatabaseStmt));
case QUERY_NODE_SHOW_DATABASES_STMT: case QUERY_NODE_SHOW_DATABASES_STMT:
...@@ -132,7 +136,7 @@ SNodeptr nodesMakeNode(ENodeType type) { ...@@ -132,7 +136,7 @@ SNodeptr nodesMakeNode(ENodeType type) {
default: default:
break; break;
} }
printf("================================ nodesMakeNode unknown node = %s\n", nodesNodeName(type)); nodesError("nodesMakeNode unknown node = %s", nodesNodeName(type));
return NULL; return NULL;
} }
......
...@@ -110,15 +110,20 @@ typedef enum ETableOptionType { ...@@ -110,15 +110,20 @@ typedef enum ETableOptionType {
TABLE_OPTION_KEEP = 0, TABLE_OPTION_KEEP = 0,
TABLE_OPTION_TTL, TABLE_OPTION_TTL,
TABLE_OPTION_COMMENT, TABLE_OPTION_COMMENT,
TABLE_OPTION_SMA,
TABLE_OPTION_MAX TABLE_OPTION_MAX
} ETableOptionType; } ETableOptionType;
STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt); STableOptions* createDefaultTableOptions(SAstCreateContext* pCxt);
STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal); STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ETableOptionType type, const SToken* pVal);
STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma);
SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment); SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment);
SDataType createDataType(uint8_t type); SDataType createDataType(uint8_t type);
SDataType createVarLenDataType(uint8_t type, const SToken* pLen); SDataType createVarLenDataType(uint8_t type, const SToken* pLen);
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, STableOptions* pOptions); SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions);
SNode* createCreateSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists,
const STokenPair* pFullTableName, const STokenPair* pUseFullTableName, SNodeList* pSpecificTags, SNodeList* pValsOfTags);
SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables);
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName); SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName);
......
此差异已折叠。
...@@ -32,16 +32,6 @@ typedef struct SMsgBuf { ...@@ -32,16 +32,6 @@ typedef struct SMsgBuf {
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg); int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr); int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
int32_t parserValidateIdToken(SToken* pToken);
typedef struct SKvParam {
SKVRowBuilder *builder;
SSchema *schema;
char buf[TSDB_MAX_TAGS_LEN];
} SKvParam;
int32_t KvRowAppend(const void *value, int32_t len, void *param);
STableMeta* tableMetaDup(const STableMeta* pTableMeta); STableMeta* tableMetaDup(const STableMeta* pTableMeta);
SSchema *getTableColumnSchema(const STableMeta *pTableMeta); SSchema *getTableColumnSchema(const STableMeta *pTableMeta);
SSchema *getTableTagSchema(const STableMeta* pTableMeta); SSchema *getTableTagSchema(const STableMeta* pTableMeta);
...@@ -49,6 +39,8 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta); ...@@ -49,6 +39,8 @@ int32_t getNumOfColumns(const STableMeta* pTableMeta);
int32_t getNumOfTags(const STableMeta* pTableMeta); int32_t getNumOfTags(const STableMeta* pTableMeta);
STableComInfo getTableInfo(const STableMeta* pTableMeta); STableComInfo getTableInfo(const STableMeta* pTableMeta);
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -36,7 +36,7 @@ typedef struct SToken { ...@@ -36,7 +36,7 @@ typedef struct SToken {
* @return * @return
*/ */
#define isNumber(tk) \ #define isNumber(tk) \
((tk)->type == TK_NK_INTEGER || (tk)->type == TK_NK_FLOAT || (tk)->type == TK_HEX || (tk)->type == TK_BIN) ((tk)->type == TK_NK_INTEGER || (tk)->type == TK_NK_FLOAT || (tk)->type == TK_NK_HEX || (tk)->type == TK_NK_BIN)
/** /**
* tokenizer for sql string * tokenizer for sql string
...@@ -67,11 +67,11 @@ bool taosIsKeyWordToken(const char *z, int32_t len); ...@@ -67,11 +67,11 @@ bool taosIsKeyWordToken(const char *z, int32_t len);
/** /**
* check if it is a token or not * check if it is a token or not
* @param pToken * @param pToken
* @return token type, if it is not a number, TK_ILLEGAL will return * @return token type, if it is not a number, TK_NK_ILLEGAL will return
*/ */
static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) { static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
const char* z = pToken->z; const char* z = pToken->z;
int32_t type = TK_ILLEGAL; int32_t type = TK_NK_ILLEGAL;
uint32_t i = 0; uint32_t i = 0;
for(; i < pToken->n; ++i) { for(; i < pToken->n; ++i) {
...@@ -88,7 +88,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) { ...@@ -88,7 +88,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
* .123e4 * .123e4
*/ */
if (!isdigit(z[i+1])) { if (!isdigit(z[i+1])) {
return TK_ILLEGAL; return TK_NK_ILLEGAL;
} }
for (i += 2; isdigit(z[i]); i++) { for (i += 2; isdigit(z[i]); i++) {
...@@ -109,13 +109,13 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) { ...@@ -109,13 +109,13 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
case '0': { case '0': {
char next = z[i + 1]; char next = z[i + 1];
if (next == 'b') { // bin number if (next == 'b') { // bin number
type = TK_BIN; type = TK_NK_BIN;
for (i += 2; (z[i] == '0' || z[i] == '1'); ++i) { for (i += 2; (z[i] == '0' || z[i] == '1'); ++i) {
} }
goto _end; goto _end;
} else if (next == 'x') { //hex number } else if (next == 'x') { //hex number
type = TK_HEX; type = TK_NK_HEX;
for (i += 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) { for (i += 2; isdigit(z[i]) || (z[i] >= 'a' && z[i] <= 'f') || (z[i] >= 'A' && z[i] <= 'F'); ++i) {
} }
...@@ -148,7 +148,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) { ...@@ -148,7 +148,7 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
} }
if (seg > 1) { if (seg > 1) {
return TK_ILLEGAL; return TK_NK_ILLEGAL;
} }
if ((z[i] == 'e' || z[i] == 'E') && if ((z[i] == 'e' || z[i] == 'E') &&
...@@ -164,12 +164,12 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) { ...@@ -164,12 +164,12 @@ static FORCE_INLINE int32_t tGetNumericStringType(const SToken* pToken) {
goto _end; goto _end;
} }
default: default:
return TK_ILLEGAL; return TK_NK_ILLEGAL;
} }
} }
_end: _end:
return (i < pToken->n)? TK_ILLEGAL:type; return (i < pToken->n)? TK_NK_ILLEGAL:type;
} }
void taosCleanupKeywordsTable(); void taosCleanupKeywordsTable();
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#include "astCreateFuncs.h" #include "astCreateFuncs.h"
#include "parserUtil.h"
#define CHECK_OUT_OF_MEM(p) \ #define CHECK_OUT_OF_MEM(p) \
do { \ do { \
...@@ -149,16 +150,16 @@ static SDatabaseOptions* setDbKeep(SAstCreateContext* pCxt, SDatabaseOptions* pO ...@@ -149,16 +150,16 @@ static SDatabaseOptions* setDbKeep(SAstCreateContext* pCxt, SDatabaseOptions* pO
} }
static SDatabaseOptions* setDbPrecision(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, const SToken* pVal) { static SDatabaseOptions* setDbPrecision(SAstCreateContext* pCxt, SDatabaseOptions* pOptions, const SToken* pVal) {
if (0 == strncmp(pVal->z, TSDB_TIME_PRECISION_MILLI_STR, pVal->n) && strlen(TSDB_TIME_PRECISION_MILLI_STR) == pVal->n) { char val[10] = {0};
trimString(pVal->z, pVal->n, val, sizeof(val));
if (0 == strcmp(val, TSDB_TIME_PRECISION_MILLI_STR)) {
pOptions->precision = TSDB_TIME_PRECISION_MILLI; pOptions->precision = TSDB_TIME_PRECISION_MILLI;
} else if (0 == strncmp(pVal->z, TSDB_TIME_PRECISION_MICRO_STR, pVal->n) && strlen(TSDB_TIME_PRECISION_MICRO_STR) == pVal->n) { } else if (0 == strcmp(val, TSDB_TIME_PRECISION_MICRO_STR)) {
pOptions->precision = TSDB_TIME_PRECISION_MICRO; pOptions->precision = TSDB_TIME_PRECISION_MICRO;
} else if (0 == strncmp(pVal->z, TSDB_TIME_PRECISION_NANO_STR, pVal->n) && strlen(TSDB_TIME_PRECISION_NANO_STR) == pVal->n) { } else if (0 == strcmp(val, TSDB_TIME_PRECISION_NANO_STR)) {
pOptions->precision = TSDB_TIME_PRECISION_NANO; pOptions->precision = TSDB_TIME_PRECISION_NANO;
} else { } else {
char tmp[10]; snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option precision: %s", val);
strncpy(tmp, pVal->z, pVal->n);
snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "invalid db option precision: %s", tmp);
pCxt->valid = false; pCxt->valid = false;
} }
return pOptions; return pOptions;
...@@ -296,7 +297,7 @@ static STableOptions* setTableComment(SAstCreateContext* pCxt, STableOptions* pO ...@@ -296,7 +297,7 @@ static STableOptions* setTableComment(SAstCreateContext* pCxt, STableOptions* pO
pCxt->valid = false; pCxt->valid = false;
return pOptions; return pOptions;
} }
strncpy(pOptions->comments, pVal->z, pVal->n); trimString(pVal->z, pVal->n, pOptions->comments, sizeof(pOptions->comments));
return pOptions; return pOptions;
} }
...@@ -413,6 +414,8 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* ...@@ -413,6 +414,8 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
if (TSDB_DATA_TYPE_TIMESTAMP == dataType) { if (TSDB_DATA_TYPE_TIMESTAMP == dataType) {
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI; val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
} }
val->isDuration = false;
val->translate = false;
return (SNode*)val; return (SNode*)val;
} }
...@@ -422,6 +425,7 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral) ...@@ -422,6 +425,7 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral)
val->literal = strndup(pLiteral->z, pLiteral->n); val->literal = strndup(pLiteral->z, pLiteral->n);
CHECK_OUT_OF_MEM(val->literal); CHECK_OUT_OF_MEM(val->literal);
val->isDuration = true; val->isDuration = true;
val->translate = false;
val->node.resType.type = TSDB_DATA_TYPE_BIGINT; val->node.resType.type = TSDB_DATA_TYPE_BIGINT;
val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; val->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
val->node.resType.precision = TSDB_TIME_PRECISION_MILLI; val->node.resType.precision = TSDB_TIME_PRECISION_MILLI;
...@@ -708,13 +712,18 @@ STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions, ...@@ -708,13 +712,18 @@ STableOptions* setTableOption(SAstCreateContext* pCxt, STableOptions* pOptions,
return setTableOptionFuncs[type](pCxt, pOptions, pVal); return setTableOptionFuncs[type](pCxt, pOptions, pVal);
} }
STableOptions* setTableSmaOption(SAstCreateContext* pCxt, STableOptions* pOptions, SNodeList* pSma) {
pOptions->pSma = pSma;
return pOptions;
}
SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment) { SNode* createColumnDefNode(SAstCreateContext* pCxt, const SToken* pColName, SDataType dataType, const SToken* pComment) {
SColumnDefNode* pCol = (SColumnDefNode*)nodesMakeNode(QUERY_NODE_COLUMN_DEF); SColumnDefNode* pCol = (SColumnDefNode*)nodesMakeNode(QUERY_NODE_COLUMN_DEF);
CHECK_OUT_OF_MEM(pCol); CHECK_OUT_OF_MEM(pCol);
strncpy(pCol->colName, pColName->z, pColName->n); strncpy(pCol->colName, pColName->z, pColName->n);
pCol->dataType = dataType; pCol->dataType = dataType;
if (NULL != pComment) { if (NULL != pComment) {
strncpy(pCol->comments, pComment->z, pComment->n); trimString(pComment->z, pComment->n, pCol->comments, sizeof(pCol->comments));
} }
return (SNode*)pCol; return (SNode*)pCol;
} }
...@@ -730,19 +739,51 @@ SDataType createVarLenDataType(uint8_t type, const SToken* pLen) { ...@@ -730,19 +739,51 @@ SDataType createVarLenDataType(uint8_t type, const SToken* pLen) {
} }
SNode* createCreateTableStmt(SAstCreateContext* pCxt, SNode* createCreateTableStmt(SAstCreateContext* pCxt,
bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, STableOptions* pOptions) { bool ignoreExists, const STokenPair* pFullTableName, SNodeList* pCols, SNodeList* pTags, STableOptions* pOptions) {
SCreateTableStmt* pStmt = (SCreateTableStmt*)nodesMakeNode(QUERY_NODE_CREATE_TABLE_STMT); SCreateTableStmt* pStmt = (SCreateTableStmt*)nodesMakeNode(QUERY_NODE_CREATE_TABLE_STMT);
CHECK_OUT_OF_MEM(pStmt); CHECK_OUT_OF_MEM(pStmt);
if (TK_NIL != pFullTableName->first.type) { if (TK_NIL != pFullTableName->first.type) {
strncpy(pStmt->dbName, pFullTableName->first.z, pFullTableName->first.n); strncpy(pStmt->dbName, pFullTableName->first.z, pFullTableName->first.n);
} else {
strcpy(pStmt->dbName, pCxt->pQueryCxt->db);
} }
strncpy(pStmt->tableName, pFullTableName->second.z, pFullTableName->second.n); strncpy(pStmt->tableName, pFullTableName->second.z, pFullTableName->second.n);
pStmt->ignoreExists = ignoreExists; pStmt->ignoreExists = ignoreExists;
pStmt->pCols = pCols; pStmt->pCols = pCols;
pStmt->pTags = pTags;
pStmt->options = *pOptions; pStmt->options = *pOptions;
return (SNode*)pStmt; return (SNode*)pStmt;
} }
SNode* createCreateSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists,
const STokenPair* pFullTableName, const STokenPair* pUseFullTableName, SNodeList* pSpecificTags, SNodeList* pValsOfTags) {
SCreateSubTableStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_SUBTABLE_STMT);
CHECK_OUT_OF_MEM(pStmt);
if (TK_NIL != pFullTableName->first.type) {
strncpy(pStmt->dbName, pFullTableName->first.z, pFullTableName->first.n);
} else {
strcpy(pStmt->dbName, pCxt->pQueryCxt->db);
}
strncpy(pStmt->tableName, pFullTableName->second.z, pFullTableName->second.n);
if (TK_NIL != pUseFullTableName->first.type) {
strncpy(pStmt->useDbName, pUseFullTableName->first.z, pUseFullTableName->first.n);
} else {
strcpy(pStmt->useDbName, pCxt->pQueryCxt->db);
}
strncpy(pStmt->useTableName, pUseFullTableName->second.z, pUseFullTableName->second.n);
pStmt->ignoreExists = ignoreExists;
pStmt->pSpecificTags = pSpecificTags;
pStmt->pValsOfTags = pValsOfTags;
return (SNode*)pStmt;
}
SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables) {
SCreateMultiTableStmt* pStmt = nodesMakeNode(QUERY_NODE_CREATE_MULTI_TABLE_STMT);
CHECK_OUT_OF_MEM(pStmt);
pStmt->pSubTables = pSubTables;
return (SNode*)pStmt;
}
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName) { SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName) {
SUseDatabaseStmt* pStmt = (SUseDatabaseStmt*)nodesMakeNode(QUERY_NODE_USE_DATABASE_STMT); SUseDatabaseStmt* pStmt = (SUseDatabaseStmt*)nodesMakeNode(QUERY_NODE_USE_DATABASE_STMT);
CHECK_OUT_OF_MEM(pStmt); CHECK_OUT_OF_MEM(pStmt);
......
...@@ -26,22 +26,6 @@ extern void NewParse(void*, int, SToken, void*); ...@@ -26,22 +26,6 @@ extern void NewParse(void*, int, SToken, void*);
extern void NewParseFree(void*, FFree); extern void NewParseFree(void*, FFree);
extern void NewParseTrace(FILE*, char*); extern void NewParseTrace(FILE*, char*);
static void setQuery(SAstCreateContext* pCxt, SQuery* pQuery) {
pQuery->pRoot = pCxt->pRootNode;
ENodeType type = nodeType(pCxt->pRootNode);
if (QUERY_NODE_SELECT_STMT == type) {
pQuery->haveResultSet = true;
pQuery->directRpc = false;
} else if (QUERY_NODE_CREATE_TABLE_STMT == type) {
pQuery->haveResultSet = false;
pQuery->directRpc = false;
} else {
pQuery->haveResultSet = false;
pQuery->directRpc = true;
}
pQuery->msgType = (QUERY_NODE_CREATE_TABLE_STMT == type ? TDMT_VND_CREATE_TABLE : TDMT_VND_QUERY);
}
int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) { int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
SAstCreateContext cxt; SAstCreateContext cxt;
initAstCreateContext(pParseCxt, &cxt); initAstCreateContext(pParseCxt, &cxt);
...@@ -58,23 +42,23 @@ int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) { ...@@ -58,23 +42,23 @@ int32_t doParse(SParseContext* pParseCxt, SQuery** pQuery) {
i += t0.n; i += t0.n;
switch (t0.type) { switch (t0.type) {
case TK_SPACE: case TK_NK_SPACE:
case TK_COMMENT: { case TK_NK_COMMENT: {
break; break;
} }
case TK_SEMI: { case TK_SEMI: {
NewParse(pParser, 0, t0, &cxt); NewParse(pParser, 0, t0, &cxt);
goto abort_parse; goto abort_parse;
} }
case TK_QUESTION: case TK_NK_QUESTION:
case TK_ILLEGAL: { case TK_NK_ILLEGAL: {
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z); snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unrecognized token: \"%s\"", t0.z);
cxt.valid = false; cxt.valid = false;
goto abort_parse; goto abort_parse;
} }
case TK_HEX: case TK_NK_HEX:
case TK_OCT: case TK_NK_OCT:
case TK_BIN: { case TK_NK_BIN: {
snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z); snprintf(cxt.pQueryCxt->pMsg, cxt.pQueryCxt->msgLen, "unsupported token: \"%s\"", t0.z);
cxt.valid = false; cxt.valid = false;
goto abort_parse; goto abort_parse;
...@@ -95,7 +79,7 @@ abort_parse: ...@@ -95,7 +79,7 @@ abort_parse:
if (NULL == *pQuery) { if (NULL == *pQuery) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
setQuery(&cxt, *pQuery); (*pQuery)->pRoot = cxt.pRootNode;
} }
return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED; return cxt.valid ? TSDB_CODE_SUCCESS : TSDB_CODE_FAILED;
} }
...@@ -280,29 +280,13 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) { ...@@ -280,29 +280,13 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
return found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol); return found ? DEAL_RES_CONTINUE : translateColumnWithoutPrefix(pCxt, pCol);
} }
static int32_t trimStringCopy(const char* src, int32_t len, bool format, char* dst) { static int32_t trimStringWithVarFormat(const char* src, int32_t len, bool format, char* dst) {
char* dstVal = dst; char* dstVal = dst;
if (format) { if (format) {
varDataSetLen(dst, len); varDataSetLen(dst, len);
dstVal = varDataVal(dst); dstVal = varDataVal(dst);
} }
// delete escape character: \\, \', \" return trimString(src, len, dstVal, len);
char delim = src[0];
int32_t cnt = 0;
int32_t j = 0;
for (uint32_t k = 1; k < len - 1; ++k) {
if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
dstVal[j] = src[k + 1];
cnt++;
j++;
k++;
continue;
}
dstVal[j] = src[k];
j++;
}
dstVal[j] = '\0';
return j;
} }
static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
...@@ -351,7 +335,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { ...@@ -351,7 +335,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
return DEAL_RES_ERROR; return DEAL_RES_ERROR;
} }
trimStringCopy(pVal->literal, n, true, pVal->datum.p); trimStringWithVarFormat(pVal->literal, n, true, pVal->datum.p);
break; break;
} }
case TSDB_DATA_TYPE_TIMESTAMP: { case TSDB_DATA_TYPE_TIMESTAMP: {
...@@ -361,7 +345,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { ...@@ -361,7 +345,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
return DEAL_RES_ERROR; return DEAL_RES_ERROR;
} }
int32_t len = trimStringCopy(pVal->literal, n, false, tmp); int32_t len = trimStringWithVarFormat(pVal->literal, n, false, tmp);
if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) { if (taosParseTime(tmp, &pVal->datum.i, len, pVal->node.resType.precision, tsDaylight) != TSDB_CODE_SUCCESS) {
tfree(tmp); tfree(tmp);
generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); generateSyntaxErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal);
...@@ -378,6 +362,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) { ...@@ -378,6 +362,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
break; break;
} }
} }
pVal->translate = true;
return DEAL_RES_CONTINUE; return DEAL_RES_CONTINUE;
} }
...@@ -856,6 +841,47 @@ static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseS ...@@ -856,6 +841,47 @@ static int32_t translateCreateDatabase(STranslateContext* pCxt, SCreateDatabaseS
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t columnNodeToField(SNodeList* pList, SArray** pArray) {
*pArray = taosArrayInit(LIST_LENGTH(pList), sizeof(SField));
SNode* pNode;
FOREACH(pNode, pList) {
SColumnDefNode* pCol = (SColumnDefNode*)pNode;
SField field = { .type = pCol->dataType.type, .bytes = pCol->dataType.bytes };
strcpy(field.name, pCol->colName);
taosArrayPush(*pArray, &field);
}
return TSDB_CODE_SUCCESS;
}
static int32_t translateCreateSTable(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
SMCreateStbReq createReq = {0};
createReq.igExists = pStmt->ignoreExists;
columnNodeToField(pStmt->pCols, &createReq.pColumns);
columnNodeToField(pStmt->pTags, &createReq.pTags);
createReq.numOfColumns = LIST_LENGTH(pStmt->pCols);
createReq.numOfTags = LIST_LENGTH(pStmt->pTags);
SName tableName = { .type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId };
strcpy(tableName.dbname, pStmt->dbName);
strcpy(tableName.tname, pStmt->tableName);
tNameExtractFullName(&tableName, createReq.name);
pCxt->pCmdMsg = malloc(sizeof(SCmdMsgInfo));
if (NULL== pCxt->pCmdMsg) {
return TSDB_CODE_OUT_OF_MEMORY;
}
pCxt->pCmdMsg->epSet = pCxt->pParseCxt->mgmtEpSet;
pCxt->pCmdMsg->msgType = TDMT_MND_CREATE_STB;
pCxt->pCmdMsg->msgLen = tSerializeSMCreateStbReq(NULL, 0, &createReq);
pCxt->pCmdMsg->pMsg = malloc(pCxt->pCmdMsg->msgLen);
if (NULL== pCxt->pCmdMsg->pMsg) {
return TSDB_CODE_OUT_OF_MEMORY;
}
tSerializeSMCreateStbReq(pCxt->pCmdMsg->pMsg, pCxt->pCmdMsg->msgLen, &createReq);
return TSDB_CODE_SUCCESS;
}
static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* pStmt) { static int32_t translateUseDatabase(STranslateContext* pCxt, SUseDatabaseStmt* pStmt) {
SName name = {0}; SName name = {0};
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName)); tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
...@@ -935,6 +961,9 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) { ...@@ -935,6 +961,9 @@ static int32_t translateQuery(STranslateContext* pCxt, SNode* pNode) {
case QUERY_NODE_CREATE_DATABASE_STMT: case QUERY_NODE_CREATE_DATABASE_STMT:
code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode); code = translateCreateDatabase(pCxt, (SCreateDatabaseStmt*)pNode);
break; break;
case QUERY_NODE_CREATE_TABLE_STMT:
code = translateCreateSTable(pCxt, (SCreateTableStmt*)pNode);
break;
case QUERY_NODE_USE_DATABASE_STMT: case QUERY_NODE_USE_DATABASE_STMT:
code = translateUseDatabase(pCxt, (SUseDatabaseStmt*)pNode); code = translateUseDatabase(pCxt, (SUseDatabaseStmt*)pNode);
break; break;
...@@ -1020,7 +1049,7 @@ static int32_t doBuildSingleTableBatchReq(SName* pTableName, SNodeList* pColumns ...@@ -1020,7 +1049,7 @@ static int32_t doBuildSingleTableBatchReq(SName* pTableName, SNodeList* pColumns
pBatch->info = *pVgroupInfo; pBatch->info = *pVgroupInfo;
pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq)); pBatch->req.pArray = taosArrayInit(1, sizeof(struct SVCreateTbReq));
if (pBatch->req.pArray == NULL) { if (pBatch->req.pArray == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
taosArrayPush(pBatch->req.pArray, &req); taosArrayPush(pBatch->req.pArray, &req);
...@@ -1031,7 +1060,7 @@ static int32_t serializeVgroupTablesBatchImpl(SVgroupTablesBatch* pTbBatch, SArr ...@@ -1031,7 +1060,7 @@ static int32_t serializeVgroupTablesBatchImpl(SVgroupTablesBatch* pTbBatch, SArr
int tlen = sizeof(SMsgHead) + tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req)); int tlen = sizeof(SMsgHead) + tSerializeSVCreateTbBatchReq(NULL, &(pTbBatch->req));
void* buf = malloc(tlen); void* buf = malloc(tlen);
if (buf == NULL) { if (buf == NULL) {
// TODO: handle error return TSDB_CODE_OUT_OF_MEMORY;
} }
((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId); ((SMsgHead*)buf)->vgId = htonl(pTbBatch->info.vgId);
...@@ -1068,15 +1097,11 @@ static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) { ...@@ -1068,15 +1097,11 @@ static void destroyCreateTbReqBatch(SVgroupTablesBatch* pTbBatch) {
} }
static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
if (QUERY_NODE_CREATE_TABLE_STMT == nodeType(pQuery->pRoot)) { if (QUERY_NODE_CREATE_TABLE_STMT == nodeType(pQuery->pRoot) && NULL == ((SCreateTableStmt*)pQuery->pRoot)->pTags) {
SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot; SCreateTableStmt* pStmt = (SCreateTableStmt*)pQuery->pRoot;
SName tableName = { .type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId }; SName tableName = { .type = TSDB_TABLE_NAME_T, .acctId = pCxt->pParseCxt->acctId };
if ('\0' == pStmt->dbName[0]) { strcpy(tableName.dbname, pStmt->dbName);
strcpy(tableName.dbname, pCxt->pParseCxt->db);
} else {
strcpy(tableName.dbname, pStmt->dbName);
}
strcpy(tableName.tname, pStmt->tableName); strcpy(tableName.tname, pStmt->tableName);
SVgroupInfo info = {0}; SVgroupInfo info = {0};
catalogGetTableHashVgroup(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &pCxt->pParseCxt->mgmtEpSet, &tableName, &info); catalogGetTableHashVgroup(pCxt->pParseCxt->pCatalog, pCxt->pParseCxt->pTransporter, &pCxt->pParseCxt->mgmtEpSet, &tableName, &info);
...@@ -1089,13 +1114,16 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { ...@@ -1089,13 +1114,16 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
SArray* pBufArray = taosArrayInit(1, POINTER_BYTES); SArray* pBufArray = taosArrayInit(1, POINTER_BYTES);
if (pBufArray == NULL) { if (pBufArray == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
serializeVgroupTablesBatchImpl(&tbatch, pBufArray); serializeVgroupTablesBatchImpl(&tbatch, pBufArray);
destroyCreateTbReqBatch(&tbatch); destroyCreateTbReqBatch(&tbatch);
SVnodeModifOpStmt* pNewStmt = nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT); SVnodeModifOpStmt* pNewStmt = nodesMakeNode(QUERY_NODE_VNODE_MODIF_STMT);
if (pNewStmt == NULL) {
return TSDB_CODE_OUT_OF_MEMORY;
}
pNewStmt->sqlNodeType = nodeType(pQuery->pRoot); pNewStmt->sqlNodeType = nodeType(pQuery->pRoot);
pNewStmt->pDataBlocks = pBufArray; pNewStmt->pDataBlocks = pBufArray;
pQuery->sqlNodeType = nodeType(pQuery->pRoot); pQuery->sqlNodeType = nodeType(pQuery->pRoot);
...@@ -1105,6 +1133,31 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { ...@@ -1105,6 +1133,31 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
int32_t code = TSDB_CODE_SUCCESS;
switch (nodeType(pQuery->pRoot)) {
case QUERY_NODE_SELECT_STMT:
pQuery->haveResultSet = true;
pQuery->directRpc = false;
pQuery->msgType = TDMT_VND_QUERY;
code = setReslutSchema(pCxt, pQuery);
break;
case QUERY_NODE_VNODE_MODIF_STMT:
pQuery->haveResultSet = false;
pQuery->directRpc = false;
pQuery->msgType = TDMT_VND_CREATE_TABLE;
break;
default:
pQuery->haveResultSet = false;
pQuery->directRpc = true;
pQuery->pCmdMsg = pCxt->pCmdMsg;
pCxt->pCmdMsg = NULL;
pQuery->msgType = pQuery->pCmdMsg->msgType;
break;
}
return code;
}
int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) { int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
STranslateContext cxt = { STranslateContext cxt = {
.pParseCxt = pParseCxt, .pParseCxt = pParseCxt,
...@@ -1122,13 +1175,7 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) { ...@@ -1122,13 +1175,7 @@ int32_t doTranslate(SParseContext* pParseCxt, SQuery* pQuery) {
code = translateQuery(&cxt, pQuery->pRoot); code = translateQuery(&cxt, pQuery->pRoot);
} }
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
if (pQuery->directRpc) { code = setQuery(&cxt, pQuery);
pQuery->pCmdMsg = cxt.pCmdMsg;
cxt.pCmdMsg = NULL;
}
if (pQuery->haveResultSet) {
code = setReslutSchema(&cxt, pQuery);
}
} }
destroyTranslateContext(&cxt); destroyTranslateContext(&cxt);
return code; return code;
......
...@@ -80,6 +80,68 @@ static int32_t skipInsertInto(SInsertParseContext* pCxt) { ...@@ -80,6 +80,68 @@ static int32_t skipInsertInto(SInsertParseContext* pCxt) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t parserValidateIdToken(SToken* pToken) {
if (pToken == NULL || pToken->z == NULL || pToken->type != TK_NK_ID) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// it is a token quoted with escape char '`'
if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) {
return TSDB_CODE_SUCCESS;
}
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
if (sep == NULL) { // It is a single part token, not a complex type
if (isNumber(pToken)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
strntolower(pToken->z, pToken->z, pToken->n);
} else { // two part
int32_t oldLen = pToken->n;
char* pStr = pToken->z;
if (pToken->type == TK_NK_SPACE) {
pToken->n = (uint32_t)strtrim(pToken->z);
}
pToken->n = tGetToken(pToken->z, &pToken->type);
if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (pToken->type != TK_NK_ID) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
int32_t firstPartLen = pToken->n;
pToken->z = sep + 1;
pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1);
int32_t len = tGetToken(pToken->z, &pToken->type);
if (len != pToken->n || pToken->type != TK_NK_ID) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// re-build the whole name string
if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
// first part do not have quote do nothing
} else {
pStr[firstPartLen] = TS_PATH_DELIMITER[0];
memmove(&pStr[firstPartLen + 1], pToken->z, pToken->n);
uint32_t offset = (uint32_t)(pToken->z - (pStr + firstPartLen + 1));
memset(pToken->z + pToken->n - offset, ' ', offset);
}
pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0]));
pToken->z = pStr;
strntolower(pToken->z, pToken->z, pToken->n);
}
return TSDB_CODE_SUCCESS;
}
static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullDbName, char* tableName) { static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullDbName, char* tableName) {
if (parserValidateIdToken(pStname) != TSDB_CODE_SUCCESS) { if (parserValidateIdToken(pStname) != TSDB_CODE_SUCCESS) {
return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pStname->z); return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pStname->z);
...@@ -320,7 +382,7 @@ static int parseTime(char **end, SToken *pToken, int16_t timePrec, int64_t *time ...@@ -320,7 +382,7 @@ static int parseTime(char **end, SToken *pToken, int16_t timePrec, int64_t *time
static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, uint32_t type, char* tmpTokenBuf, SMsgBuf* pMsgBuf) { static FORCE_INLINE int32_t checkAndTrimValue(SToken* pToken, uint32_t type, char* tmpTokenBuf, SMsgBuf* pMsgBuf) {
if ((pToken->type != TK_NOW && pToken->type != TK_NK_INTEGER && pToken->type != TK_NK_STRING && pToken->type != TK_NK_FLOAT && pToken->type != TK_NK_BOOL && if ((pToken->type != TK_NOW && pToken->type != TK_NK_INTEGER && pToken->type != TK_NK_STRING && pToken->type != TK_NK_FLOAT && pToken->type != TK_NK_BOOL &&
pToken->type != TK_NULL && pToken->type != TK_HEX && pToken->type != TK_OCT && pToken->type != TK_BIN) || pToken->type != TK_NULL && pToken->type != TK_NK_HEX && pToken->type != TK_NK_OCT && pToken->type != TK_NK_BIN) ||
(pToken->n == 0) || (pToken->type == TK_NK_RP)) { (pToken->n == 0) || (pToken->type == TK_NK_RP)) {
return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z); return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z);
} }
...@@ -370,7 +432,7 @@ static FORCE_INLINE int32_t toDouble(SToken *pToken, double *value, char **endPt ...@@ -370,7 +432,7 @@ static FORCE_INLINE int32_t toDouble(SToken *pToken, double *value, char **endPt
// not a valid integer number, return error // not a valid integer number, return error
if ((*endPtr - pToken->z) != pToken->n) { if ((*endPtr - pToken->z) != pToken->n) {
return TK_ILLEGAL; return TK_NK_ILLEGAL;
} }
return pToken->type; return pToken->type;
...@@ -496,7 +558,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int ...@@ -496,7 +558,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
double dv; double dv;
if (TK_ILLEGAL == toDouble(pToken, &dv, &endptr)) { if (TK_NK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z); return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
} }
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) { if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
...@@ -508,7 +570,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int ...@@ -508,7 +570,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
double dv; double dv;
if (TK_ILLEGAL == toDouble(pToken, &dv, &endptr)) { if (TK_NK_ILLEGAL == toDouble(pToken, &dv, &endptr)) {
return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z); return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
} }
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) { if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
...@@ -646,6 +708,37 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo* ...@@ -646,6 +708,37 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo*
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
typedef struct SKvParam {
SKVRowBuilder *builder;
SSchema *schema;
char buf[TSDB_MAX_TAGS_LEN];
} SKvParam;
static int32_t KvRowAppend(const void *value, int32_t len, void *param) {
SKvParam* pa = (SKvParam*) param;
int32_t type = pa->schema->type;
int32_t colId = pa->schema->colId;
if (TSDB_DATA_TYPE_BINARY == type) {
STR_WITH_SIZE_TO_VARSTR(pa->buf, value, len);
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
} else if (TSDB_DATA_TYPE_NCHAR == type) {
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
int32_t output = 0;
if (!taosMbsToUcs4(value, len, varDataVal(pa->buf), pa->schema->bytes - VARSTR_HEADER_SIZE, &output)) {
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
}
varDataSetLen(pa->buf, output);
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
} else {
tdAddColToKVRow(pa->builder, colId, type, value);
}
return TSDB_CODE_SUCCESS;
}
// pSql -> tag1_value, ...) // pSql -> tag1_value, ...)
static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pTagsSchema, uint8_t precision) { static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pTagsSchema, uint8_t precision) {
if (tdInitKVRowBuilder(&pCxt->tagsBuilder) < 0) { if (tdInitKVRowBuilder(&pCxt->tagsBuilder) < 0) {
...@@ -893,7 +986,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { ...@@ -893,7 +986,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
} }
// FILE csv_file_path // FILE csv_file_path
if (TK_FILE == sToken.type) { if (TK_NK_FILE == sToken.type) {
// pSql -> csv_file_path // pSql -> csv_file_path
NEXT_TOKEN(pCxt->pSql, sToken); NEXT_TOKEN(pCxt->pSql, sToken);
if (0 == sToken.n || (TK_NK_STRING != sToken.type && TK_NK_ID != sToken.type)) { if (0 == sToken.n || (TK_NK_STRING != sToken.type && TK_NK_ID != sToken.type)) {
......
此差异已折叠。
...@@ -45,93 +45,6 @@ int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* ...@@ -45,93 +45,6 @@ int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char*
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
} }
int32_t parserValidateIdToken(SToken* pToken) {
if (pToken == NULL || pToken->z == NULL || pToken->type != TK_NK_ID) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// it is a token quoted with escape char '`'
if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) {
return TSDB_CODE_SUCCESS;
}
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
if (sep == NULL) { // It is a single part token, not a complex type
if (isNumber(pToken)) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
strntolower(pToken->z, pToken->z, pToken->n);
} else { // two part
int32_t oldLen = pToken->n;
char* pStr = pToken->z;
if (pToken->type == TK_SPACE) {
pToken->n = (uint32_t)strtrim(pToken->z);
}
pToken->n = tGetToken(pToken->z, &pToken->type);
if (pToken->z[pToken->n] != TS_PATH_DELIMITER[0]) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
if (pToken->type != TK_NK_ID) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
int32_t firstPartLen = pToken->n;
pToken->z = sep + 1;
pToken->n = (uint32_t)(oldLen - (sep - pStr) - 1);
int32_t len = tGetToken(pToken->z, &pToken->type);
if (len != pToken->n || pToken->type != TK_NK_ID) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
// re-build the whole name string
if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
// first part do not have quote do nothing
} else {
pStr[firstPartLen] = TS_PATH_DELIMITER[0];
memmove(&pStr[firstPartLen + 1], pToken->z, pToken->n);
uint32_t offset = (uint32_t)(pToken->z - (pStr + firstPartLen + 1));
memset(pToken->z + pToken->n - offset, ' ', offset);
}
pToken->n += (firstPartLen + sizeof(TS_PATH_DELIMITER[0]));
pToken->z = pStr;
strntolower(pToken->z, pToken->z, pToken->n);
}
return TSDB_CODE_SUCCESS;
}
int32_t KvRowAppend(const void *value, int32_t len, void *param) {
SKvParam* pa = (SKvParam*) param;
int32_t type = pa->schema->type;
int32_t colId = pa->schema->colId;
if (TSDB_DATA_TYPE_BINARY == type) {
STR_WITH_SIZE_TO_VARSTR(pa->buf, value, len);
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
} else if (TSDB_DATA_TYPE_NCHAR == type) {
// if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
int32_t output = 0;
if (!taosMbsToUcs4(value, len, varDataVal(pa->buf), pa->schema->bytes - VARSTR_HEADER_SIZE, &output)) {
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
}
varDataSetLen(pa->buf, output);
tdAddColToKVRow(pa->builder, colId, type, pa->buf);
} else {
tdAddColToKVRow(pa->builder, colId, type, value);
}
return TSDB_CODE_SUCCESS;
}
static uint32_t getTableMetaSize(const STableMeta* pTableMeta) { static uint32_t getTableMetaSize(const STableMeta* pTableMeta) {
assert(pTableMeta != NULL); assert(pTableMeta != NULL);
...@@ -184,3 +97,26 @@ STableComInfo getTableInfo(const STableMeta* pTableMeta) { ...@@ -184,3 +97,26 @@ STableComInfo getTableInfo(const STableMeta* pTableMeta) {
assert(pTableMeta != NULL); assert(pTableMeta != NULL);
return pTableMeta->tableInfo; return pTableMeta->tableInfo;
} }
int32_t trimString(const char* src, int32_t len, char* dst, int32_t dlen) {
// delete escape character: \\, \', \"
char delim = src[0];
int32_t cnt = 0;
int32_t j = 0;
for (uint32_t k = 1; k < len - 1; ++k) {
if (j >= dlen) {
break;
}
if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
dst[j] = src[k + 1];
cnt++;
j++;
k++;
continue;
}
dst[j] = src[k];
j++;
}
dst[j] = '\0';
return j;
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册