Skip to content

Commit 58522cb

Browse files
authored
fix(sql-check): avoid npe when virtual column exists (#2031)
1 parent 3227e5f commit 58522cb

7 files changed

Lines changed: 51 additions & 12 deletions

File tree

server/odc-service/src/main/java/com/oceanbase/odc/service/sqlcheck/rule/BaseRestrictIndexDataTypes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream)
145145
ColumnAttributes a = d.getColumnAttributes();
146146
if (a == null || CollectionUtils.isEmpty(a.getConstraints())) {
147147
return false;
148+
} else if (d.getDataType() == null) {
149+
return false;
148150
}
149151
return a.getConstraints().stream().anyMatch(c -> c.isPrimaryKey() || c.isUniqueKey())
150152
&& !isTypeAllowed(d.getDataType().getName());

server/odc-service/src/main/java/com/oceanbase/odc/service/sqlcheck/rule/BaseRestrictPKDataTypes.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ protected CreateTable getTable(String schema, String tableName, SqlCheckContext
118118
protected Map<String, String> getColumnName2TypeName(CreateTable createTable) {
119119
Map<String, String> col2TypeName = new HashMap<>();
120120
createTable.getColumnDefinitions().forEach(d -> {
121+
if (d.getDataType() == null) {
122+
return;
123+
}
121124
String column = unquoteIdentifier(d.getColumnReference().getColumn());
122125
col2TypeName.put(column, d.getDataType().getName());
123126
});
@@ -160,6 +163,8 @@ private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream)
160163
ColumnAttributes a = d.getColumnAttributes();
161164
if (a == null || CollectionUtils.isEmpty(a.getConstraints())) {
162165
return false;
166+
} else if (d.getDataType() == null) {
167+
return false;
163168
}
164169
return a.getConstraints().stream().anyMatch(InLineConstraint::isPrimaryKey)
165170
&& !isTypeAllowed(d.getDataType().getName());

server/odc-service/src/main/java/com/oceanbase/odc/service/sqlcheck/rule/MySQLRestrictAutoIncrementDataTypes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream)
8383
return false;
8484
}
8585
return Boolean.TRUE.equals(ca.getAutoIncrement());
86-
}).filter(d -> this.allowedTypeNames.stream()
86+
}).filter(d -> d.getDataType() != null && this.allowedTypeNames.stream()
8787
.noneMatch(s -> StringUtils.equalsIgnoreCase(s, d.getDataType().getName())))
8888
.map(d -> {
8989
DataType type = d.getDataType();

server/odc-service/src/main/java/com/oceanbase/odc/service/sqlcheck/rule/NoDefaultValueExists.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,19 @@ public List<DialectType> getSupportsDialectTypes() {
7676
}
7777

7878
private boolean containsIgnoreCase(String name) {
79+
if (name == null) {
80+
return true;
81+
}
7982
return this.typesAllowNoDefault.stream().anyMatch(s -> StringUtils.equalsIgnoreCase(s, name));
8083
}
8184

8285
private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream) {
8386
return stream.filter(d -> {
8487
ColumnAttributes attributes = d.getColumnAttributes();
8588
if (attributes == null) {
86-
return !containsIgnoreCase(d.getDataType().getName());
89+
return !containsIgnoreCase(getDataTypeName(d));
8790
}
88-
return attributes.getDefaultValue() == null && !containsIgnoreCase(d.getDataType().getName());
91+
return attributes.getDefaultValue() == null && !containsIgnoreCase(getDataTypeName(d));
8992
}).map(d -> {
9093
String dataTypes = "N/A";
9194
if (CollectionUtils.isNotEmpty(typesAllowNoDefault)) {
@@ -95,4 +98,8 @@ private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream)
9598
}).collect(Collectors.toList());
9699
}
97100

101+
private String getDataTypeName(ColumnDefinition definition) {
102+
return definition.getDataType() == null ? null : definition.getDataType().getName();
103+
}
104+
98105
}

server/odc-service/src/main/java/com/oceanbase/odc/service/sqlcheck/rule/ProhibitedDatatypeExists.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public List<DialectType> getSupportsDialectTypes() {
7676
}
7777

7878
private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream) {
79-
return stream.filter(d -> containsIgnoreCase(d.getDataType().getName()))
79+
return stream.filter(d -> containsIgnoreCase(d.getDataType() == null ? null : d.getDataType().getName()))
8080
.map(d -> {
8181
DataType type = d.getDataType();
8282
String dataTypes = "N/A";
@@ -88,6 +88,9 @@ private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream)
8888
}
8989

9090
private boolean containsIgnoreCase(String name) {
91+
if (name == null) {
92+
return false;
93+
}
9194
return this.prohibitedTypeNames.stream().anyMatch(s -> StringUtils.equalsIgnoreCase(s, name));
9295
}
9396

server/odc-service/src/main/java/com/oceanbase/odc/service/sqlcheck/rule/RestrictColumnNotNull.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,21 +77,24 @@ public List<DialectType> getSupportsDialectTypes() {
7777
}
7878

7979
private boolean containsIgnoreCase(String name) {
80+
if (name == null) {
81+
return true;
82+
}
8083
return this.nullableDatatypes.stream().anyMatch(s -> StringUtils.equalsIgnoreCase(s, name));
8184
}
8285

8386
private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream) {
8487
return stream.filter(d -> {
8588
ColumnAttributes attributes = d.getColumnAttributes();
8689
if (attributes == null) {
87-
return !containsIgnoreCase(d.getDataType().getName());
90+
return !containsIgnoreCase(getDataTypeName(d));
8891
}
8992
List<InLineConstraint> cs = attributes.getConstraints();
9093
if (CollectionUtils.isEmpty(cs)) {
91-
return !containsIgnoreCase(d.getDataType().getName());
94+
return !containsIgnoreCase(getDataTypeName(d));
9295
}
9396
return cs.stream().noneMatch(c -> Boolean.FALSE.equals(c.getNullable()))
94-
&& !containsIgnoreCase(d.getDataType().getName());
97+
&& !containsIgnoreCase(getDataTypeName(d));
9598
}).map(d -> {
9699
String dataTypes = "N/A";
97100
if (CollectionUtils.isNotEmpty(nullableDatatypes)) {
@@ -101,4 +104,8 @@ private List<CheckViolation> builds(String sql, Stream<ColumnDefinition> stream)
101104
}).collect(Collectors.toList());
102105
}
103106

107+
private String getDataTypeName(ColumnDefinition definition) {
108+
return definition.getDataType() == null ? null : definition.getDataType().getName();
109+
}
110+
104111
}

