Skip to content

Commit 2bcaa5b

Browse files
authored
[fix](nereids) Fix not check column name when create or alter view (#42206)
This is brought by #32743 set enable_unicode_name_support = true; If run create view sql should fail beausel_shipdate column name contains invalid char '(' and ')', but now success this pr fix this and throw exception `ERROR 1105 (HY000): errCode = 2, detailMessage = Incorrect column name '(日期)'. Column regex is '^[_a-zA-Z@0-9\s/][.a-zA-Z0-9_+-/?@#$%^&*"\s,:]{0,255}$'` CREATE VIEW view1 AS SELECT "零售公司", l_shipdate as '(日期)', l_receiptdate as k2 FROM lineitem; and if run create view sql as following, should success: CREATE VIEW view2 AS SELECT "零售公司", l_shipdate as '日期', l_receiptdate as k2 FROM lineitem; and the schema of view2 should be mysql> desc view2; +-------------+-------------+------+-------+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+-------------+------+-------+---------+-------+ | __literal_0 | varchar(16) | No | false | NULL | | | 日期 | date | No | false | NULL | | | k2 | date | No | false | NULL | | +-------------+-------------+------+-------+---------+-------+ 3 rows in set (0.01 sec)
1 parent 40572ee commit 2bcaa5b

File tree

5 files changed

+75
-44
lines changed

5 files changed

+75
-44
lines changed

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/AlterViewInfo.java

-19
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.apache.doris.analysis.AlterViewStmt;
2121
import org.apache.doris.analysis.ColWithComment;
2222
import org.apache.doris.analysis.TableName;
23-
import org.apache.doris.catalog.Column;
2423
import org.apache.doris.catalog.DatabaseIf;
2524
import org.apache.doris.catalog.Env;
2625
import org.apache.doris.catalog.TableIf;
@@ -31,19 +30,13 @@
3130
import org.apache.doris.common.UserException;
3231
import org.apache.doris.common.util.Util;
3332
import org.apache.doris.mysql.privilege.PrivPredicate;
34-
import org.apache.doris.nereids.NereidsPlanner;
35-
import org.apache.doris.nereids.analyzer.UnboundResultSink;
36-
import org.apache.doris.nereids.properties.PhysicalProperties;
3733
import org.apache.doris.nereids.trees.expressions.Slot;
38-
import org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel;
3934
import org.apache.doris.nereids.util.PlanUtils;
4035
import org.apache.doris.qe.ConnectContext;
4136

4237
import com.google.common.collect.Lists;
43-
import com.google.common.collect.Sets;
4438

4539
import java.util.List;
46-
import java.util.Set;
4740

4841
/** AlterViewInfo */
4942
public class AlterViewInfo extends BaseViewInfo {
@@ -83,18 +76,6 @@ public void init(ConnectContext ctx) throws UserException {
8376
createFinalCols(outputs);
8477
}
8578

86-
/**validate*/
87-
public void validate(ConnectContext ctx) throws UserException {
88-
NereidsPlanner planner = new NereidsPlanner(ctx.getStatementContext());
89-
planner.planWithLock(new UnboundResultSink<>(logicalQuery), PhysicalProperties.ANY, ExplainLevel.NONE);
90-
Set<String> colSets = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
91-
for (Column col : finalCols) {
92-
if (!colSets.add(col.getName())) {
93-
ErrorReport.reportAnalysisException(ErrorCode.ERR_DUP_FIELDNAME, col.getName());
94-
}
95-
}
96-
}
97-
9879
/**translateToLegacyStmt*/
9980
public AlterViewStmt translateToLegacyStmt(ConnectContext ctx) {
10081
List<ColWithComment> cols = Lists.newArrayList();

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/BaseViewInfo.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
import org.apache.doris.common.AnalysisException;
2222
import org.apache.doris.common.ErrorCode;
2323
import org.apache.doris.common.ErrorReport;
24+
import org.apache.doris.common.FeNameFormat;
2425
import org.apache.doris.common.Pair;
26+
import org.apache.doris.common.UserException;
2527
import org.apache.doris.nereids.CascadesContext;
2628
import org.apache.doris.nereids.DorisParser;
2729
import org.apache.doris.nereids.DorisParser.NamedExpressionContext;
2830
import org.apache.doris.nereids.DorisParser.NamedExpressionSeqContext;
2931
import org.apache.doris.nereids.DorisParserBaseVisitor;
32+
import org.apache.doris.nereids.NereidsPlanner;
3033
import org.apache.doris.nereids.StatementContext;
3134
import org.apache.doris.nereids.analyzer.UnboundResultSink;
3235
import org.apache.doris.nereids.jobs.executor.AbstractBatchJobExecutor;
@@ -44,6 +47,7 @@
4447
import org.apache.doris.nereids.trees.expressions.Slot;
4548
import org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionVisitor;
4649
import org.apache.doris.nereids.trees.plans.Plan;
50+
import org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel;
4751
import org.apache.doris.nereids.trees.plans.logical.LogicalAggregate;
4852
import org.apache.doris.nereids.trees.plans.logical.LogicalFileSink;
4953
import org.apache.doris.nereids.trees.plans.logical.LogicalFilter;
@@ -62,13 +66,15 @@
6266
import org.apache.doris.qe.ConnectContext;
6367

6468
import com.google.common.collect.Lists;
69+
import com.google.common.collect.Sets;
6570
import org.antlr.v4.runtime.ParserRuleContext;
6671
import org.antlr.v4.runtime.tree.ParseTree;
6772
import org.antlr.v4.runtime.tree.RuleNode;
6873
import org.apache.commons.lang3.StringUtils;
6974

7075
import java.util.List;
7176
import java.util.Map;
77+
import java.util.Set;
7278
import java.util.TreeMap;
7379

7480
/** BaseViewInfo */
@@ -94,9 +100,6 @@ protected void analyzeAndFillRewriteSqlMap(String sql, ConnectContext ctx) throw
94100
if (logicalQuery instanceof LogicalFileSink) {
95101
throw new AnalysisException("Not support OUTFILE clause in CREATE VIEW statement");
96102
}
97-
if (parsedViewPlan instanceof UnboundResultSink) {
98-
parsedViewPlan = (LogicalPlan) ((UnboundResultSink<?>) parsedViewPlan).child();
99-
}
100103
CascadesContext viewContextForStar = CascadesContext.initContext(
101104
stmtCtx, parsedViewPlan, PhysicalProperties.ANY);
102105
AnalyzerForCreateView analyzerForStar = new AnalyzerForCreateView(viewContextForStar);
@@ -175,6 +178,23 @@ protected void createFinalCols(List<Slot> outputs) throws org.apache.doris.commo
175178
}
176179
}
177180

181+
/**validate*/
182+
public void validate(ConnectContext ctx) throws UserException {
183+
NereidsPlanner planner = new NereidsPlanner(ctx.getStatementContext());
184+
planner.planWithLock(new UnboundResultSink<>(logicalQuery), PhysicalProperties.ANY, ExplainLevel.NONE);
185+
Set<String> colSets = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
186+
for (Column col : finalCols) {
187+
if (!colSets.add(col.getName())) {
188+
ErrorReport.reportAnalysisException(ErrorCode.ERR_DUP_FIELDNAME, col.getName());
189+
}
190+
try {
191+
FeNameFormat.checkColumnName(col.getName());
192+
} catch (org.apache.doris.common.AnalysisException e) {
193+
throw new org.apache.doris.nereids.exceptions.AnalysisException(e.getMessage(), e);
194+
}
195+
}
196+
}
197+
178198
/** traverse ast to find the outermost project list location information in sql*/
179199
protected static class IndexFinder extends DorisParserBaseVisitor<Void> {
180200
private boolean found = false;

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateViewInfo.java

-19
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,20 @@
2020
import org.apache.doris.analysis.ColWithComment;
2121
import org.apache.doris.analysis.CreateViewStmt;
2222
import org.apache.doris.analysis.TableName;
23-
import org.apache.doris.catalog.Column;
2423
import org.apache.doris.catalog.Env;
2524
import org.apache.doris.common.ErrorCode;
2625
import org.apache.doris.common.ErrorReport;
2726
import org.apache.doris.common.FeNameFormat;
2827
import org.apache.doris.common.UserException;
2928
import org.apache.doris.common.util.Util;
3029
import org.apache.doris.mysql.privilege.PrivPredicate;
31-
import org.apache.doris.nereids.NereidsPlanner;
32-
import org.apache.doris.nereids.analyzer.UnboundResultSink;
33-
import org.apache.doris.nereids.properties.PhysicalProperties;
3430
import org.apache.doris.nereids.trees.expressions.Slot;
35-
import org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel;
3631
import org.apache.doris.nereids.util.PlanUtils;
3732
import org.apache.doris.qe.ConnectContext;
3833

3934
import com.google.common.collect.Lists;
40-
import com.google.common.collect.Sets;
4135

4236
import java.util.List;
43-
import java.util.Set;
4437

4538
/**
4639
* CreateViewInfo
@@ -78,18 +71,6 @@ public void init(ConnectContext ctx) throws UserException {
7871
createFinalCols(outputs);
7972
}
8073

81-
/**validate*/
82-
public void validate(ConnectContext ctx) throws UserException {
83-
NereidsPlanner planner = new NereidsPlanner(ctx.getStatementContext());
84-
planner.planWithLock(new UnboundResultSink<>(logicalQuery), PhysicalProperties.ANY, ExplainLevel.NONE);
85-
Set<String> colSets = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
86-
for (Column col : finalCols) {
87-
if (!colSets.add(col.getName())) {
88-
ErrorReport.reportAnalysisException(ErrorCode.ERR_DUP_FIELDNAME, col.getName());
89-
}
90-
}
91-
}
92-
9374
/**translateToLegacyStmt*/
9475
public CreateViewStmt translateToLegacyStmt(ConnectContext ctx) {
9576
List<ColWithComment> cols = Lists.newArrayList();

regression-test/data/ddl_p0/test_create_view_nereids.out

+23-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ test_view_from_view CREATE VIEW `test_view_from_view` AS select `internal`.`regr
202202
7 1
203203

204204
-- !test_backquote_in_view_define_sql --
205-
test_backquote_in_view_define CREATE VIEW `test_backquote_in_view_define` AS select `internal`.`regression_test_ddl_p0`.`mal_test_view`.`a` AS `ab``c`, `internal`.`regression_test_ddl_p0`.`mal_test_view`.`b` AS `c2` from `internal`.`regression_test_ddl_p0`.`mal_test_view`; utf8mb4 utf8mb4_0900_bin
205+
test_backquote_in_view_define CREATE VIEW `test_backquote_in_view_define` AS select `internal`.`regression_test_ddl_p0`.`mal_test_view`.`a` AS `abc`, `internal`.`regression_test_ddl_p0`.`mal_test_view`.`b` AS `c2` from `internal`.`regression_test_ddl_p0`.`mal_test_view`; utf8mb4 utf8mb4_0900_bin
206206

207207
-- !test_backquote_in_table_alias --
208208
\N 6
@@ -226,6 +226,28 @@ test_backquote_in_view_define CREATE VIEW `test_backquote_in_view_define` AS sel
226226
-- !test_backquote_in_table_alias_sql --
227227
test_backquote_in_table_alias CREATE VIEW `test_backquote_in_table_alias` AS select `internal`.`regression_test_ddl_p0`.`ab``c`.`a` AS `c1`, `internal`.`regression_test_ddl_p0`.`ab``c`.`b` AS `c2` from (select `internal`.`regression_test_ddl_p0`.`mal_test_view`.`a`,`internal`.`regression_test_ddl_p0`.`mal_test_view`.`b` from `internal`.`regression_test_ddl_p0`.`mal_test_view`) `ab``c`; utf8mb4 utf8mb4_0900_bin
228228

229+
-- !test_invalid_column_name_in_table --
230+
\N 6
231+
1 2
232+
1 3
233+
1 4
234+
1 4
235+
1 7
236+
2 8
237+
3 5
238+
3 6
239+
3 9
240+
4 2
241+
5 \N
242+
5 6
243+
5 6
244+
5 6
245+
5 8
246+
7 1
247+
248+
-- !test_invalid_column_name_in_table_define_sql --
249+
test_invalid_column_name_in_table CREATE VIEW `test_invalid_column_name_in_table` AS select `internal`.`regression_test_ddl_p0`.`mal_test_view`.`a` ,`internal`.`regression_test_ddl_p0`.`mal_test_view`.`b` from `internal`.`regression_test_ddl_p0`.`mal_test_view`; utf8mb4 utf8mb4_0900_bin
250+
229251
-- !test_generate --
230252
1 10 A 30
231253
1 10 A 60

regression-test/suites/ddl_p0/test_create_view_nereids.groovy

+29-2
Original file line numberDiff line numberDiff line change
@@ -267,17 +267,44 @@ suite("test_create_view_nereids") {
267267
qt_test_create_view_from_view_sql "show create view test_view_from_view"
268268

269269
// test backquote in name
270+
try {
271+
sql "create view test_backquote_in_view_define(`ab``c`, c2) as select a,b from mal_test_view;"
272+
} catch (Exception e) {
273+
assertTrue(e.getMessage().contains("Incorrect column name 'ab`c'"))
274+
}
270275

271276
sql "drop view if exists test_backquote_in_view_define;"
272-
sql "create view test_backquote_in_view_define(`ab``c`, c2) as select a,b from mal_test_view;"
273-
qt_test_backquote_in_view_define "select * from test_backquote_in_view_define order by `ab``c`, c2;"
277+
sql "create view test_backquote_in_view_define(`abc`, c2) as select a,b from mal_test_view;"
278+
qt_test_backquote_in_view_define "select * from test_backquote_in_view_define order by abc, c2;"
274279
qt_test_backquote_in_view_define_sql "show create view test_backquote_in_view_define;"
275280

276281
sql "drop view if exists test_backquote_in_table_alias;"
277282
sql "create view test_backquote_in_table_alias(c1, c2) as select * from (select a,b from mal_test_view) `ab``c`;"
278283
qt_test_backquote_in_table_alias "select * from test_backquote_in_table_alias order by c1, c2;"
279284
qt_test_backquote_in_table_alias_sql "show create view test_backquote_in_table_alias;"
280285

286+
// test invalid column name
287+
sql """set enable_unicode_name_support = true;"""
288+
sql "drop view if exists test_invalid_column_name_in_table;"
289+
try {
290+
// create view should fail if contains invalid column name
291+
sql "create view test_invalid_column_name_in_table as select a as '(第一列)',b from mal_test_view;"
292+
} catch (Exception e) {
293+
assertTrue(e.getMessage().contains("Incorrect column name '(第一列)'"))
294+
}
295+
296+
sql "create view test_invalid_column_name_in_table as select a ,b from mal_test_view;"
297+
order_qt_test_invalid_column_name_in_table "select * from test_invalid_column_name_in_table"
298+
order_qt_test_invalid_column_name_in_table_define_sql "show create view test_invalid_column_name_in_table;"
299+
300+
try {
301+
// alter view should fail if contains invalid column name
302+
sql "alter view test_invalid_column_name_in_table as select a as '(第一列)',b from mal_test_view;"
303+
} catch (Exception e) {
304+
assertTrue(e.getMessage().contains("Incorrect column name '(第一列)'"))
305+
}
306+
sql """set enable_unicode_name_support = false;"""
307+
281308
sql "drop table if exists create_view_table1"
282309
sql """CREATE TABLE create_view_table1 (
283310
id INT,

0 commit comments

Comments
 (0)