From 01fef3069483eebb29b7aca1d51e19f917cfb5c6 Mon Sep 17 00:00:00 2001 From: Jing Sima Date: Sun, 23 Mar 2025 17:26:28 +0800 Subject: [PATCH] fix: [TS-4897] Fix create child table after modify super virtual table failed (#30316) --- source/libs/parser/src/parTranslater.c | 19 +++++++-- tests/army/vtable/test_vtable_alter.py | 55 ++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 1b8f0e034c..10b631c2c3 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -10784,6 +10784,18 @@ static const SSchema* getNormalColSchema(const STableMeta* pTableMeta, const cha return NULL; } +static const col_id_t getNormalColSchemaIndex(const STableMeta* pTableMeta, const char* pColName) { + int32_t numOfCols = getNumOfColumns(pTableMeta); + SSchema* pColsSchema = getTableColumnSchema(pTableMeta); + for (int32_t i = 0; i < numOfCols; ++i) { + const SSchema* pSchema = pColsSchema + i; + if (0 == strcmp(pColName, pSchema->name)) { + return (col_id_t)i; + } + } + return -1; +} + static SSchema* getTagSchema(const STableMeta* pTableMeta, const char* pTagName) { int32_t numOfTags = getNumOfTags(pTableMeta); SSchema* pTagsSchema = getTableTagSchema(pTableMeta); @@ -16065,11 +16077,12 @@ static int32_t buildVirtualSubTableBatchReq(const SCreateVSubTableStmt* pStmt, S if (pStmt->pSpecificColRefs) { FOREACH(pCol, pStmt->pSpecificColRefs) { SColumnRefNode* pColRef = (SColumnRefNode*)pCol; - const SSchema* pSchema = getColSchema(pStbMeta, pColRef->colName); - if (pSchema == NULL) { + col_id_t schemaIdx = getNormalColSchemaIndex(pStbMeta, pColRef->colName); + if (schemaIdx == -1) { PAR_ERR_JRET(TSDB_CODE_PAR_INVALID_COLUMN); } - PAR_ERR_JRET(setColRef(&req.colRef.pColRef[pSchema->colId - 1], pSchema->colId, pColRef->refColName, pColRef->refTableName, pColRef->refDbName)); + const SSchema* pSchema = getTableColumnSchema(pStbMeta) + schemaIdx; + PAR_ERR_JRET(setColRef(&req.colRef.pColRef[schemaIdx], pSchema->colId, pColRef->refColName, pColRef->refTableName, pColRef->refDbName)); } } else if (pStmt->pColRefs){ col_id_t index = 1; // start from second column, don't set column ref for ts column diff --git a/tests/army/vtable/test_vtable_alter.py b/tests/army/vtable/test_vtable_alter.py index 79df00ae17..2cfa1c498e 100644 --- a/tests/army/vtable/test_vtable_alter.py +++ b/tests/army/vtable/test_vtable_alter.py @@ -22,7 +22,10 @@ class TDTestCase(TBase): def prepare_vtables(self): tdSql.execute("drop table if exists vtb_virtual_stb;") + tdSql.execute("drop table if exists vtb_virtual_stb_1;") tdSql.execute("drop table if exists vtb_virtual_ctb0;") + tdSql.execute("drop table if exists vtb_virtual_ctb_after_modified_1;") + tdSql.execute("drop table if exists vtb_virtual_ctb_after_modified_2;") tdSql.execute("drop table if exists vtb_virtual_ntb0;") tdLog.info(f"prepare virtual super tables.") tdSql.execute(f"CREATE STABLE `vtb_virtual_stb` (" @@ -55,6 +58,36 @@ class TDTestCase(TBase): "binary_32_tag binary(32))" "VIRTUAL 1") + tdSql.execute(f"CREATE STABLE `vtb_virtual_stb_1` (" + "ts timestamp, " + "u_tinyint_col tinyint unsigned, " + "u_smallint_col smallint unsigned, " + "u_int_col int unsigned, " + "u_bigint_col bigint unsigned, " + "tinyint_col tinyint, " + "smallint_col smallint, " + "int_col int, " + "bigint_col bigint, " + "float_col float, " + "double_col double, " + "bool_col bool, " + "binary_16_col binary(16)," + "binary_32_col binary(32)," + "nchar_16_col nchar(16)," + "nchar_32_col nchar(32)," + "varbinary_16_col varbinary(16)," + "varbinary_32_col varbinary(32)," + "geo_16_col geometry(16)," + "geo_32_col geometry(32)" + ") TAGS (" + "int_tag int," + "bool_tag bool," + "float_tag float," + "double_tag double," + "nchar_32_tag nchar(32)," + "binary_32_tag binary(32))" + "VIRTUAL 1") + tdLog.info(f"prepare virtual child tables.") tdSql.execute("CREATE VTABLE `vtb_virtual_ctb0`(" "u_tinyint_col FROM vtb_org_child_0.u_tinyint_col, " @@ -301,6 +334,27 @@ class TDTestCase(TBase): tdSql.query(f"select tag_type from information_schema.ins_tags where db_name='test_vtable_alter' and table_name='vtb_virtual_ctb0' and tag_name='nchar_32_tag'") tdSql.checkData(0, 0, "NCHAR(64)") + def test_alter_virtual_super_table_and_create_child(self): + tdLog.info(f"test alter virtual super tables and create child.") + + tdSql.execute("use test_vtable_alter;") + tdSql.execute("select database();") + + # 1. add column + # 1.1. add column without column reference + tdSql.execute("alter stable vtb_virtual_stb_1 add column extra_boolcol bool") + + # 1.2. create child table using modified super table + tdSql.execute("CREATE VTABLE `vtb_virtual_ctb_after_modified_1`(bool_col from vtb_org_child_18.bool_col, extra_boolcol from vtb_org_child_19.bool_col) USING vtb_virtual_stb_1 TAGS (0, false, 0, 0, 'vchild0', 'vchild0')") + tdSql.execute("select * from vtb_virtual_ctb_after_modified_1") + + # 2. drop column + # 2.1. drop column from stb + tdSql.execute("alter stable vtb_virtual_stb_1 drop column bool_col;") + tdSql.execute("CREATE VTABLE `vtb_virtual_ctb_after_modified_2`(extra_boolcol from vtb_org_child_17.bool_col) USING vtb_virtual_stb_1 TAGS (0, false, 0, 0, 'vchild0', 'vchild0')") + + tdSql.execute("select * from vtb_virtual_ctb_after_modified_2") + def test_error_cases(self): tdLog.info(f"test alter virtual super tables.") @@ -360,6 +414,7 @@ class TDTestCase(TBase): self.test_alter_virtual_normal_table() self.test_alter_virtual_child_table() self.test_alter_virtual_super_table() + self.test_alter_virtual_super_table_and_create_child() self.test_error_cases() tdLog.success(f"{__file__} successfully executed")