server/odc-service/src/test/java/com/oceanbase/odc/service/sqlcheck/OracleSqlCheckerTest.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,10 @@ public void check_restrictPrimaryKeyType_violationGenerated() {
521521
+ "constraint abcd_pk primary key(name, \"age\"))",
522522
"alter table abcd add primary key (NAME)",
523523
"alter table abcd add primary key (age)",
524-
"alter table \"abcd\" add primary key (NAME)"
524+
"alter table \"abcd\" add primary key (NAME)",
525+
"CREATE TABLE ORACLE_RANGE_VARCHAR_2(\n"
526+
+ " char_column_number GENERATED ALWAYS AS (TO_NUMBER(char_column)) VIRTUAL\n"
527+
+ ")",
525528
};
526529
JdbcTemplate jdbcTemplate = Mockito.mock(JdbcTemplate.class);
527530
Mockito.when(jdbcTemplate.queryForObject(Mockito.anyString(), Mockito.any(RowMapper.class)))
@@ -563,7 +566,10 @@ public void check_restrictIndexType_violationGenerated() {
563566
"alter table abcd add unique (\"age\")",
564567
"create index abcd_idx1 on abcd(id)",
565568
"create index abcd_idx2 on abcd(id, name)",
566-
"create index abcd_idx3 on abcd(age_t, name)"
569+
"create index abcd_idx3 on abcd(age_t, name)",
570+
"CREATE TABLE ORACLE_RANGE_VARCHAR_2(\n"
571+
+ " char_column_number GENERATED ALWAYS AS (TO_NUMBER(char_column)) VIRTUAL\n"
572+
+ ")"
567573
};
568574
JdbcTemplate jdbcTemplate = Mockito.mock(JdbcTemplate.class);
569575
Mockito.when(jdbcTemplate.queryForObject(Mockito.anyString(), Mockito.any(RowMapper.class)))
@@ -814,7 +820,10 @@ public void check_columnCollation_violationGenerated() {
814820
public void check_columnIsNullable_violationGenerated() {
815821
String[] sqls = new String[] {
816822
"create table aaaa(id varchar(64), col1 blob, col2 number not null)",
817-
"alter table abdcd add id number default 123, add id1 nchar(23) null, add col1 blob, add col2 number not null"
823+
"alter table abdcd add id number default 123, add id1 nchar(23) null, add col1 blob, add col2 number not null",
824+
"CREATE TABLE ORACLE_RANGE_VARCHAR_2(\n"
825+
+ " char_column_number GENERATED ALWAYS AS (TO_NUMBER(char_column)) VIRTUAL\n"
826+
+ ")"
818827
};
819828
DefaultSqlChecker sqlChecker = new DefaultSqlChecker(DialectType.OB_ORACLE, "$$",
820829
Collections.singletonList(new RestrictColumnNotNull(new HashSet<>(Collections.singletonList("blob")))));
@@ -833,7 +842,10 @@ public void check_columnIsNullable_violationGenerated() {
833842
public void check_noDefaultValue_violationGenerated() {
834843
String[] sqls = new String[] {
835844
"create table aaaa(id varchar(64), col1 blob, col2 number default 123)",
836-
"alter table abdcd add id number unique, add id1 nchar(23) null, add col1 blob, add col2 number default 567"
845+
"alter table abdcd add id number unique, add id1 nchar(23) null, add col1 blob, add col2 number default 567",
846+
"CREATE TABLE ORACLE_RANGE_VARCHAR_2(\n"
847+
+ " char_column_number GENERATED ALWAYS AS (TO_NUMBER(char_column)) VIRTUAL\n"
848+
+ ")"
837849
};
838850
DefaultSqlChecker sqlChecker = new DefaultSqlChecker(DialectType.OB_ORACLE, "$$",
839851
Collections.singletonList(new NoDefaultValueExists(new HashSet<>(Collections.singletonList("blob")))));
@@ -1062,7 +1074,10 @@ public void check_prohibitedDataTypes_violationGenerated() {
10621074
String[] sqls = {
10631075
"create table abcd(ida blob not null, col1 varchar(64) not null default 'abcd')",
10641076
"alter table abcd add idb varchar2(64) not null",
1065-
"alter table abcd add idv clob not null default 123"
1077+
"alter table abcd add idv clob not null default 123",
1078+
"CREATE TABLE ORACLE_RANGE_VARCHAR_2(\n"
1079+
+ " char_column_number GENERATED ALWAYS AS (TO_NUMBER(char_column)) VIRTUAL\n"
1080+
+ ")"
10661081
};
10671082
DefaultSqlChecker sqlChecker = new DefaultSqlChecker(DialectType.OB_ORACLE,
10681083
null,

0 commit comments

Comments
 (0)