From 0792b025eabde7cc4240b7d7f93e8ebad2d18c25 Mon Sep 17 00:00:00 2001 From: kailixu Date: Fri, 19 Jul 2024 15:08:34 +0800 Subject: [PATCH] fix: insert clause mixed with bound and unspecified columns --- include/libs/qcom/query.h | 1 + source/libs/parser/inc/parInsertUtil.h | 1 + source/libs/parser/src/parInsertSql.c | 3 +++ source/libs/parser/src/parInsertUtil.c | 9 +++++++++ tests/system-test/1-insert/insert_column_value.py | 13 +++++++++++-- 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index 2078455f1d..347fb203ef 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -192,6 +192,7 @@ typedef struct SBoundColInfo { int16_t* pColIndex; // bound index => schema index int32_t numOfCols; int32_t numOfBound; + bool hasBoundCols; } SBoundColInfo; typedef struct STableColsData { diff --git a/source/libs/parser/inc/parInsertUtil.h b/source/libs/parser/inc/parInsertUtil.h index 4f2877fcf6..899661a18c 100644 --- a/source/libs/parser/inc/parInsertUtil.h +++ b/source/libs/parser/inc/parInsertUtil.h @@ -45,6 +45,7 @@ int16_t insFindCol(struct SToken *pColname, int16_t start, int16_t end, SSchema void insBuildCreateTbReq(SVCreateTbReq *pTbReq, const char *tname, STag *pTag, int64_t suid, const char *sname, SArray *tagName, uint8_t tagNum, int32_t ttl); int32_t insInitBoundColsInfo(int32_t numOfBound, SBoundColInfo *pInfo); +void insResetBoundColsInfo(SBoundColInfo *pInfo); void insInitColValues(STableMeta *pTableMeta, SArray *aColValues); void insCheckTableDataOrder(STableDataCxt *pTableCxt, SRowKey *rowKey); int32_t insGetTableDataCxt(SHashObj *pHash, void *id, int32_t idLen, STableMeta *pTableMeta, diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index 313d9449d2..0d0fe75ddb 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -183,6 +183,7 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, const char** pSql, E } pBoundInfo->numOfBound = 0; + pBoundInfo->hasBoundCols = true; bool hasPK = pTableMeta->tableInfo.numOfPKs; int16_t numOfBoundPKs = 0; @@ -1379,6 +1380,8 @@ static int32_t parseBoundColumnsClause(SInsertParseContext* pCxt, SVnodeModifyOp if (NULL != pStmt->pBoundCols) { return parseBoundColumns(pCxt, &pStmt->pBoundCols, BOUND_COLUMNS, pStmt->pTableMeta, &pTableCxt->boundColsInfo); + } else if (pTableCxt->boundColsInfo.hasBoundCols) { + insResetBoundColsInfo(&pTableCxt->boundColsInfo); } return TSDB_CODE_SUCCESS; diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index 17b5733ff7..7e1893ae00 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -180,6 +180,7 @@ void insInitColValues(STableMeta* pTableMeta, SArray* aColValues) { initColValue int32_t insInitBoundColsInfo(int32_t numOfBound, SBoundColInfo* pInfo) { pInfo->numOfCols = numOfBound; pInfo->numOfBound = numOfBound; + pInfo->hasBoundCols = false; pInfo->pColIndex = taosMemoryCalloc(numOfBound, sizeof(int16_t)); if (NULL == pInfo->pColIndex) { return TSDB_CODE_OUT_OF_MEMORY; @@ -190,6 +191,14 @@ int32_t insInitBoundColsInfo(int32_t numOfBound, SBoundColInfo* pInfo) { return TSDB_CODE_SUCCESS; } +void insResetBoundColsInfo(SBoundColInfo* pInfo) { + pInfo->numOfBound = pInfo->numOfCols; + pInfo->hasBoundCols = false; + for (int32_t i = 0; i < pInfo->numOfCols; ++i) { + pInfo->pColIndex[i] = i; + } +} + void insCheckTableDataOrder(STableDataCxt* pTableCxt, SRowKey* rowKey) { // once the data block is disordered, we do NOT keep last timestamp any more if (!pTableCxt->ordered) { diff --git a/tests/system-test/1-insert/insert_column_value.py b/tests/system-test/1-insert/insert_column_value.py index fcb83e2f97..956fa0d229 100644 --- a/tests/system-test/1-insert/insert_column_value.py +++ b/tests/system-test/1-insert/insert_column_value.py @@ -45,7 +45,7 @@ class TDTestCase: self.TIMESTAMP_BASE = 1706716800 tdSql.init(conn.cursor()) tdSql.execute(f'drop database if exists db') - tdSql.execute(f'create database if not exists db vgroups 1') + tdSql.execute(f'create database if not exists db vgroups 1 keep 10512000m') tdLog.printNoPrefix("create table") self.__create_tb() @@ -516,10 +516,19 @@ class TDTestCase: # check json self.__insert_query_json("db", "stb_js", "ctb_js", OK_JS, KO_JS, "\'{\"k1\":\"v1\",\"k2\":\"v2\"}\'") + def __insert_query_ts5184(self, dbname="db", stbname="stb_ts5184", ctbname="ctb_ts5184", ntbname="ntb_ts5184"): + TB_LIST = [ ctbname, ntbname] + tdSql.execute(f'create table {dbname}.{stbname} (ts timestamp, w_ts timestamp, opc nchar(100),quality int) tags(t0 int);') + tdSql.execute(f'create table {dbname}.{ntbname} (ts timestamp, w_ts timestamp, opc nchar(100),quality int);') + tdSql.execute(f'create table {dbname}.{ctbname} using {dbname}.{stbname} tags(1);') + for _tb in TB_LIST: + tdSql.execute(f'insert into {dbname}.{_tb} values(1721265436000,now(),"0",192) {dbname}.{_tb}(quality,w_ts,ts) values(192,now(),1721265326000) {dbname}.{_tb}(quality,w_ts,ts) values(190,now()+1s,1721265326000) {dbname}.{_tb} values(1721265436000,now()+2s,"1",191) {dbname}.{_tb}(quality,w_ts,ts) values(192,now()+3s,1721265326002) {dbname}.{_tb}(ts,w_ts,opc,quality) values(1721265436003,now()+4s,"3",193);'); + tdSql.query(f'select * from {dbname}.{_tb}', show=True) + tdSql.checkRows(4) def run(self): self.__insert_query_exec() - + self.__insert_query_ts5184() def stop(self): tdSql.close()