Merge pull request #5214 from taosdata/feature/TD-2423
[TD-2423]support create child table with specified tag list
This commit is contained in:
commit
67671328df
|
@ -6375,16 +6375,14 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
// get table meta from mnode
|
// get table meta from mnode
|
||||||
code = tNameExtractFullName(&pStableMetaInfo->name, pCreateTableInfo->tagdata.name);
|
code = tNameExtractFullName(&pStableMetaInfo->name, pCreateTableInfo->tagdata.name);
|
||||||
|
|
||||||
SArray* pList = pCreateTableInfo->pTagVals;
|
SArray* pValList = pCreateTableInfo->pTagVals;
|
||||||
code = tscGetTableMeta(pSql, pStableMetaInfo);
|
code = tscGetTableMeta(pSql, pStableMetaInfo);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = taosArrayGetSize(pList);
|
size_t valSize = taosArrayGetSize(pValList);
|
||||||
if (tscGetNumOfTags(pStableMetaInfo->pTableMeta) != size) {
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// too long tag values will return invalid sql, not be truncated automatically
|
// too long tag values will return invalid sql, not be truncated automatically
|
||||||
SSchema *pTagSchema = tscGetTableTagSchema(pStableMetaInfo->pTableMeta);
|
SSchema *pTagSchema = tscGetTableTagSchema(pStableMetaInfo->pTableMeta);
|
||||||
|
@ -6395,36 +6393,111 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SArray* pNameList = NULL;
|
||||||
|
size_t nameSize = 0;
|
||||||
|
int32_t schemaSize = tscGetNumOfTags(pStableMetaInfo->pTableMeta);
|
||||||
int32_t ret = TSDB_CODE_SUCCESS;
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
|
||||||
SSchema* pSchema = &pTagSchema[i];
|
|
||||||
tVariantListItem* pItem = taosArrayGet(pList, i);
|
|
||||||
|
|
||||||
char tagVal[TSDB_MAX_TAGS_LEN];
|
if (pCreateTableInfo->pTagNames) {
|
||||||
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
|
pNameList = pCreateTableInfo->pTagNames;
|
||||||
if (pItem->pVar.nLen > pSchema->bytes) {
|
nameSize = taosArrayGetSize(pNameList);
|
||||||
tdDestroyKVRowBuilder(&kvRowBuilder);
|
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
if (valSize != nameSize) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schemaSize < valSize) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool findColumnIndex = false;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < nameSize; ++i) {
|
||||||
|
SStrToken* sToken = taosArrayGet(pNameList, i);
|
||||||
|
if (TK_STRING == sToken->type) {
|
||||||
|
tscDequoteAndTrimToken(sToken);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
|
tVariantListItem* pItem = taosArrayGet(pValList, i);
|
||||||
|
|
||||||
// check again after the convert since it may be converted from binary to nchar.
|
findColumnIndex = false;
|
||||||
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
|
|
||||||
int16_t len = varDataTLen(tagVal);
|
// todo speedup by using hash list
|
||||||
if (len > pSchema->bytes) {
|
for (int32_t t = 0; t < schemaSize; ++t) {
|
||||||
tdDestroyKVRowBuilder(&kvRowBuilder);
|
if (strncmp(sToken->z, pTagSchema[t].name, sToken->n) == 0 && strlen(pTagSchema[t].name) == sToken->n) {
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
SSchema* pSchema = &pTagSchema[t];
|
||||||
|
|
||||||
|
char tagVal[TSDB_MAX_TAGS_LEN];
|
||||||
|
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
if (pItem->pVar.nLen > pSchema->bytes) {
|
||||||
|
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
|
||||||
|
|
||||||
|
// check again after the convert since it may be converted from binary to nchar.
|
||||||
|
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
int16_t len = varDataTLen(tagVal);
|
||||||
|
if (len > pSchema->bytes) {
|
||||||
|
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
|
||||||
|
tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
|
||||||
|
|
||||||
|
findColumnIndex = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!findColumnIndex) {
|
||||||
|
return tscInvalidSQLErrMsg(pCmd->payload, "invalid tag name", sToken->z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (schemaSize != valSize) {
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
for (int32_t i = 0; i < valSize; ++i) {
|
||||||
tdDestroyKVRowBuilder(&kvRowBuilder);
|
SSchema* pSchema = &pTagSchema[i];
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
tVariantListItem* pItem = taosArrayGet(pValList, i);
|
||||||
|
|
||||||
|
char tagVal[TSDB_MAX_TAGS_LEN];
|
||||||
|
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
if (pItem->pVar.nLen > pSchema->bytes) {
|
||||||
|
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = tVariantDump(&(pItem->pVar), tagVal, pSchema->type, true);
|
||||||
|
|
||||||
|
// check again after the convert since it may be converted from binary to nchar.
|
||||||
|
if (pSchema->type == TSDB_DATA_TYPE_BINARY || pSchema->type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
int16_t len = varDataTLen(tagVal);
|
||||||
|
if (len > pSchema->bytes) {
|
||||||
|
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
tdDestroyKVRowBuilder(&kvRowBuilder);
|
||||||
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
|
||||||
|
tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
tdAddColToKVRow(&kvRowBuilder, pSchema->colId, pSchema->type, tagVal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
|
SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder);
|
||||||
|
|
|
@ -122,8 +122,8 @@
|
||||||
#define TK_UNSIGNED 103
|
#define TK_UNSIGNED 103
|
||||||
#define TK_TAGS 104
|
#define TK_TAGS 104
|
||||||
#define TK_USING 105
|
#define TK_USING 105
|
||||||
#define TK_AS 106
|
#define TK_COMMA 106
|
||||||
#define TK_COMMA 107
|
#define TK_AS 107
|
||||||
#define TK_NULL 108
|
#define TK_NULL 108
|
||||||
#define TK_SELECT 109
|
#define TK_SELECT 109
|
||||||
#define TK_UNION 110
|
#define TK_UNION 110
|
||||||
|
@ -228,6 +228,7 @@
|
||||||
#define TK_VALUES 209
|
#define TK_VALUES 209
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TK_SPACE 300
|
#define TK_SPACE 300
|
||||||
#define TK_COMMENT 301
|
#define TK_COMMENT 301
|
||||||
#define TK_ILLEGAL 302
|
#define TK_ILLEGAL 302
|
||||||
|
|
|
@ -76,6 +76,7 @@ typedef struct SQuerySQL {
|
||||||
typedef struct SCreatedTableInfo {
|
typedef struct SCreatedTableInfo {
|
||||||
SStrToken name; // table name token
|
SStrToken name; // table name token
|
||||||
SStrToken stableName; // super table name token , for using clause
|
SStrToken stableName; // super table name token , for using clause
|
||||||
|
SArray *pTagNames; // create by using super table, tag name
|
||||||
SArray *pTagVals; // create by using super table, tag value
|
SArray *pTagVals; // create by using super table, tag value
|
||||||
char *fullname; // table full name
|
char *fullname; // table full name
|
||||||
STagData tagdata; // true tag data, super table full name is in STagData
|
STagData tagdata; // true tag data, super table full name is in STagData
|
||||||
|
@ -246,7 +247,7 @@ SCreateTableSQL *tSetCreateSqlElems(SArray *pCols, SArray *pTags, SQuerySQL *pSe
|
||||||
void tSqlExprNodeDestroy(tSQLExpr *pExpr);
|
void tSqlExprNodeDestroy(tSQLExpr *pExpr);
|
||||||
|
|
||||||
SAlterTableInfo * tAlterTableSqlElems(SStrToken *pTableName, SArray *pCols, SArray *pVals, int32_t type, int16_t tableTable);
|
SAlterTableInfo * tAlterTableSqlElems(SStrToken *pTableName, SArray *pCols, SArray *pVals, int32_t type, int16_t tableTable);
|
||||||
SCreatedTableInfo createNewChildTableInfo(SStrToken *pTableName, SArray *pTagVals, SStrToken *pToken, SStrToken* igExists);
|
SCreatedTableInfo createNewChildTableInfo(SStrToken *pTableName, SArray *pTagNames, SArray *pTagVals, SStrToken *pToken, SStrToken* igExists);
|
||||||
|
|
||||||
void destroyAllSelectClause(SSubclauseInfo *pSql);
|
void destroyAllSelectClause(SSubclauseInfo *pSql);
|
||||||
void doDestroyQuerySql(SQuerySQL *pSql);
|
void doDestroyQuerySql(SQuerySQL *pSql);
|
||||||
|
|
|
@ -356,9 +356,20 @@ create_stable_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) LP columnlist(X) RP T
|
||||||
create_from_stable(A) ::= ifnotexists(U) ids(V) cpxName(Z) USING ids(X) cpxName(F) TAGS LP tagitemlist(Y) RP. {
|
create_from_stable(A) ::= ifnotexists(U) ids(V) cpxName(Z) USING ids(X) cpxName(F) TAGS LP tagitemlist(Y) RP. {
|
||||||
X.n += F.n;
|
X.n += F.n;
|
||||||
V.n += Z.n;
|
V.n += Z.n;
|
||||||
A = createNewChildTableInfo(&X, Y, &V, &U);
|
A = createNewChildTableInfo(&X, NULL, Y, &V, &U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_from_stable(A) ::= ifnotexists(U) ids(V) cpxName(Z) USING ids(X) cpxName(F) LP tagNamelist(P) RP TAGS LP tagitemlist(Y) RP. {
|
||||||
|
X.n += F.n;
|
||||||
|
V.n += Z.n;
|
||||||
|
A = createNewChildTableInfo(&X, P, Y, &V, &U);
|
||||||
|
}
|
||||||
|
|
||||||
|
%type tagNamelist{SArray*}
|
||||||
|
%destructor tagNamelist {taosArrayDestroy($$);}
|
||||||
|
tagNamelist(A) ::= tagNamelist(X) COMMA ids(Y). {taosArrayPush(X, &Y); A = X; }
|
||||||
|
tagNamelist(A) ::= ids(X). {A = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(A, &X);}
|
||||||
|
|
||||||
// create stream
|
// create stream
|
||||||
// create table table_name as select count(*) from super_table_name interval(time)
|
// create table table_name as select count(*) from super_table_name interval(time)
|
||||||
create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) AS select(S). {
|
create_table_args(A) ::= ifnotexists(U) ids(V) cpxName(Z) AS select(S). {
|
||||||
|
|
|
@ -496,7 +496,8 @@ static void freeVariant(void *pItem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeCreateTableInfo(void* p) {
|
void freeCreateTableInfo(void* p) {
|
||||||
SCreatedTableInfo* pInfo = (SCreatedTableInfo*) p;
|
SCreatedTableInfo* pInfo = (SCreatedTableInfo*) p;
|
||||||
|
taosArrayDestroy(pInfo->pTagNames);
|
||||||
taosArrayDestroyEx(pInfo->pTagVals, freeVariant);
|
taosArrayDestroyEx(pInfo->pTagVals, freeVariant);
|
||||||
tfree(pInfo->fullname);
|
tfree(pInfo->fullname);
|
||||||
tfree(pInfo->tagdata.data);
|
tfree(pInfo->tagdata.data);
|
||||||
|
@ -574,11 +575,12 @@ SCreateTableSQL *tSetCreateSqlElems(SArray *pCols, SArray *pTags, SQuerySQL *pSe
|
||||||
return pCreate;
|
return pCreate;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCreatedTableInfo createNewChildTableInfo(SStrToken *pTableName, SArray *pTagVals, SStrToken *pToken, SStrToken* igExists) {
|
SCreatedTableInfo createNewChildTableInfo(SStrToken *pTableName, SArray *pTagNames, SArray *pTagVals, SStrToken *pToken, SStrToken* igExists) {
|
||||||
SCreatedTableInfo info;
|
SCreatedTableInfo info;
|
||||||
memset(&info, 0, sizeof(SCreatedTableInfo));
|
memset(&info, 0, sizeof(SCreatedTableInfo));
|
||||||
|
|
||||||
info.name = *pToken;
|
info.name = *pToken;
|
||||||
|
info.pTagNames = pTagNames;
|
||||||
info.pTagVals = pTagVals;
|
info.pTagVals = pTagVals;
|
||||||
info.stableName = *pTableName;
|
info.stableName = *pTableName;
|
||||||
info.igExist = (igExists->n > 0)? 1:0;
|
info.igExist = (igExists->n > 0)? 1:0;
|
||||||
|
|
2026
src/query/src/sql.c
2026
src/query/src/sql.c
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,162 @@
|
||||||
|
system sh/stop_dnodes.sh
|
||||||
|
system sh/deploy.sh -n dnode1 -i 1
|
||||||
|
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||||
|
system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2
|
||||||
|
system sh/exec.sh -n dnode1 -s start
|
||||||
|
|
||||||
|
sleep 100
|
||||||
|
sql connect
|
||||||
|
print ======================== dnode1 start
|
||||||
|
|
||||||
|
$db = testdb
|
||||||
|
|
||||||
|
sql create database $db
|
||||||
|
sql use $db
|
||||||
|
|
||||||
|
sql create stable st2 (ts timestamp, f1 int) tags (id int, t1 int, t2 nchar(4), t3 double)
|
||||||
|
|
||||||
|
|
||||||
|
sql insert into tb1 using st2 (id, t1) tags(1,2) values (now, 1)
|
||||||
|
|
||||||
|
sql select id,t1,t2,t3 from tb1
|
||||||
|
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data01 != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data02 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data03 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql create table tb2 using st2 (t2,t3) tags ("12",22.0)
|
||||||
|
|
||||||
|
sql select id,t1,t2,t3 from tb2;
|
||||||
|
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data01 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data02 != 12 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data03 != 22.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
|
||||||
|
sql create table tb3 using st2 tags (1,2,"3",33.0);
|
||||||
|
|
||||||
|
sql select id,t1,t2,t3 from tb3;
|
||||||
|
|
||||||
|
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data01 != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data02 != 3 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data03 != 33.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql insert into tb4 using st2 tags(1,2,"33",44.0) values (now, 1);
|
||||||
|
|
||||||
|
sql select id,t1,t2,t3 from tb4;
|
||||||
|
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data01 != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data02 != 33 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data03 != 44.000000000 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql_error create table tb5 using st2() tags (3,3,"3",33.0);
|
||||||
|
|
||||||
|
sql_error create table tb6 using st2 (id,t1) tags (3,3,"3",33.0);
|
||||||
|
|
||||||
|
sql_error create table tb7 using st2 (id,t1) tags (3);
|
||||||
|
|
||||||
|
sql_error create table tb8 using st2 (ide) tags (3);
|
||||||
|
|
||||||
|
sql_error create table tb9 using st2 (id);
|
||||||
|
|
||||||
|
sql_error create table tb10 using st2 (id t1) tags (1,1);
|
||||||
|
|
||||||
|
sql_error create table tb10 using st2 (id,,t1) tags (1,1,1);
|
||||||
|
|
||||||
|
sql_error create table tb11 using st2 (id,t1,) tags (1,1,1);
|
||||||
|
|
||||||
|
sql create table tb12 using st2 (t1,id) tags (2,1);
|
||||||
|
|
||||||
|
sql select id,t1,t2,t3 from tb12;
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data01 != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data02 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data03 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
sql create table tb13 using st2 ("t1",'id') tags (2,1);
|
||||||
|
|
||||||
|
sql select id,t1,t2,t3 from tb13;
|
||||||
|
|
||||||
|
if $rows != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
if $data00 != 1 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data01 != 2 then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data02 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
if $data03 != NULL then
|
||||||
|
return -1
|
||||||
|
endi
|
||||||
|
|
||||||
|
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
Loading…
Reference in New Issue